1

Matlabで検索機能をオーバーロードできますか?

ご存じのとおり、 ind = find(X) は、配列 X のすべての非ゼロ要素を検索し、それらの要素の線形インデックスをベクトル ind に返します。

しかし、X がオブジェクトの配列の場合、find 関数を使用してこれらのプロパティに基づいて要素を見つけるにはどうすればよいでしょうか?

4

2 に答える 2

3

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.

オーバーロードされた検索関数で何をするかはあなた次第です。「これらのプロパティ」と呼ばれるものに一致する要素のインデックスを出力する関数を作成するだけです。

于 2013-08-09T11:36:51.560 に答える
2

ここでいくつかのことを行うことができます: オーバーロードfindするか、検索したい条件をポップアウトしfindてそれらの通常を呼び出します。おそらく、プロパティ アクセス式で通常の検索を使用する方が理にかなっています。

プロパティ アクセス式

オブジェクトまたはその他の構造に適用するfindには、プロパティ アクセス構文を使用して、探している条件を満たすオブジェクトを識別する論理式を作成し、それらを に渡しfindます。クラスにqtyプロパティがあり、それが検索対象であるとします。

ind = find( [X.qty] ~= 0 );

これらの論理式を組み合わせて、より複雑な検索を行うことができます。

ind = find( [X.ghz] > 3 && [X.cacheMB] > 2 && [X.price] < 600 )

find() のオーバーロード

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()

于 2013-08-12T23:48:39.133 に答える