简体   繁体   English

如何在Matlab中重载find函数

[英]How can I overload find function in Matlab

Can I overload find function in Matlab? 我可以在Matlab中重载find函数吗?

As you know: ind = find(X) locates allnonzero elements of array X, and returns the linear indices ofthose elements in vector ind. 如您所知:ind = find(X)定位数组X的所有非零元素,并返回矢量ind中这些元素的线性索引。

But when X is array of object, how can I use find function to findout elements based on these properties ? 但是,当X是对象数组时,如何使用find函数基于这些属性来查找元素?

As Lucius Domitius Ahenobarbus noted in the link he gave, there are strict rules of when you can overload functions in matlab. 正如Lucius Domitius Ahenobarbus在他给出的链接中指出的那样,在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. 您在重载的find函数中所做的一切取决于您。 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. 你可以在这里做两件事情:超载find ,或弹出你要搜索并拨打正规的条件find这些。 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 . 要将find应用于对象或其他结构,您可以使用属性访问语法来创建逻辑表达式,以标识满足所需条件的对象,并将其传递给find Suppose your class has a qty property, and that's what you're searching on. 假设您的课程有一个qty属性,那就是您要搜索的属性。

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() 重载find()

You should probably only overload the well-known Matlab functions like find if your object methods are going to have similar semantics. 如果您的对象方法将具有相似的语义,则可能应该只重载著名的Matlab函数(例如find The find function takes an array of logicals and returns numeric indexes. find函数采用逻辑数组并返回数字索引。 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. 为了与其他Matlab代码良好配合,除了允许对象的实例外,它可能还应接受与常规函数相同的典型参数。

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. 假设您的类将二维空间中的点表示为(X,Y)坐标,并且您想将原点(0,0)上的点视为零,并将所有其他点视为非零。 You would provide a find method that tests both those points. 您将提供一个find方法来测试这两个点。 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. 为了使行为与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

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. 为了与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

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. 所有这一切都是一种痛苦,因此,如果您需要对象的多态行为,则可能只想重载find ;也就是说,如果要将它们传递给编写用于在其输入上调用find()其他代码。 If you just need the output of find() locally in your code, it's probably easier to do property access. 如果仅在代码中需要本地find()的输出,则进行属性访问可能会更容易。 Or you could just provide an isnonzero() method for quick conversion to an input that find() will play well with. 或者,您可以只提供isnonzero()方法以快速转换为find()可以很好地使用的输入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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