たとえば、magic(5)
から中央の値を読み取りたい場合、次のようにできます。
M = magic(5);
value = M(3,3);
value == 13
を取得します。次のいずれかのようなことができるようにしたいと思います。
value = magic(5)(3,3);
value = (magic(5))(3,3);
中間変数を不要にします。ただし、MATLABはUnbalanced or unexpected parenthesis or bracket
の前の最初の括弧で3
について文句を言います。
最初に変数に割り当てることなく、配列/行列から値を読み取ることは可能ですか?
実際にはis必要なことを行うことができますが、インデックス演算子の関数形式を使用する必要があります。 ()
を使用してインデックス作成操作を実行すると、実際には subsref
関数を呼び出しています。だから、あなたはできませんがこれを行う:
value = magic(5)(3, 3);
あなたはcanこれを行うことができます:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Glyいですが、可能です。 ;)
一般に、インデックス付けステップを関数呼び出しに変更するだけで、2セットの括弧が連続して続くことはありません。これを行う別の方法は、独自の 匿名関数 を定義して、添え字付きのインデックス付けを行うことです。例えば:
subindex = @(A, r, c) A(r, c); % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3); % Use the function to index the matrix
しかし、すべてを言って完了したら、一時的なローカル変数ソリューションはmuchより読みやすく、間違いなく私が提案するものです。
良いブログ投稿 on Matlabのアートのローレン 数日前に役立つかもしれない宝石がいくつかありました。特に、次のようなヘルパー関数を使用します。
paren = @(x, varargin) x(varargin{:});
curly = @(x, varargin) x{varargin{:}};
paren()
は次のように使用できます
paren(magic(5), 3, 3);
戻ります
ans = 16
また、これはgnoviceの答えよりも高速になると推測しますが、チェックしていません(プロファイラーを使用してください!!!)。そうは言っても、これらの関数定義をどこかに含める必要があります。私は個人的にそれらを独立した機能にしました。なぜなら、それらは非常に便利だからです。
これらの関数およびその他の関数は、MATLABアドオンエクスプローラーまたは ファイル交換 で利用可能なFunctional Programming Constructsアドオンで利用可能になりました。
文書化されていない機能の使用についてどう思いますか?
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
またはセル配列の場合:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
魔法のように:)
悪いニュース、上記のハックはR2015bではもう機能しません!それは問題ありません、文書化されていない機能であり、サポートされている機能として信頼することはできません:)
このタイプのものはどこにあるのか疑問に思う人は、fullfile(matlabroot,'bin','registry')
フォルダーを見てください。そこには、あらゆる種類の便利なものをリストしたXMLファイルがたくさんあります。これらの関数の一部を直接呼び出すと、MATLABセッションが簡単にクラッシュする可能性があることに注意してください。
残念ながら、magic(5)(3,3)
のような構文はmatlabではサポートされていません。一時的な中間変数を使用する必要があります。使用後にメモリを解放できます。
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
実行時間を標準の方法(結果を割り当ててからエントリにアクセスする)と比較する場合、それらはまったく同じであることに注意してください。
subs=@(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0103
>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0101
私の意見では、一番下の行は次のとおりです。MATLABにはポインターがありません。
新しい関数を作成すると、より簡単になります。
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
そしてそれを使用します:
value = getElem(magic(5), 3, 3);
これを行うには、最初の表記が最も簡潔な方法です。
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
これをループで実行している場合は、毎回Mを再割り当てするだけで、clearステートメントも無視できます。
Amroの答えを補完するために、feval
の代わりにbuiltin
を使用できます。演算子関数をオーバーロードしようとしない限り、実際には違いはありません。
BUILTIN(...)はFEVAL(...)と同じですが、オーバーロードされた関数が存在する場合でも元の組み込みバージョンの関数を呼び出します(これが機能するには、BUILTINをオーバーロードしてはいけません)。
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
おもしろいのは、feval
がbuiltin
よりもわずかに速い(〜3.5%)ように見えることです。少なくともMatlab 2013bでは、feval
とは異なり、builtin
は関数がオーバーロードされているかどうかを確認する必要があるため、奇妙です:
>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.