滞后超前型低通滤波器 (2)

本文详细探讨了滞后超前型低通滤波器的特性计算过程,包括相位滞后计算及相位余量对应的频率确定,并通过编程语言Maxima实现了关键参数的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我以前写过篇博客,讨论了《锁相环电路设计与应用》书中提到的滞后超前型低通滤波器的特性。http://blog.youkuaiyun.com/liyuanbhu/article/details/7831863

不过当时没有仔细计算书后附录给出的曲线。最近有点空闲时间,研究了一下那几条曲线是如何计算得来的。在这里记录一下。

 

首先,相位返回量与两个因素有关,第一个是M,第二个是fH/fL的比值(这个比值在程序中用A表示,A=fH/fL)。

给出和 R1 的值,就可以确定 R2 的值。

再给个 fm 值和A值就可以确定fH 和 fL的值。

到这里 C1 C2 的值就可以确定了。

至此,公式中所有的参数就都确定了。

下面给出个函数,可以计算任何一个频率下的相位滞后。

R1MAfm 是滤波器参数,f是要计算的频率点。

编程语言采用 Maxima

phase2(R1, M, A, fm, f):=block([pi, fH, fL, OmegaM, OmegaH, OmegaL, omega, C1, C2, R2, den, num],  
    pi:3.14159,    
    R2: M/(1-M)*R1,
    fH: sqrt(A)*fm,
    fL: fm/sqrt(A),
    OmegaM: 2*pi*fm,
    OmegaH: 2*pi*fH,
    OmegaL: 2*pi*fL, 
    C2: 1/(R2*OmegaH),
    C1: 1/(R2*OmegaL)-C2,
    omega: 2*pi*f,
    num: (C1+C2)*R2*%i*omega+1,
    den: C1*R1*C2*R2*(%i*omega)^2+((C1+C2)*R2+C1*R1)*(%i*omega)+1,
    ev(carg(num/den) / pi * 180.0, numer))$


下面所有计算中 R1取值1000fm取值也为 1000

首先计算fm频率处的相位滞后,因为这个频率出相位返回值最大。

R1:1000;
fm:1000;
y1:makelist ([A,phase2(R1, 10^(-10.0/20.0), A, fm, fm)], A, 1.5, 100, 0.5)$
y2:makelist ([A,phase2(R1, 10^(-20.0/20.0), A, fm, fm)], A, 1.5, 100, 0.5)$
y3:makelist ([A,phase2(R1, 10^(-30.0/20.0), A, fm, fm)], A, 1.5, 100, 0.5)$
y4:makelist ([A,phase2(R1, 10^(-40.0/20.0), A, fm, fm)], A, 1.5, 100, 0.5)$
wxplot2d([[discrete,y1],[discrete,y2],[discrete,y3],[discrete,y4]],
[style, points], 
[legend, "-10dB", "-20dB", "-30dB", "-40dB"], 
[xlabel, "fH/fL"], 
[ylabel, "Phase lag at frequency fm"],  [gnuplot_preamble,"set grid"]);

下图是计算出的结果。

下面给定确定的M和A,计算fdH fdL。实际上,我们只需要计算 fdH,因为fdHfdL 好计算的多。fdH >fm,而相位变化在 f>fm 后是单调变化的,很容易用各种数值算法来计算,最简单的方法就是确定一个区间然后用二分查找法。而我们知道 fdH * fdL = fm^2,所以求出了 fdH 自然就可以确定 fdL了。

下面是个例子程序求 M=0.3162(对应-10dB),A= 2时 30°相位余量对应的 fdH。由于中心频率是1000,所以我们在1000 100000之间肯定能找到 fdH

 

R1:1000;
fm:1000;

fdH:find_root(phase2(R1, 10^(-10.0/20.0), 2, fm, f)=-60, f, 1000, 100000);
fdL:fm^2/fdH;
B:fdH/fdL;


结果是:

3291.133743180222

303.8466613738098

10.83156131549946

利用类似的方法,用个循环就能求出附录的表格了。

下面是程序,A2100 之间变化,也就是 fH/fL2100 之间变化。然后查找相位滞后为30度的点,也就是 fdH 点。

R1:1000;
fm:1000;

dHdL:makelist ((find_root(phase2(R1, 10^(-10.0/20.0), A, fm, f)=-60, f, 1000, 100000)/fm)^2, A, 2, 100, 2)$
fH:makelist (sqrt(A), A, 2, 100, 2)$
fL:1/fH$
plot2d([[discrete,dHdL, fH],[discrete,dHdL,fL]],[legend, "fH", "fL"],  [gnuplot_preamble,"set logscale xy;set grid mxtics mytics; set mxtics"]);

 

 

