Matlabで検索機能をオーバーロードできますか?
ご存じのとおり、 ind = find(X) は、配列 X のすべての非ゼロ要素を検索し、それらの要素の線形インデックスをベクトル ind に返します。
しかし、X がオブジェクトの配列の場合、find 関数を使用してこれらのプロパティに基づいて要素を見つけるにはどうすればよいでしょうか?
Matlabで検索機能をオーバーロードできますか?
ご存じのとおり、 ind = find(X) は、配列 X のすべての非ゼロ要素を検索し、それらの要素の線形インデックスをベクトル ind に返します。
しかし、X がオブジェクトの配列の場合、find 関数を使用してこれらのプロパティに基づいて要素を見つけるにはどうすればよいでしょうか?
Lucius Domitius Ahenobarbus が彼が提供したリンクで指摘したように、matlab で関数をオーバーロードできるタイミングには厳密な規則があります。
次のクラスを受講します。
classdef myclass
methods
function find(self)
fprintf('find(myclass) has been called.\n');
end
end
end
そして実行
X = [myclass myclass myclass]
find(X)
これにより、次の出力が得られます。
X =
1x3 myclass with no properties.
Methods
find(myclass) has been called.
オーバーロードされた検索関数で何をするかはあなた次第です。「これらのプロパティ」と呼ばれるものに一致する要素のインデックスを出力する関数を作成するだけです。
ここでいくつかのことを行うことができます: オーバーロードfind
するか、検索したい条件をポップアウトしfind
てそれらの通常を呼び出します。おそらく、プロパティ アクセス式で通常の検索を使用する方が理にかなっています。
オブジェクトまたはその他の構造に適用するfind
には、プロパティ アクセス構文を使用して、探している条件を満たすオブジェクトを識別する論理式を作成し、それらを に渡しfind
ます。クラスにqty
プロパティがあり、それが検索対象であるとします。
ind = find( [X.qty] ~= 0 );
これらの論理式を組み合わせて、より複雑な検索を行うことができます。
ind = find( [X.ghz] > 3 && [X.cacheMB] > 2 && [X.price] < 600 )
find
オブジェクトメソッドが同様のセマンティクスを持つ場合など、よく知られている Matlab 関数のみをオーバーロードする必要があります。このfind
関数は論理値の配列を取り、数値インデックスを返します。したがって、そのクラスの要素自体がある意味でゼロまたはゼロ以外の値と見なすことができる場合にのみ、クラスにとって意味があると思われます。
クラスで機能するように関数をオーバーロードするには、関数と同じ名前でクラスにメソッドを定義するだけです。他の Matlab コードとうまく連携するには、オブジェクトのインスタンスを許可する以外に、通常の関数と同じ一般的な引数を受け入れる必要があります。
クラスが 2 次元空間の点を (X,Y) 座標として表し、原点 (0,0) の点をゼロと見なし、他のすべての点を非ゼロと見なしたいとします。find
これらの両方のポイントをテストするメソッドを提供します。動作を Matlab の と一致させるにはfind
、コードにゼロ以外のテストを実装し、他のすべてを通常のfind
関数に渡すことができます。
class point
properties
X;
Y;
end
methods
function out = find(obj)
% Test for zero/nonzero points
x = reshape([obj.X], size(x));
y = reshape([obj.Y], size(y));
isNonzero = x + y; % Quantity is not meaningful, but covers zero/nonzero/NaN
out = find(isNonzero);
end
end
end
と完全に一致させるには、オーバーロードされたメソッドもサポートする必要がある追加の入力引数と出力引数をサポートするfind
ため、もう少し複雑です。find
class point
properties
X;
Y;
end
methods
function varargout = find(obj, varargin)
varargout = cell(1, max(nargout, 1));
% TODO: In production code, verify that varargin does not
% contain @point objects, to avoid infinite recursion
% Test for zero/nonzero points
x = reshape([obj.X], size(obj));
y = reshape([obj.Y], size(obj));
isNonzero = x + y; % Quantity is not meaningful, but covers zero/nonzero/NaN
[varargout{:}] = find(isNonzero, varargin{:});
end
end
end
これはすべて面倒なことなので、オブジェクトからポリモーフィックな動作が必要な場合、つまり、入力find
を呼び出すように記述された他のコードにオブジェクトを渡したい場合にのみ、オーバーロードする必要があります。コードでローカルにfind()
の出力だけが必要な場合は、おそらくプロパティ アクセスを行う方が簡単です。または、うまく機能する入力にすばやく変換する方法をfind()
提供することもできます。isnonzero()
find()