Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Vectorizing OOP code

Subject: Vectorizing OOP code

From: David Young

Date: 15 Sep, 2010 19:27:05

Message: 1 of 4

This is slightly related to the recent thread at [[url http://www.mathworks.com/matlabcentral/newsreader/view_thread/291551]] but I think my question is different enough to merit a new thread.

It's this: is there a compact way to vectorise all the methods of a class so that they operate on each element of an array of objects?

For example, suppose I have a class like this:

% --- start example
classdef test
    properties
        s = '';
    end
    methods
        function t = A(t)
            t.s = 'A was applied to t';
        end
    end
end
%--- end example

I can create an object and apply the method to it with

  t = test;
  t = t.A;

but I can't use the same syntax with an array of objects, because A expects a scalar:

  tarray(3) = test;
  tarray = tarray.A; % error

What I'd like is for method A to be called for each object in the array.

I could fix this in various ways for this particular example, but what I'm looking for is a general technique to apply to a class with lots of methods. My best effort so far looks like this:

%--- start example
classdef testvec
    properties
        s = '';
    end
    
    methods
        function t = A(t)
            % This block needs to be in each method
            if ~isscalar(t)
                t = t.loop(@A);
                return
            end
            
            % This is the method's code for a scalar object
            t.s = 'A was applied to t';
        end
    end
    
    methods (Access = private)
        function t = loop(t, method)
            for i = 1:length(t)
                t(i) = method(t(i));
            end
        end
    end
end
%--- end example

and now I can do

  ts(3) = testvec;
  ts = ts.A;
  ts.s % shows that it has succeeded

I feel as there ought to be a neater way to do this. Has anyone any ideas?

(By the way, I've stuck to value classes, but I don't think it would make any difference to use handle classes.)

Subject: Vectorizing OOP code

From: Matt J

Date: 16 Sep, 2010 02:28:06

Message: 2 of 4

You can do this even more compactly by overloading subsref, subsasgn and numel as in the classdef below. If you take this approach, you don't have to rewrite the other class methods. Note for example that the class method A(t) below is as you originally wrote it. In general though, I think that using arrays of objects is to be discouraged. They lead to discontiguous memory allocation for class property data, and hence slow performance.

classdef myClass

    properties
        s = '';
    end
    methods
        function t = A(t)
            t.s = 'A was applied to t';
        end
        
        
        function out=subsref(t,S)
            
            
            switch S(1).type
                
                case '.'
                    
                    methodName=S(1).subs;
                    
                    for i=1:length(t)
                     out(i)=feval(methodName,t(i));
                    end
            
                case '()'
                    
                    out=builtin('subsref',t,S);
                    
                otherwise
                  error 'Syntax not implemented'
                                    
            end
            
        end
        
        
        function N=numel(t)
            
            N=1;
            
        end
        
    end
end


%%%%%%%%%%%%%%%%USAGE TEST


>> t(3)=myClass; t=t.A;

>> t(1).s,t(2).s,t(3).s

ans =

A was applied to t


ans =

A was applied to t


ans =

A was applied to t

Subject: Vectorizing OOP code

From: Matt J

Date: 16 Sep, 2010 03:17:04

Message: 3 of 4

"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <i6rvbm$2mp$1@fred.mathworks.com>...
> You can do this even more compactly by overloading subsref, subsasgn and numel as in the classdef below. If you take this approach, you don't have to rewrite the other class methods. Note for example that the class method A(t) below is as you originally wrote it. In general though, I think that using arrays of objects is to be discouraged. They lead to discontiguous memory allocation for class property data, and hence slow performance.
========

On the downside, with this technique only the syntax

t.method(...)

will trigger the vectorized method execution and only from outside the classdef.

Subject: Vectorizing OOP code

From: David Young

Date: 16 Sep, 2010 06:53:05

Message: 4 of 4

Matt - thank you. That's very interesting and useful.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us