如何在 MATLAB 中正确使用递归?

发布于 2024-10-13 05:29:46 字数 447 浏览 3 评论 0原文

我有一个简单的 m 文件,我将其创建为递归函数:

function[velocity] = terminal(m,c,t,vi)
%inputs:
% m = mass
% c = coeffcient of drag
% t = time
% vi = initial velocity

if t==18, velocity = vi+(9.8-c/m*(vi))*2;
    return 
end

velocity = vi+(9.8-c/m*(vi))*2;
velocity  %used to print out velocity for debugging
terminal(m,c,t+2,velocity);
end

速度的计算在打印出每个递归时正确完成。然而最后返回的“ans”是递归的第一个计算值。我的问题是如何正确地递归设置 matlab 函数?或者可以这样做,并且使用循环更好吗?

I have a simple m file that I have created as a recursive function:

function[velocity] = terminal(m,c,t,vi)
%inputs:
% m = mass
% c = coeffcient of drag
% t = time
% vi = initial velocity

if t==18, velocity = vi+(9.8-c/m*(vi))*2;
    return 
end

velocity = vi+(9.8-c/m*(vi))*2;
velocity  %used to print out velocity for debugging
terminal(m,c,t+2,velocity);
end

The calculation of velocity is being done correctly as it prints out every recursion. However the "ans" that is returned at the end is the first calculated value of recursion. My question is how do I correctly setup a matlab function recursively? Or can it be done, and is it better to use a loop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

娇俏 2024-10-20 05:29:47

请耐心等待,我已经有一段时间没有做太多 Matlab 工作了。

但我会简单地迭代调用您的函数:

velocity = vi
for t = 0:2:18
    velocity = velocity+(9.8-c/m*(velocity))*2;
end

然后,对于 t 的每个实例,它将计算给定初始速度的速度,并用新速度更新该值。

要让它采用大小为 2 的增量步长,只需向其添加步长即可。

根据评论更新

Bear with me, haven't done a lot of Matlab for some time now.

But I would simply call your function iteratively:

velocity = vi
for t = 0:2:18
    velocity = velocity+(9.8-c/m*(velocity))*2;
end

Then for each instance of t it would calculate velocity for a given initial velocity and update that value with it's new velocity.

To have it take incremental steps with a size of 2, simply add your step size to it.

Updated in response to the comments

ら栖息 2024-10-20 05:29:47
velocity = terminal(m,c,t+2,velocity)

应该有效。

velocity = terminal(m,c,t+2,velocity)

should work.

许一世地老天荒 2024-10-20 05:29:47

这里递归的问题是它增加了每次的函数调用开销。这将使您的代码在 matlab 中变得更慢且效率更低。使用循环来代替,你会远远领先。是的,在某些情况下,递归是一个很有价值的工具。但在许多情况下,仔细编写的循环是更好的解决方案。

最后,当您确实使用递归时,请了解何时应用记忆等工具来改进算法的行为。记忆只是意味着不重新计算已经完成的事情。例如,可以对斐波那契数列使用递归,但这是一种效率极低的方法。

The problem with recursion here is it adds function call overhead for each time through. This will make your code far slower and less efficient in matlab. Use a loop instead and you will be far ahead of things. Yes, there are cases where recursion is a valuable tool. But in many cases a carefully written loop is the better solution.

Finally, when you DO use recursion, learn when to apply tools like memoization to improve the behavior of the algorithm. Memoization simply means to not recompute that which you have already done. For example it is possible to use recursion for a fibonacci sequence, but this is a terribly inefficient way to do so.

过潦 2024-10-20 05:29:47

函数的返回值是velocity。 Matlab 将返回函数体中分配给速度的最后一个值。尽管 velocity 被分配到递归的更深处,但这对 Matlab 来说并不重要。
下一次调用 terminal() 时的 velocity 是一个不同的变量!

将最后一行更改为

function[velocity] = terminal(m,c,t,vi)
%inputs:
% m = mass
% c = coeffcient of drag
% t = time
% vi = initial velocity

if t==18, velocity = vi+(9.8-c/m*(vi))*2;
    return 
end

velocity = vi+(9.8-c/m*(vi))*2;
velocity  %used to print out velocity for debugging
velocity = terminal(m,c,t+2,velocity);
end

给出预期结果。

The return value of your function is velocity. Matlab will return the last value assigned to velocity in the function body. Even though velocity is assigned deeper into the recursion, this doesn't matter to Matlab.
velocity in the next call to terminal() is a different variable!

Changing the final line to

function[velocity] = terminal(m,c,t,vi)
%inputs:
% m = mass
% c = coeffcient of drag
% t = time
% vi = initial velocity

if t==18, velocity = vi+(9.8-c/m*(vi))*2;
    return 
end

velocity = vi+(9.8-c/m*(vi))*2;
velocity  %used to print out velocity for debugging
velocity = terminal(m,c,t+2,velocity);
end

Gives the expected result.

感悟人生的甜 2024-10-20 05:29:46

虽然我的答案会偏离编程并进入微积分领域,但应该注意的是,您可以在没有递归或循环的情况下解决您的问题,因为您可以准确地解决对于使用积分的方程v(t)。您似乎正在对下落物体上的斯托克斯阻力进行建模,因此您可以使用此积分表中的第四个公式来计算之后达到的最终速度vFinal给定起始速度vInitial,下降一段时间tDelta。这是您将得到的结果公式:

vFinal = 9.8*m/c + (vInitial - 9.8*m/c)*exp(-c*tDelta/m);

这将是比通过及时向前推进顺序步骤来近似 vFinal 更准确的答案(即 欧拉方法,当采用的时间步长太大时,该方法可能会显示严重错误或不稳定)。

Although my answer will stray away from programming and into the realm of calculus, it should be noted that you can solve your problem both without recursion or a loop since you can exactly solve for an equation v(t) using integration. It appears that you are modeling Stokes' drag on a falling body, so you can use the fourth formula from this integration table to compute a final velocity vFinal that is achieved after falling for a time tDelta given a starting velocity vInitial. Here is the resulting formula you would get:

vFinal = 9.8*m/c + (vInitial - 9.8*m/c)*exp(-c*tDelta/m);

This will be a more accurate answer than approximating vFinal by making sequential steps forward in time (i.e. the Euler method, which can display significant errors or instabilities when the time steps that are taken are too large).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文