簡體   English   中英

具有兩個向量參數的Matlab函數

[英]Matlab function with two vector arguments

我有一個定義如下的函數:

@(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作為標量傳遞, N0得到向量輸出。

對於每個lambda ,我想使用完整的N0向量評估函數。 (即,我想返回向量數組而不是一個向量)。 有沒有辦法做到這一點而不循環?

我將假設您的數據由以下方式提供:

  • ATbp標量值
  • N0lambda 向量。

版本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')

是的你可以。 在使用函數句柄之前,您需要做一些預處理。 我將假設N0lambda都是列向量 ,其中N0M元素長,而lambdaN元素長。 如果你想創建一個二維矩陣,使得每行是應用的單個值的結果lambdaN0保持不變,有什么你需要做的是使雙方N0lambda一個矩陣 ,使得它們都是 N x M長。 N0將進行換位 ,使其成為向量,並逐行堆疊N次以創建此矩陣。 lambda也將是N x M ,其中lambda向量將按列堆疊M次以創建此矩陣。

然后,您可以將這些矩陣作為輸入提交到函數句柄中。 結果將是N x M矩陣,其中每一都是對向量N0應用一個 λ的結果。 作為此概念的證明,請考慮函數句柄的第一部分:

p.*erfc(1.0./sqrt(N0).*sqrt(Tb) ...

此步驟的結果將有erfc函數產生的M相同的列。 然后,將其乘以(A - lambda) lambda形狀將使每一行都反映要應用於N0每個單個值的單個 lambda。 關於等式(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矩陣,我們津津樂道。

一些討論和代碼

這里提出了另bsxfun基於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針對@knedlsepp's Version -1 solution code@rayryeng的解決方案代碼運行了建議的解決方案代碼。 基准代碼在ideone.com上列出 在我的系統上獲得的運行時為-

1) N0和長度為500 lambda

--------- 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和長度為1000 lambda

--------- 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和長度為3500 lambda

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM