【问题标题】:How to have square wave in Matlab symbolic equation如何在Matlab符号方程中产生方波
【发布时间】:2017-03-10 10:16:01
【问题描述】:

我的项目要求我使用 Matlab 创建一个内部有方波的符号方程。 我试着这样写,但无济于事:

syms t;
a=square(t);

输入参数必须是“双”。

我能做些什么来解决这个问题?提前感谢您提供的帮助。

【问题讨论】:

  • heaviside 阶跃函数可用于创建符号阶跃函数。这个和其他(咳嗽 trig)函数的某种组合应该产生一个方波
  • @RTL:你的(咳嗽 trig)评论让我很开心……对于那些从事信号处理的人来说,这简直是开玩笑。

标签: matlab symbolic-math


【解决方案1】:

这里有几个使用floorsign 函数的通用选项:

f=@(A,T,x0,x) A*sign(sin((2*pi*(x-x0))/T));
f=@(A,T,x0,x) A*(-1).^(floor(2*(x-x0)/T));

例如使用floor函数:

 syms x
 sqr=2*floor(x)-floor(2*x)+1;
 ezplot(sqr, [-2, 2])

【讨论】:

【解决方案2】:

这里有一些东西可以帮助您入门。回想一下,我们可以将方波表示为Fourier Series expansion。我不会用细节来打扰您,但是您可以将任何 periodic 函数表示为余弦和正弦的总和(à la @RTL)。在不进行推导的情况下,这是频率为f 的方波的封闭式方程,峰峰值幅度为 2(即从 -1 变为 1)。回想一下,频率是每秒周期数。因此,f = 1 表示我们每秒重复一次方波。

基本上,您要做的就是在等式的第一行编写代码……但是您到底要怎么做呢?欢迎来到符号数学工具箱的世界。我们需要事先做的是声明我们的频率是多少。我们现在假设f = 1。借助 Symbolic Math Toolbox,您可以在 MATLAB 中定义被视为数学变量的内容。之后,MATLAB 拥有一整套工具,您可以使用这些工具来评估依赖这些变量的函数。一个很好的例子是,如果您想使用它来定义函数f(x)封闭形式 解决方案。然后您可以使用diff 来区分并查看导数是什么。自己试试吧:

syms x;
f = x^4;
df = diff(f);

syms 表示您将声明之后的任何内容都声明为数学变量。在这种情况下,x 就是这样。 df 现在应该给你4x^3。酷吧?无论如何,让我们回到手头的问题。我们看到实际上在周期性平方函数中有两个变量需要定义:tk。一旦我们这样做了,我们需要首先在求和中创建我们的函数。我们可以这样做:

syms t k;
f = 1; %//Define frequency here
funcSum = (sin(2*pi*(2*k - 1)*f*t) / (2*k - 1));

这解决了这个问题......现在我们如何将它封装成一个无限的总和!? MATLAB 中的sum 命令假定我们有一个有限数组要求和。如果你想对一个函数进行符号求和,我们必须使用symsum 函数。我们通常这样称呼它:

funcOut = symsum(func, v, start, finish);

func 是我们想要总结的函数。 v 是我们希望用于索引总和的总和变量。在我们的例子中,就是kstart 是求和的开始,在我们的例子中是 1,finish 是我们希望完成求和的地方。在我们的例子中,它是无穷大,因此 MATLAB 有一个名为 Inf 的特殊关键字来表示它。因此:

xsquare = (4/pi) * symsum(funcSum, k, 1, Inf);

xquare 现在包含您根据符号数学工具箱定义的方波表示。现在,如果你想绘制你的方波,看看我们是否有这个权利。我们可以做到以下几点。让我们在-3 <= t <= 3 之间切换。因此,你会做这样的事情:

tVector = -3 : 0.01 : 3; %// Choose a step size of 0.01
yout = subs(xsquare, t, tVector);

您会注意到会有一些值为NaN。原因是因为在周期的倍数(T = 1, 2, 3, ...)处,行为未定义,因为这些点处的导数未定义。因此,我们可以使用1-1 填写。现在让我们选择1。另外,因为傅里叶级数一般是复值函数,而方波是纯实数,所以这个函数的输出实际上会给你一个复值向量。因此,只需砍掉复杂的部分,只得到真实的部分:

yout = real(double(yout)); %// To cast back to double.
yout(isnan(yout)) = 1;
plot(tVector, yout);

你会得到类似的东西:

您也可以通过ezplot 方式执行此操作:ezplot(xsquare)。但是,您会看到在波自身重复的点处,我们得到NaN 值,因此高峰值和低峰值之间存在脱节。

注意:

Natan 的解决方案要优雅得多。当他提出一些东西时,我还在写这篇文章。无论哪种方式,我都想从信号处理的角度来说明如何做到这一点。去傅里叶吧!

【讨论】:

  • 非常好的通用方法。方波有点矫枉过正,但 +1
  • @LuisMendo:啊哈哈谢谢。我也这样写它作为测试自己的一种方式,如果我可以使用symsum 正确地做到这一点。我不知道为什么我不只是做正弦波的sign。更简单。
  • @natan 谢谢 :-) 我最严重的错误之一是使问题过于复杂,这是一个很好的例子。不过感谢您的投票!
  • 感谢rayryeng的详细解释,但是我执行程序时出现问题,我认为是我的电脑问题。非常感谢您的帮助。 =D
【解决方案3】:

单位幅度方波的傅里叶级数为:

alpha + 2/Pi*sum(sin( n * Pi*alpha)/n*cos(n*theta),n=1..infinity)

这是一个方便的技巧:

 cos(n*theta) = Re( exp( I * n * theta)) 

1/n*exp(I*n*theta) = I*anti-derivative(exp(I*n*theta),theta)

把它们放在一起:将反导数(或积分)运算符从总和中取出,你会得到一个几何级数。然后整合,最后取真部分。

结果:

squarewave= 
alpha+ 1/Pi*Re(I*ln((1-exp(I*(theta+Pi*alpha)))/(1-exp(I*(theta-Pi*alpha)))))

我在 MAPLE 中尝试过,效果很好! (虽然可能不太实用)

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多