17

セルを使用して、作業中のデータを管理しています。次のようなことができるようになりたいです。

A = cellfun( @(X)( randn( 5,5 ) ), cell( 5,1 ), 'UniformOutput', 0 );
B = cellfun( @(X)( randn( 5,5 ) ), cell( 5,1 ), 'UniformOutput', 0 );
%#
%# Each of the following would fail if cell member dimensions
%# don't match up
%#
%# matrix sums for each cell entry
%# C = A + B;
C = cellfun( @(X,Y)( X + Y ), A, B, 'UniformOutput', 0 );
%#
%# direct/hadamard product
%# D = A .* B;
D = cellfun( @(X,Y)( X .* Y ), A, B, 'UniformOutput', 0 );
%#
%# matrix-matrix products (not across all entries)
%# E = A * B;
E = cellfun( @(X,Y)( X * Y ), A, B, 'UniformOutput', 0 );

しかし、私は非常に冗長な構文でそれを実行したくありません。セルの数学演算子の定義を提供するだけの場合、このための新しいクラスを作成するのは少しやり過ぎのようです。

質問:クラスはそれを実行する唯一の方法ですか?

これを行うためのクラスを作成すると、コードの作成が確実に簡単になります。私が目にする最大の欠点は最適化に関連していますが、それについて私を悩ませているものは他にもいくつかあります。

舞台裏で行われている最適化(たとえば、JacketがGPUで実行するために何かをコンパイルするとき)は、どの最適化を行うかを決定するのに苦労する可能性があります。例として、適切な次元の行列をいくつか含む2つのセル(A、B)があるとします。新しいセルを生成するコードを作成する場合:

Z = c1*A + c2*B

...スカラー{c1、c2}を使用すると、Jacket(またはその他)が次のように計算を行う必要があると簡単に判断できるように記述できます。

Z{kk} = c1*A{kk} + c2*B{kk}

またはおそらくそれよりもさらに優れた最適化。さもないと。速度が低下したり、メモリ効率が低下したりする可能性があります。例:

temp1 = cellfun( @(X)( c1*X ), A );
temp2 = cellfun( @(X)( c2*X ), B );
Z     = cellfun( @plus, temp1, temp2 );

MATLABまたはJacketがそれを最適化できないと仮定すると、これはメモリを過剰に使用することになります。

4

1 に答える 1

25

実際、MATLABの組み込みデータ型に対して、新しい演算子を作成したり、既存の演算子をオーバーロードしたりすることができます。整数型のデフォルトのオーバーフロー動作の変更に関する別のSO質問への回答で、この1つの例を説明します。

まず、セル配列に現在存在するメソッドを確認することをお勧めします。これは、関数METHODSを使用して実行できます。これは、MATLABR2010bで取得したものです。

>> methods cell

Methods for class cell:

aa2nt            issorted         regexptranslate  strfind          
accumarray       newdepfun        reshape          strjust          
cell2struct      nt2aa            rna2dna          strmatch         
ctranspose       nwalign          seq2regexp       strtok           
display          permute          setdiff          transpose        
dna2rna          regexp           setxor           union            
intersect        regexpi          sort             unique           
ismember         regexprep        strcat           

算術演算子メソッドは、演算子や演算子のように、同等の関数として上記のリストに表示されます。セル配列には、メソッド(演算子)のみが定義されています。残りの部分は自分で作成し、セル配列の引数に対して特定の演算子がどのように動作するかを定義する必要があります。plus+times.*transpose.'

これを行うには、最初にという新しいフォルダーを作成し、 MATLABパス@cell上の既存のフォルダーに配置します。次に、新しいメソッドをフォルダーに配置します。たとえば、セル配列のメソッドの非常に単純な実装(入力チェック、エラーチェックなどなし)は次のようになります。@cellplus

function C = plus(A,B)
  C = cellfun(@plus,A,B,'UniformOutput',false);  %# Apply plus cell-wise
end

In the above code, you would probably first want to check that the operands A and B are cell arrays of the same size. However, you could create whatever unique functionality you want, such as allowing B to be a scalar value which would get added to every cell of A. It's totally up to you to define how the + operator will behave for cell arrays.

This would then allow you to write your code in a much more compact way, as in this example:

>> A = {[1 2 3] [4 5] 6};  %# One 3-element cell array
>> B = {5 [4 5] 2};        %# Another 3-element cell array
>> C = A+B;                %# Use the new plus operator
>> C{:}                    %# Display the cell contents

ans =

     6     7     8

ans =

     8    10

ans =

     8

I can't really speak to the behind-the-scenes optimizations and how this might affect them. I know that the documentation "Techniques for Improving Performance" specifically mentions this about overloading built-in functions:

Overloading MATLAB built-in functions on any of the standard MATLAB data classes can negatively affect performance. For example, if you overload the plus function to handle any of the integer classes differently, you may hinder certain optimizations in the MATLAB built-in function code for plus, and thus may slow down any programs that make use of this overload.

However, in your case you aren't overloading existing functions for a class. You're simply creating new ones that didn't exist for that class, so it's hard to say what effect this may ultimately have on performance.

于 2011-03-21T04:13:36.667 に答える