我有一个函数来计算一个数字数组(randparam),我想逐个元素地输入另一个进行模拟的函数。
例如
function [randparam] = arraycode
code
randparam = results of code
% randparam is now a 1x1001 vector.
end
接下来我想在我的模拟函数
中输入1和1的randparamfunction simulation
x = constant + constant * randparam + constant
return
end
对我来说困难的原因是因为模拟函数中的返回命令,它只计算上面方程式x的一步,将结果返回到另一个函数,称之为积分器,然后积分器函数将调用模拟再次运行来计算x。
所以积分器功能可能看起来像
function integrator (x)
y = simulation(x) * 5
u = y+10
yy = simulation(x) * 10 + u
end
如您所见,积分器函数调用模拟函数两次。这给我带来了两个问题:
如果我在模拟函数中创建一个for循环,我会使用以下内容逐个元素地输入:
表示i = 1:100
x =常数+常数* randparam(i)+常数
返回
端
然后每当我的积分器函数再次调用我的模拟函数时,我的for循环再次从1开始。
2.如果我有一些保持我在我的基础工作区,以便我的模拟函数中的for循环知道从1升级,那么我的y和yy函数会有不同的x输入,因为它会尽快第二次叫yy,那我现在是i + 1,这要归功于y的电话。
在这种情况下,有没有办法避免for循环?问题二的一个潜在解决方案是复制脚本但使用不同的名称,并让我的for循环使用不同的变量,但这看起来效率很低。
希望我明白这一点。
感谢。
答案 0 :(得分:3)
首先,如果您通常希望将相同的函数应用于数组的每个元素,并且还没有内置的矢量化方式,那么可以使用arrayfun
(虽然通常简单的for
循环更快且更易读):
%# randparam is a 1x1001 vector.
%#next I want to input randparam 1 by 1 into my simulation function
function simulation
x = constant + constant * randparam + constant
return
end
(注意:问问自己这个函数可能正在做什么,因为它没有返回一个值而且MATLAB没有通过引用传递。)这就是arrayfun
的用途:将函数应用于每个函数数组的元素(或向量,在本例中)。同样,你应该确保在你的情况下这样做是有意义的,而不是一个显式的循环。
function simulation(input_val)
#% your stuff
end
sim_results = arrayfun( @simulation, randparam);
当然,你写它的方式,行
x = constant + constant*randparam + constant;
可以(并且将会)进行矢量化 - 如果你给它一个矢量或矩阵,结果就是矢量或矩阵。
第二次似乎你不清楚MATLAB中函数变量的“范围”。如果调用函数,则会创建一个干净的工作区。因此,来自一个函数的x
在您调用的另一个函数中不会自动可用。变量在函数末尾也超出范围,因此在函数内使用x
不会更改/覆盖该函数外部存在的变量x
。并且函数的多次调用都有自己的工作区。
答案 1 :(得分:0)
积分器级别的循环出了什么问题?
function integrator (x)
for i=1:length(x)
y = simulation(x(i)) * 5
u = y+10
yy = simulation(x(i)) * 10 + u
end
并将整个randparm传递给积分器?从你的问题中不清楚你是否希望simulation
在给定相同的输入时返回相同的值,或者是否希望它使用相同的输入步进两次,或者是否要在每次调用时都需要新的输入。还不清楚simulation
是否保持任何内部状态。您编写示例的方式,模拟仅取决于输入值,而不取决于任何先前的输入或输出,这将使向量化变得微不足道。如果我们都错过了这条船,请使用更精确的示例代码编辑您的问题。