我有一个定义如下的函数:
@(A,N0,Tb,lambda,p) p.*erfc(1.0./sqrt(N0).*sqrt(Tb).*(A-lambda)).*(1.0./2.0)-erfc(1.0./sqrt(N0).*sqrt(Tb).*(A+lambda)).*(p-1.0).*(1.0./2.0)
我有N0
和lambda
作为向量。如果我将N0
作为向量并将lambda
作为标量传递,我会得到一个向量输出。
对于每个lambda
,我想用完整的N0
向量来评估函数。 (即,我想返回一个向量数组而不是只返回一个向量)。有没有办法在没有循环的情况下做到这一点?
答案 0 :(得分:2)
我将假设您的数据由以下人员提供:
A
,Tb
,p
标量值N0
,lambda
列 -vectors。由于您尝试组合的两个向量是通过乘法组合的,因此您可以使用线性代数。如果将列向量乘以行向量,则将获得成对乘积矩阵:
>> (1:4)'*(10:12)
ans =
10 11 12
20 22 24
30 33 36
40 44 48
所以你的代码会导致:
f = @(A,N0,Tb,lambda,p) p*erfc(sqrt(Tb./N0)*(A-lambda).')*0.5 ...
+(1-p)*erfc(sqrt(Tb./N0)*(A+lambda).')*0.5
如果你的公式是将值除了乘法以外的其他东西,你就不能使用线性代数。为此,有一个奇妙的函数bsxfun
,它以类似的方式组合了列和行向量,但您可以指定要使用的函数而不是乘法。您可以通过以下方式在此处使用它:
让我们调用您的初始函数f
,然后您可以定义一个新函数g
,它可以成对地处理lambda
和N0
:
g = @(A,N0,Tb,lambda,p) bsxfun(@(N0,lambda) f(A,N0,Tb,lambda,p), N0, lambda')
答案 1 :(得分:2)
是的,你可以。在使用函数句柄之前,您需要进行一些预处理。我将假设N0
和lambda
都是列向量,其中N0
为M
个元素长且lambda
为N
元素很长。如果您想要创建一个二维矩阵,使得每一行都是lambda
的单个值而N0
保持不变的结果,那么您需要做的是同时N0
和lambda
矩阵,以便 N x M
长。 N0
将转置,使其成为行向量,并按行排列N
次以创建此矩阵。 lambda
也是N x M
,其中lambda
向量按列排列M
次以创建此矩阵。
然后,您可以将这些矩阵作为输入提交到函数句柄中。结果将是N x M
矩阵,其中每个列是将一个 lambda应用于向量N0
的结果。作为这个概念的证明,请考虑函数句柄的第一部分:
p.*erfc(1.0./sqrt(N0).*sqrt(Tb) ...
此步骤的结果将从M
函数生成erfc
个相同的列。然后我们将其与(A - lambda)
相乘。 lambda
将以这样的方式进行整形:每行反映单个 lambda将应用于N0
的每个值。关于(A + lambda)
的等式的另一面,可以说同样的事情。因此,尝试这样做:
M = numel(N0);
N = numel(lambda);
N0_matrix = repmat(N0.', N, 1);
lambda_matrix = repmat(lambda, 1, M);
f = @(A,N0,Tb,lambda,p) p.*erfc(1.0./sqrt(N0).*sqrt(Tb).*(A-lambda)).*(1.0./2.0)-erfc(1.0./sqrt(N0).*sqrt(Tb).*(A+lambda)).*(p-1.0).*(1.0./2.0);
out = f(A, N0_matrix, Tb, lambda_matrix, p);
out
将是我们谈到的N x M
矩阵。
答案 2 :(得分:1)
这里提出的是另一种基于bsxfun
的方法,为问题中使用的特定函数句柄量身定制 -
%// This could could be reused in the function definition,
%// so that pre-calulcating it makes sense for performance
f1vals = 1.0./sqrt(N0).*sqrt(Tb);
%// Finally get the output using f1vals and other inputs
out = p.*erfc(bsxfun(@times,f1vals,A - lambda')).*0.5 - ...
erfc(bsxfun(@times,f1vals,A + lambda')).*(p-1.0).*0.5;
请注意,此方法还假定N0
和lambda
为列向量,其他为标量。
建议的解决方案代码针对@knedlsepp's Version -1 solution code
和@rayryeng's solution code运行
用于各种数据。基准测试代码列在here on ideone.com。在我的系统上获得的运行时间是 -
1)N0
和lambda
长度500
:
--------- With Proposed solution
Elapsed time is 0.068731 seconds.
--------- With Knedlsepp Version - 1 solution
Elapsed time is 0.082629 seconds.
--------- With Rayryeng solution
Elapsed time is 0.132094 seconds.
2)N0
和lambda
长度1000
:
--------- With Proposed solution
Elapsed time is 0.220694 seconds.
--------- With Knedlsepp Version - 1 solution
Elapsed time is 0.244323 seconds.
--------- With Rayryeng solution
Elapsed time is 0.334007 seconds.
3)N0
和lambda
长度3500
:
--------- With Proposed solution
Elapsed time is 2.571570 seconds.
--------- With Knedlsepp Version - 1 solution
Elapsed time is 3.009692 seconds.
--------- With Rayryeng solution
Elapsed time is 3.747122 seconds.