Matlab函数有两个向量参数

时间:2014-12-21 06:48:04

标签: matlab vectorization

我有一个定义如下的函数:

@(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)

我有N0lambda作为向量。如果我将N0作为向量并将lambda作为标量传递,我会得到一个向量输出。

对于每个lambda,我想用完整的N0向量来评估函数。 (即,我想返回一个向量数组而不是只返回一个向量)。有没有办法在没有循环的情况下做到这一点?

3 个答案:

答案 0 :(得分:2)

我将假设您的数据由以下人员提供:

  • ATbp标量值
  • N0lambda -vectors。

版本1 - (快速且针对问题)

由于您尝试组合的两个向量是通过乘法组合的,因此您可以使用线性代数。如果将列向量乘以行向量,则将获得成对乘积矩阵:

>> (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

版本2 - (更一般和重用代码)

如果你的公式是将值除了乘法以外的其他东西,你就不能使用线性代数。为此,有一个奇妙的函数bsxfun,它以类似的方式组合了列和行向量,但您可以指定要使用的函数而不是乘法。您可以通过以下方式在此处使用它:

让我们调用您的初始函数f,然后您可以定义一个新函数g,它可以成对地处理lambdaN0

g = @(A,N0,Tb,lambda,p) bsxfun(@(N0,lambda) f(A,N0,Tb,lambda,p), N0, lambda')

答案 1 :(得分:2)

是的,你可以。在使用函数句柄之前,您需要进行一些预处理。我将假设N0lambda都是列向量,其中N0M个元素长且lambdaN元素很长。如果您想要创建一个二维矩阵,使得每一行都是lambda的单个值而N0保持不变的结果,那么您需要做的是同时N0lambda 矩阵,以便 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;

请注意,此方法还假定N0lambda为列向量,其他为标量。

基准

建议的解决方案代码针对@knedlsepp's Version -1 solution code@rayryeng's solution code运行 用于各种数据。基准测试代码列在here on ideone.com。在我的系统上获得的运行时间是 -

1)N0lambda长度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)N0lambda长度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)N0lambda长度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.