1

Minimalistic Example:

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

Now assume I pass equal functions to the constructor, I want the row and col access would also be the same:

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

Is this possible?

I have a good reason for this 'insane' requirement:

I have several algorithms which run with 100+ MBs of input and takes those two functions as input, and when they are equal they can be optimized very efficiently; to call the algorithms I need to make transformations to the input functions which are encapsulated inside this class. I can't change the algorithms (not my code) and they use isequal on they're own functions to dispatch.

Omer Rosler
  • 237
  • 1
  • 10

1 Answers1

2

Two variables pointing to the same anonymous function are considered to be equal

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

isequal(f, g)
%   1

However, if you define the anonymous functions at different times, then they are not considered to be equal because the internal workspaces of the two functions could differ.

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

isequal(f, g)
%   0

In order to have your property return equal handles, you could have some "shadow" property (accessors_) which caches the accessors and you update these cached values whenever the arr property is changed.

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

This also has the added benefit that you aren't creating function handles every time that colAcc and rowAcc are retrieved.

Suever
  • 64,497
  • 14
  • 82
  • 101