web-dev-qa-db-ja.com

MATLABの関数をマップしますか?

MATLABにはMap関数がないことに少し驚いていますが、それは私がそれなしでは生きていけないものなので、私は1つを一緒にハックしました。より良いバージョンはありますか? MATLAB向けのやや標準的な機能プログラミングライブラリがありますか?

function results = map(f,list)
% why doesn't MATLAB have a Map function?
results = zeros(1,length(list));
for k = 1:length(list)
    results(1,k) = f(list(k));
end

end

使用法は、例えば.

map( @(x)x^2,1:10)
95
user121550

簡単な答え:組み込み関数 arrayfun は、数値配列に対してmap関数が行うこととまったく同じです。

>> y = arrayfun(@(x) x^2, 1:10)
y =

     1     4     9    16    25    36    49    64    81   100

同様に動作する他の2つの組み込み関数があります: cellfun (セル配列の要素で動作します)および structfun (で動作します)構造体の各フィールド)。

ただし、特に要素単位の 算術演算子 を使用して、ベクトル化を利用する場合、これらの関数は多くの場合必要ありません。あなたが与えた例では、ベクトル化されたソリューションは次のようになります:

>> x = 1:10;
>> y = x.^2
y =

     1     4     9    16    25    36    49    64    81   100

一部の操作は自動的に要素間で動作します(ベクトルにスカラー値を追加するなど)が、他の演算子は要素ごとの操作(演算子の前に.で示される)の特別な構文があります。 MATLABの多くの組み込み関数は、要素ごとの演算(多くの場合、 summean for))、したがってマップ関数を必要としません。

要約すると、配列内の各要素を二乗するいくつかの異なる方法があります。

x = 1:10;       % Sample array
f = @(x) x.^2;  % Anonymous function that squares each element of its input

% Option #1:
y = x.^2;  % Use the element-wise power operator

% Option #2:
y = f(x);  % Pass a vector to f

% Option #3:
y = arrayfun(f, x);  % Pass each element to f separately

もちろん、このような単純な操作では、オプション#1が最も賢明な(そして効率的な)選択です。

130
gnovice

ベクトルおよび要素単位の操作に加えて、セル配列に関数をマッピングするためのcellfunもあります。例えば:

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans = 
    'A'    'B'    'C'

'UniformOutput'がtrue(または提供されない)の場合、セル配列の次元に従って結果を連結しようとします。

cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC
10
kwatford

Matlabのベクトル化を使用したかなり単純なソリューションは次のとおりです。

a = [ 10 20 30 40 50 ]; % the array with the original values
b = [ 10 8 6 4 2 ]; % the mapping array
c = zeros( 1, 10 ); % your target array

今、タイピング

c( b ) = a

返す

c = 0    50     0    40     0    30     0    20     0    10

c(b)は、サイズ5のベクトルへの参照であり、bで指定されたインデックスにcの要素があります。この参照ベクトルに値を割り当てると、c(b)にはcの値への参照が含まれ、コピーは含まれないため、cの元の値が上書きされます。

2
doc

必要な結果が関数の配列である場合、組み込みのarrayfunは機能しないようです:例:map(@(x)[x x ^ 2 x ^ 3]、1:10)

以下のわずかな変更により、この作業が改善されます。

function results = map(f,list)
% why doesn't MATLAB have a Map function?
for k = 1:length(list)
    if (k==1)
        r1=f(list(k));
        results = zeros(length(r1),length(list));
        results(:,k)=r1;
    else
        results(:,k) = f(list(k));

    end;
end;
end
1
Foo Bara

Matlabにマップ関数が組み込まれていない場合、効率性を考慮している可能性があります。実装では、ループを使用してリストの要素を反復処理しますが、これは一般的にmatlabの世界では嫌われています。ほとんどの組み込みmatlab関数は「ベクトル化」されています。 e。配列全体で関数を呼び出す方が、自分で繰り返し処理して各要素に対して関数を呼び出すよりも効率的です。

つまり、これ


a = 1:10;
a.^2

これよりずっと速い


a = 1:10;
map(@(x)x^2, a)

マップの定義を前提としています。

0
Dima

値のリストに適用されるスカラー関数は各値に適用されるため、mapと同様に機能するため、mapは必要ありません。ちょうど試して

l = 1:10
f = @(x) x + 1

f(l)

あなたの特定のケースでは、あなたも書くことができます

l.^2
0
Dario