R1:1000;
db:-10.0;
M:10^(db/20);
fm:1000;
dHdL:makelist ((find_root(phase2(R1, M, A, fm, f)=-30, f, 1000, 10000)/fm)^2, A, 6, 18, 2)$
fH:makelist (sqrt(A), A, 6, 18, 2)$
fL:1/fH$
wxplot2d([[discrete,dHdL, fH]],[legend, "fH"], [xlabel, "fdH/fdL"], [gnuplot_preamble,"set grid mxtics mytics; set mxtics; set mytics"]);
wxplot2d([[discrete,dHdL,fL]],[legend, "fL"],  [xlabel, "fdH/fdL"],[gnuplot_preamble,"set grid mxtics mytics; set mxtics; set mytics"]);


DQN(Deep Q-Network)是一种使用深度神经网络实现的强化学习算法,用于解决离散动作空间的问题。在PyTorch中实现DQN可以分为以下几个步骤: 1. 定义神经网络:使用PyTorch定义一个包含多个全连接层的神经网络,输入为状态空间的维度,输出为动作空间的维度。 ```python import torch.nn as nn import torch.nn.functional as F class QNet(nn.Module): def __init__(self, state_dim, action_dim): super(QNet, self).__init__() self.fc1 = nn.Linear(state_dim, 64) self.fc2 = nn.Linear(64, 64) self.fc3 = nn.Linear(64, action_dim) def forward(self, x): x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x ``` 2. 定义经验回放缓存:包含多条经验,每条经验包含一个状态、一个动作、一个奖励和下一个状态。 ```python import random class ReplayBuffer(object): def __init__(self, max_size): self.buffer = [] self.max_size = max_size def push(self, state, action, reward, next_state): if len(self.buffer) < self.max_size: self.buffer.append((state, action, reward, next_state)) else: self.buffer.pop(0) self.buffer.append((state, action, reward, next_state)) def sample(self, batch_size): state, action, reward, next_state = zip(*random.sample(self.buffer, batch_size)) return torch.stack(state), torch.tensor(action), torch.tensor(reward), torch.stack(next_state) ``` 3. 定义DQN算法:使用PyTorch定义DQN算法,包含训练和预测两个方法。 ```python class DQN(object): def __init__(self, state_dim, action_dim, gamma, epsilon, lr): self.qnet = QNet(state_dim, action_dim) self.target_qnet = QNet(state_dim, action_dim) self.gamma = gamma self.epsilon = epsilon self.lr = lr self.optimizer = torch.optim.Adam(self.qnet.parameters(), lr=self.lr) self.buffer = ReplayBuffer(100000) self.loss_fn = nn.MSELoss() def act(self, state): if random.random() < self.epsilon: return random.randint(0, action_dim - 1) else: with torch.no_grad(): q_values = self.qnet(state) return q_values.argmax().item() def train(self, batch_size): state, action, reward, next_state = self.buffer.sample(batch_size) q_values = self.qnet(state).gather(1, action.unsqueeze(1)).squeeze(1) target_q_values = self.target_qnet(next_state).max(1)[0].detach() expected_q_values = reward + self.gamma * target_q_values loss = self.loss_fn(q_values, expected_q_values) self.optimizer.zero_grad() loss.backward() self.optimizer.step() def update_target_qnet(self): self.target_qnet.load_state_dict(self.qnet.state_dict()) ``` 4. 训练模型:使用DQN算法进行训练,并更新目标Q网络。 ```python dqn = DQN(state_dim, action_dim, gamma=0.99, epsilon=1.0, lr=0.001) for episode in range(num_episodes): state = env.reset() total_reward = 0 for step in range(max_steps): action = dqn.act(torch.tensor(state, dtype=torch.float32)) next_state, reward, done, _ = env.step(action) dqn.buffer.push(torch.tensor(state, dtype=torch.float32), action, reward, torch.tensor(next_state, dtype=torch.float32)) state = next_state total_reward += reward if len(dqn.buffer.buffer) > batch_size: dqn.train(batch_size) if step % target_update == 0: dqn.update_target_qnet() if done: break dqn.epsilon = max(0.01, dqn.epsilon * 0.995) ``` 5. 测试模型:使用训练好的模型进行测试。 ```python total_reward = 0 state = env.reset() while True: action = dqn.act(torch.tensor(state, dtype=torch.float32)) next_state, reward, done, _ = env.step(action) state = next_state total_reward += reward if done: break print("Total reward: {}".format(total_reward)) ``` 以上就是在PyTorch中实现DQN强化学习的基本步骤。需要注意的是,DQN算法中还有很多细节和超参数需要调整,具体实现过程需要根据具体问题进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值