2016-08-12 10 views
2

私はMatlabを少し使い慣れており、ベクトル入力用の多変数関数の定義について質問があります。ベクトル入力用の多変数関数の定義

この関数が単一の関数、たとえばf(t)である場合、ベクトル入力用の方法を知っています。一般的な方法は、f(t)を定義した後にarrayfunを使用することです。多変数関数の場合はどうでしょうか、例えばf(x,y)?私は何をしたいyためxため[1 2 3][4 5 6 7]言って、2つの入力を取得することです(異なる場合があります寸法は、それらの両方は、いずれかの列ベクトルまたは行ベクトルです)私は与えることを計算することができるように

[f(1,4),f(1,5),f(1,6),f(1,7); 
f(2,4),f(2,5),f(2,6),f(2,7); 
f(3,4),f(3,5),f(3,6),f(3,7)] 

xyのベクトル入力が同じ次元にない可能性があります。

f(x,y)の例がない場合は説明が難しいかもしれないことをご理解ください。 f(x,y)の私の使用のために、f(x,y)を表示することは非常に複雑かもしれません。簡略化のためf(x,y)x^2+yとし、一度定義するとベクトル入力の場合はx.^2+yに変更できません。

+0

ベクトルに作用するように 'x^2 + y'を適合させるのは簡単です。しかし、2つの変数の代わりに2つのベクトルを使って関数を与えることはできません。異なるサイズの2つのベクトルのすべての組み合わせで行列を作ることは難しくありません。 –

+0

また、一般的な方法は 'arrayfun'を使うのではなく、古き良きループを使うことです。私は 'arrayfun'がループより速い単一のケースをまだ見ていません。もちろん、 'arrayfun'はもっときれいに見えるかもしれません。 –

+0

ループがarrayfunを使用するよりも高速であることを意味しますか?私がループを使ってそれを書くには、私はダブルループを使います。ディメンションが非常に高い場合は、非常に遅くなる可能性があります。 –

答えて

0
>> x = [1 2 3]; 
>> y = [4 5 6 7]; 
>> outValue = foo(x, y); 

>> outValue 

outValue = 

5  6  7  8 
8  9 10 11 
13 14 15 16 

この機能を行います。ここでは

function out = foo(x, y) 

for i = 1 : length(x) 
    for j = 1 : length(y) 
     out(i, j) = x(i)^2 + y(j); 
    end 
end 
+0

関数 'foo'の小さなtypo:' out(i、j)= x(i)^ 2 + y(j); '内部ループをベクトル化することもできます: 'out(i、:) = x(i)^ 2 + y(:);' – serial

0

は、ループやインライン関数のために使用するコードです:

x = [1 2 3]; 
y = [4 5 6 7]; 
f = @(x,y) x^2 +y; 
A = zeros(length(x), length(y)); 
for m = 1:length(x) 
    for n = 1:length(y) 
     A(m, n) = f(x(m), y(n)); 
    end 
end 
disp(A); 

結果:ここで

A = 

    5  6  7  8 
    8  9 10 11 
    13 14 15 16 
2

がのセットですを使用した提案10:

すべてのケース( ABCD)のために出力されます
testfun = @(x,y) x^2+y; % non-vectorized form 
x = 1:3; 
y = 4:7; 
[X,Y] = ndgrid(x,y); 

% if the function can be vectorized (fastest!): 
testfun_vec = @(x,y) x.^2+y; % vectorized form 
A = testfun_vec(X,Y); 

% or without ndgrid (also super fast): 
B = bsxfun(testfun_vec,x.',y); % use the transpose to take all combinations 

% if not, or if it's not bivariate operation (slowest): 
C = arrayfun(testfun,X(:),Y(:)); 
C = reshape(C,length(x),length(y)); 

% and if you want a loop: 
D = zeros(length(x),length(y)); 
for k = 1:length(X(:)) 
    D(k) = testfun(X(k),Y(k)); 
end 

:あなたはあなたの関数をベクトル化することができるかどう

 5  6  7  8 
    8  9 10 11 
    13 14 15 16 

は、すでに述べたように - これは最善の解決策であり、 2つの入力がある場合はbsxfunも良い解決策です。そうでない場合は、小さなデータがあり、コードをコンパクトに使用したい場合は、を使用してください。大きな配列を扱う場合は、のネストなしループのためにを使用してください。

関連する問題