将相等的函数句柄转换为其他相等的函数句柄

Transform equal function handles to other equal function handles

简约示例:

classdef MyClass
properties
    arr
    handArr
end
properties(Dependent)
    rowAcc
    colAcc
end
methods
    function obj = MyClass(arr, handRow, handCol)
        obj.arr = arr;
        obj.handArr{1} = handRow;
        if ~isequal(handRow, handCol)
            obj.handArr{2} = handCol;
        end
    end
    function r = get.rowAcc(obj)
        r = obj.handArr{1}(obj.arr);
    end
    function c = get.colAcc(obj)
        c = obj.handArr{end}(obj.arr);
    end
end
end

现在假设我将相同的函数传递给构造函数,我希望行和列的访问权限也相同:

f=@(x)@(y) y;
x=MyClass(1, f, f);
isequal(x.rowAcc, x.colAcc) //should be 1

这可能吗?

我有一个很好的理由'insane'要求:

我有几个算法 运行 具有 100+ MB 的输入,并将这两个函数作为输入,当它们相等时,可以非常有效地优化它们;要调用算法,我需要对封装在 class 中的输入函数进行转换。我无法更改算法(不是我的代码),它们使用 isequal 来调度它们自己的函数。

指向同一个匿名函数的两个变量被认为是相等的

f = @(x)x;
g = f;

isequal(f, g)
%   1

但是,如果您在不同时间定义匿名函数,则它们不会被视为相等,因为这两个函数的内部工作空间可能不同。

f = @(x)x;
g = @(x)x;

isequal(f, g)
%   0

为了让你的 属性 return 相等 句柄,你可以有一些 "shadow" 属性 (accessors_) 缓存访问器,只要 arr 属性 更改,您就更新这些缓存的值。

classdef MyClass

    properties
        arr
        handArr
    end

    properties (Access = 'protected')
        accessors_      % An array of accessor functions for rows & columns
    end

    properties (Dependent)
        rowAcc
        colAcc
    end

    methods
        function set.arr(obj, value)
            % Set the value
            obj.arr = value;

            % Update the accessors_
            self.accessors_ = obj.handArr{1}(obj.arr);

            % Only assign another accessor if we have a second one
            if numel(obj.handArr) > 1
                self.accessors_(2) = obj.handArr{2}(obj.arr);
            end
        end

        function res = get.rowAcc(obj)
            res = obj.accessors_(1);
        end

        function res = get.colAcc(obj)
            % If only one was stored, this will return a duplicate of it
            res = obj.accessors_(end);
        end
    end
end

这还有一个额外的好处,即您不必在每次检索 colAccrowAcc 时都创建函数句柄。