Code covered by the BSD License  

Highlights from
On-The-Fly Definition of Custom Matrix Objects

On-The-Fly Definition of Custom Matrix Objects

by

 

07 Feb 2010 (Updated )

Class of matrix-like objects with on-the-fly definable methods.

MatrixObj
classdef MatrixObj
%MATRIXOBJ -  a class for on-the-fly creation of customized matrix objects.
%
% For full details and examples see the UserGuide.
%
% Objects of the MatrixObj class (and its subclass DataObj) are capable of 
% behaving as matrices, but with math operators (+,-,*,\,.*,<,>,etc...) that 
% can be defined/redefined in any Mfile context, or even at the command line. This
% removes the restriction of writing a dedicated classdef file or class directory
% for every new matrix-type object that a user might wish to create.
% 
% The class works by storing function handles to the various matrix
% operator functions like plus, minus, mtimes, mldivide, etc... in a property
% of MatrixObj called Ops, which is a structure variable. Hence, one can set
% the matrix operators as desired simply by setting the fields of Ops to an
% appropriate function handle.
%
%
%DETAILS OF USAGE:
%
% The following constructs a default MatrixObj object M,
% 
%      M=MatrixObj;
% 
% This is probably the simplest way to construct the object. 
% The two main properties of MatrixObj are "Params" and "Ops". The
% properties can be populated with non-default values by dot-indexing
% assignment statements.
%
%        M.Params=...
%        M.Ops.methodname1=...
%
% Another construction syntax is
%
%     M=MatrixObj(Params,Ops)
%
% which can be used to set these properties directly.
%
% The Params property can be any MATLAB variable - numeric, struct, or 
% otherwise - and is meant for holding object parameters of any kind. 
% Its default/initial value is [].
% 
% The Ops property is a structure whose field names include all of the math 
% operator functions, plus a few more such as as sum(), inv(), conj(), size(),
% and display:
% 
%     and             horzcat       mpower        power          sum                  
%     colon           inv           mrdivide      rdivide        times              
%     ctranspose      ldivide       mtimes        size           transpose      
%     end             le            ne            subsasgn       uminus            
%     eq              lt            not           subsindex      uplus              
%     ge              minus         or            subsref        vertcat          
%     gt              mldivide      plus          display        conj                                             
%
% By assigning appropriate function handles to these fields, any/all of the
% corresponding class methods can be implemented on-the-fly. The fields of 
% Ops also default to [].
%
% Although M.Ops is in most ways manipulable as a structure using dot-indexing 
% syntax, any attempt to assign a field to Ops which is not in methods(MatrixObj)
% will result in an error. However, advanced users, if they wish, can add more  
% methods to the MatrixObj classdef, and these methods will then automatically 
% join the list of manipulable fields of Ops. 
%
%
%Copyright 2010-01-22, Matt Jacobson, Xoran Technologies, http://www.xorantech.com 
%
%based on the "Fatrix" class by Jeff Fessler, Copyright 2004-6-29, The University of Michigan


    %properties (Access=protected, Hidden=false)
    properties (Constant=true, Hidden=true);
     OpsTemplate=MatrixObj.InitOpsTemplate;
    end

    methods (Access=protected, Hidden=true);
        function Name=TemplateName(obj)
           Name='OpsTemplate';
        end
    end
    
    properties (Access=private)
        
       Params; 
    end
    
    properties
       Ops;
       Trans;
    end
    
    
    
   methods 
    
       function obj=MatrixObj(varargin)
                
            
           if nargin>=1 
               obj.Params=varargin{1};
           end
           
           if nargin>1,
               
               if isstruct(varargin{2})
                 f=fieldnames(varargin{2});  
                 c=struct2cell(varargin{2});
                 Pairs=[f(:), c(:)].';
               elseif mod(length(varargin),2)
                 error 'Methods must be specified either as struct or string/value pairs'
               else
                 Pairs=varargin;
               end
 
              obj.Ops=struct(Pairs{:});
           else
              
              obj.Ops=struct(obj.OpsTemplate{:});
           end
           

           
           
       end
    
    
       
       function obj=set.Ops(obj,Ops)
    
           
            if isempty(Ops), 
                
                error 'Setting Ops property to empty not allowed'
            end
            
            
           template=obj.(obj.TemplateName);
           %template=obj.OpsTemplate;
           
           f=fieldnames(Ops);
           [map,loc]=ismember(f,template(1,:));

           if map,
                           
               template(2,loc)=struct2cell(Ops);
            
               obj.Ops=struct(template{:});
               
           else
             BadFields=f(~map),  
             error(['Possible spelling mistake. The above fields assigned to MatrixObj.Ops do not correspond to existing methods of the MatrixObj class.'])
           end
               
           
           
       end
    
       function obj=set.Trans(obj,Ops)
    
           
           if isempty(Ops), obj.Trans=[]; return; end
           
           
           template=obj.(obj.TemplateName);
           
           f=fieldnames(Ops);
           [map,loc]=ismember(f,template(1,:));

           if map,
                           
               template(2,loc)=struct2cell(Ops);
            
               obj.Trans=struct(template{:});
               
           else
             BadFields=f(~map),  
             error(['Possible spelling mistake. The above fields assigned to MatrixObj.Trans do not correspond to existing methods of the MatrixObj class.'])
           end
               
           
           
       end
       
 
       
   end

   
    methods (Static, Hidden, Access=protected)
        
        
        function template=InitOpsTemplate
            
            m=methods('MatrixObj');
            
            [idx,loc]=ismember({'MatrixObj','get','set','loadobj'},m);
            m(loc)=[];
        
            template=[m(:).' ; repmat({[]},1,length(m))  ];


            
        end

    
    end 
    

      
    
    
end



Contact us