简体   繁体   English

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

[英]How do I correctly use Recursion in MATLAB?

I have a simple m file that I have created as a recursive function:我有一个简单的 m 文件,我将其创建为递归 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.但是最后返回的“ans”是递归的第一个计算值。 My question is how do I correctly setup a matlab function recursively?我的问题是如何递归正确设置 matlab function? Or can it be done, and is it better to use a loop?还是可以做到,用循环是不是更好?

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. 虽然我的答案会偏离编程并进入微积分领域,但应该注意的是,你可以在没有递归循环的情况下解决你的问题,因为你可以使用积分精确求解方程v(t) 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 . 看来,你模拟斯托克斯拖上落体,这样你就可以使用第四公式从这个积算表计算的最终速度vFinal是连续下跌一段时间后达到tDelta给出起始速度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 (ie the Euler method , which can display significant errors or instabilities when the time steps that are taken are too large). 通过及时推进顺序步骤(即欧拉方法 ,当所采用的时间步长太大时,可以显示重大错误或不稳定性),这将是比近似vFinal更准确的答案。

Bear with me, haven't done a lot of Matlab for some time now. 忍受我,一段时间没有做过很多Matlab。

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. 然后对于t的每个实例,它将计算给定初始速度的速度,并用它的新速度更新该值。

To have it take incremental steps with a size of 2, simply add your step size to it. 要让它采用大小为2的增量步骤, 只需将步长添加到它即可。

Updated in response to the comments 更新以回应评论

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

应该管用。

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. 这将使你的代码在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等工具来改进算法的行为。 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. 例如,可以对斐波那契序列使用递归,但这是一种非常低效的方法。

The return value of your function is velocity . function 的返回值是velocity Matlab will return the last value assigned to velocity in the function body. Matlab 将返回分配给 function 主体中速度的最后一个值。 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!即使velocity被分配到递归的更深处,这对 Matlab 也没有关系。下一次调用terminal()时的velocity是一个不同的变量!

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.给出预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM