【问题标题】:Square wave function for MatlabMatlab的方波函数
【发布时间】:2015-05-23 19:33:28
【问题描述】:

我是 Matlab 编程新手。我试图弄清楚如何计算以下函数:

我知道我的代码已关闭,我只是想从某种形式的函数开始。我试图在下面的程序中写出函数的总和。

function [g] = square_wave(n)
g = symsum(((sin((2k-1)*t))/(2k-1)), 1,n);
end

任何帮助将不胜感激。

更新:

我现在的代码:

function [yout] = square_wave(n)
syms n;
f = n^4;
df = diff(f);
syms t k;
f = 1; %//Define frequency here
funcSum = (sin(2*pi*(2*k - 1)*f*t) / (2*k - 1));
funcOut = symsum(func, v, start, finish);
xsquare = (4/pi) * symsum(funcSum, k, 1, Inf);
tVector = 0 : 0.01 : 4*pi; %// Choose a step size of 0.01
yout = subs(xsquare, t, tVector);

end

【问题讨论】:

  • 查看我链接到的副本。这已经得到了回答。具体看我的回答:stackoverflow.com/a/24004603/3250829
  • 谢谢,我试图将您发布的代码写到我自己的函数中。我需要它作为行向量返回。不幸的是,我运气不佳。
  • 给出的是关于t的函数。如果你想要一个矢量,你需要阅读帖子的结尾。您会看到该帖子定义了[-3,3] 之间的时间向量,然后使用subs 并且关于平方生成函数,它生成实际的时间/幅度值。在您的情况下,它现在是 [0, 4*pi]。只需将边界从[-3,3] 更改为[0,4*pi],您就有了答案。实际上,你需要 1001 分,所以你应该有t = linspace(0, 4*pi, 1001);。此外,我所做的是对无穷大或Inf 的总结。您所要做的就是将Inf 更改为n
  • 好的,我知道它是关于 t 的函数。那么来自用户的输入会是 t 吗?我正在尝试设置我的代码的第一行,现在它是:function [yout] = square_wave(t)。但是,当我尝试输入一个值时,出现以下错误: Square_wave (line 2) syms x; 中的错误;
  • 我重新打开了这个问题并提供了答案。希望这会有所帮助。

标签: matlab function


【解决方案1】:

注意:这个答案的部分灵感来自我之前在这里写的一篇文章:How to have square wave in Matlab symbolic equation - 但是,它并不完全相同,这就是我在这里提供答案的原因。


好的,看来您的问题的第一部分是正确的。但是,当您将事物相乘时,您需要使用* 运算符...所以2k - 1 应该是2*k - 1。忽略这一点,你是symsuming 正确地给出了方波方程。这个函数的输入只有一个参数 - n。您在上面的等式中看到的是方波的Fourier Series 表示。该理论的一个混蛋版本是,您可以将周期函数表示为正弦函数的无限总和,每个函数按一定量加权。您在等式中看到的实际上是方波的傅立叶级数。

n 控制要添加到方程中的正弦曲线的总数。你拥有的正弦曲线越多,函数看起来就越像方波。在问题中,他们希望您使用 n 的值。如果n 变得非常大,它应该开始接近方波。

symsum 将这个傅里叶级数表示为相对于t 的函数。您现在需要做的是您需要将t 的值代入此表达式,以获得每个值t 的输出幅度。他们已经为您定义了它是从04*pi 之间的1001 个点的向量。

定义此向量,然后您需要使用 subs 将时间值替换为 symsum 表达式,完成后,将它们转换回 double 以便您实际得到一个数字向量.

因此,您的函数应该是这样的:

function [g] = square_wave(n)

syms t k; %// Define t and k 
f = sin((2*k-1)*t)/(2*k-1); %// Define function
F = symsum(f, k, 1, n); %// Define Fourier Series
tVector = linspace(0, 4*pi, 1001); %// Define time points
g = double(subs(F, t, tVector)); %// Get numeric output

end

第一行将tk 定义为符号,因为tk 在表达式中是符号。接下来,我将f 定义为与tk 相关的总和内的项。之后的行定义了实际总和本身。我们使用f 并对k 求和,因为这就是求和的要求,我们从1 到n 求和。最后但同样重要的是,我们定义了一个从04*pi 的时间向量,其间有1001 个点,我们使用subs 将傅里叶级数中的t 的值替换为该向量中的所有值。结果应该是一个 1001 向量,然后我将其转换为 double 以获得数字结果,我们会得到您想要的输出。

为了向您展示这是可行的,我们可以使用n = 20 进行尝试。现在在命令提示符下执行此操作:

>> g = square_wave(20);
>> t = linspace(0, 4*pi, 1001);
>> plot(t, g);

我们得到:

因此,如果您将n 设置得更高...按照他们的建议设置为 200,您会发现该波最终看起来就像您对方波所期望的那样。


如果您没有 symsumsymssubs 所依赖的 Symbolic Math Toolbox,我们完全可以用数字来完成。您需要做的是为tn 对定义一个meshgrid 点,将每对点代入傅里叶级数的序列方程中,并对所有结果求和。

因此,你会做这样的事情:

function [g] = square_wave(n)

tVector = linspace(0, 4*pi, 1001); %// Define time points
[t,k] = meshgrid(tVector, 1:n); %// Define meshgrid
f = sin((2*k-1).*t)./(2*k-1); %// Define Fourier Series
g = sum(f, 1); %// Sum up for each time point

end

第一行代码定义了我们从04*pi的时间点。下一行代码定义了一个meshgrid 点。这是如何工作的,对于t,每列定义一个唯一的时间点,因此第一列是 200 个零,直到最后一列是 200 个 4*pi 值的列。与 k 类似,每个 row 表示一个唯一的 n 值,因此第一行是 1001 1s,然后是 1001 2s,直到 1001 1s。这意味着现在tk 的每一列都表示正确的(t,n) 对,以计算该列每次唯一的傅里叶级数的输出。

因此,您只需使用序列方程并进行逐元素乘法和除法,然后沿每一列求和,最终得到方波输出。使用上面的代码,您将得到与上面相同的结果,并且它会比symsum 快得多,因为我们现在是在数字上执行它而不是象征性地执行它,这会带来更多的计算开销。

这是n = 200时我们得到的:

n=200 的这段代码以毫秒为单位运行,而 symsum 的等效代码在我的机器上运行了将近 2 分钟 - Mac OS X 10.10.3 Yosemite、16 GB RAM、Intel Core i7 2.3 GHz。

【讨论】:

  • 谢谢!对不起,这个语法对我来说很难理解。感谢您的耐心等待!
  • @statsguyz - 哦,这根本没问题。我想我会重新打开并给你一个答案,而不是在 cmets 中来回走动。试试看,让我知道结果如何!
  • 我一定错过了什么。当我运行该函数时,我收到以下错误:要使用“syms”,您可能需要:syms - Symbolic Math Toolbox
  • 呃哦...是的,这是个问题。我假设你有符号数学工具箱,因为你使用了symsum。如果你没有那个,那么我上面的建议就行不通了……这没有意义,因为听起来你有一个相当新的 MATLAB 版本。顺便说一句,你的版本是什么?另外,请在您的命令提示符中输入ver,按回车键,然后查看符号工具箱是否在您可用的工具箱列表中。
  • @statsguyz 输入ver,按回车键,然后向下滚动,查看符号数学工具箱是否列为工具箱可用性的一部分。如果您没有它,那么我们仍然可以满足您的需求,但需要更多的工作。
猜你喜欢
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 2013-12-04
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
相关资源
最近更新 更多