简体   繁体   中英

How can I overload find function in Matlab

Can I overload find function in Matlab?

As you know: ind = find(X) locates allnonzero elements of array X, and returns the linear indices ofthose elements in vector ind.

But when X is array of object, how can I use find function to findout elements based on these properties ?

As Lucius Domitius Ahenobarbus noted in the link he gave, there are strict rules of when you can overload functions in matlab.

Take the following class:

classdef myclass
    methods
        function find(self)
            fprintf('find(myclass) has been called.\n');
        end
    end
end

And execute

X = [myclass myclass myclass]
find(X)

This gives the following output:

X = 

  1x3 myclass with no properties.
  Methods

find(myclass) has been called.

What you do in your overloaded find function is up to you. Just write a function that prints out the indices of the elements that match what you call "these properties", whatever that is.

You can do a couple things here: overload find , or pop out the conditions you want to search on and call the regular find on those. It probably makes more sense to use regular find on a property-access expression.

Property Access Expressions

To apply find to objects or other structures, you can use property access syntax to create logical expressions that identify the objects that meet the conditions you're looking for, and pass those to find . Suppose your class has a qty property, and that's what you're searching on.

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

You can combine these logical expressions to do more complicated searches.

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

Overloading find()

You should probably only overload the well-known Matlab functions like find if your object methods are going to have similar semantics. The find function takes an array of logicals and returns numeric indexes. So it probably only makes sense for your class if the elements of that class could themselves be considered zero or nonzero values in a sense.

To overload a function to work on your class, just define a method in your class with the same name as the function. To work well with other Matlab code, it should probably accept the same typical arguments as the regular function, aside from allowing instances of your object.

Let's say your class represents points in 2-D space as (X,Y) coordinates, and you want to consider the point at the origin (0,0) to be zero, and all other points to be nonzero. You would provide a find method that tests both those points. To make the behavior consistent with Matlab's find , you could just implement the nonzero test in your code, and pass everything else on to the regular find function.

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

To be fully consistent with find , it's a bit more complicated, because find supports additional input and output arguments, which overloaded methods should too.

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

All this is kind of a pain, so you may only want to overload find if you need polymorphic behavior from your objects: that is, if you want to pass them in to other code that is written to call find() on its inputs. If you just need the output of find() locally in your code, it's probably easier to do property access. Or you could just provide an isnonzero() method for quick conversion to an input that find() will play well with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM