Code covered by the BSD License  

Highlights from
Zero-Based Indexable Arrays (OOP Exercise)

from Zero-Based Indexable Arrays (OOP Exercise) by Matt J
Creates arrays whose indexing starts from zero instead of one.

ZeroBased
classdef ZeroBased
%ZeroBased - a class of arrays like MATLAB normal arrays, but can be indexed
%starting from 0.
%
%USAGE:
%
%  A=ZeroBased(B)
%
%where B is a normal MATLAB matrix will cast B to A, which is exactly 
%the same, except that it is 0-based indexed instead of 1-based.
%
%
%EXAMPLE 1:
%
%  >>A=ZeroBased(rand(3))
% 
%     A =
% 
%         0.7922    0.0357    0.6787
%         0.9595    0.8491    0.7577
%         0.6557    0.9340    0.7431
% 
%   >>A(0,2)
% 
%     ans =
% 
%         0.6787
%
%EXAMPLE 2:
%
%It works for sparse matrices too, and will even display at the command line
%with zero-based indexing display syntax, e.g.,
%
%  >> A=ZeroBased(speye(3))
% 
%     A =
% 
%        (0,0)        1
%        (1,1)        1
%        (2,2)        1
%
%
%by Matt Jacobson


   properties
      
       data;
       %classname;
       
   end


    methods
       
        function obj=ZeroBased(data)
            %constructor for ZeroBased
            
            obj.data=data;
            %obj.classname=class(data);
            
        end
        
        
       function  varargout=size(obj,varargin)

          [varargout{1:nargout}] = size( obj.data , varargin{:});
            
       end    
        
        function objnew=subsref(obj,S)
        %SUBSREF for ZeroBased class 
        
            nn=length(S.subs);
            for ii=1:nn
             if ~(ischar(S.subs{ii})|| islogical(S.subs{ii})),  
              S.subs{ii}=S.subs{ii}+1;
             end
            end

            objnew=ZeroBased(builtin('subsref',obj.data,S));

            
        end

        
        function obj=subsasgn(obj,S,rhs)
        %SUBSASGN for ZeroBased class    
            
            nn=length(S.subs);
            for ii=1:nn
             if ~(ischar(S.subs{ii})||islogical(S.subs{ii})),  
              S.subs{ii}=S.subs{ii}+1;
             end
            end

           obj.data=builtin('subsasgn',obj.data,S,rhs);
            
            
        end        
        
        function E=end(obj,K,N)
            
            E=builtin('end',obj.data,K,N)-1;
            
        end
        
        function I=subsindex(obj)
            
            I=double(obj.data-1);
            
        end
  
        function I=colon(varargin)
            
            varargin=recastCell(varargin);
            I=ZeroBased(colon(varargin{:}));
            
        end
        
        
        function  varargout=find(obj,varargin)
            
          [varargout{1:nargout}]=find(obj.data,varargin{:});
          
          for ii=1:min(2,nargout)
            varargout{ii}=varargout{ii}-1;
          end
          
        end  
        
        function display(obj)
            
            l=inputname(1);
            T=evalc('obj.data'); %only way to get at the builtin display method
            if ~isempty(l), 
                 T=strrep(T,'ans =',[l ' =']);
            end

            jj=find(T~=sprintf('\n'),1,'last');
            
            T=T(1:jj);
           
            
            if issparse(obj)
                
                Delimiters={'\((\d*),', ',(\d*)\)'};
                
                str=Delimiters{1};
                
                [tokens,starts]=regexp(T,str,'tokens','start');
                

                Indices1Based=cellfun(@(x) x{1}, tokens, 'uni', 0);

                Indices0Based=cellfun(...
                       @(i) num2str(str2double(i)-1), Indices1Based, 'uni', 0);
                

                  for ii=1:length(Indices1Based)
                  
                      st=starts(ii);
                      len1=length(Indices1Based{ii});
                      len0=length(Indices0Based{ii});
                      
                      
                      ub=st+len1;
                      lb=ub-len0+1;
                      
                      T(st+1:ub)=' ';
                      T(lb:ub)=Indices0Based{ii};
                      
                      if len0<len1, T(st:st+1)=fliplr(T(st:st+1)); end
                      
                  end
                   
                   
                   
                str=Delimiters{2};
                
                [tokens,starts]=regexp(T,str,'tokens','start');
                
                Indices1Based=cellfun(@(x) x{1}, tokens, 'uni', 0);

                Indices0Based=cellfun(...
                       @(i) num2str(str2double(i)-1), Indices1Based, 'uni', 0);
                

                  for ii=1:length(Indices1Based)
                  
                      st=starts(ii);
                      len1=length(Indices1Based{ii});
                      len0=length(Indices0Based{ii});
                      
                      
                      ub=st+len0;
                      lb=st+1;
                      
                      T(st+1:st+len1)=' ';
                      T(lb:ub)=Indices0Based{ii};
                      
                      if len0<len1, T(ub+1:ub+2)=fliplr(T(ub+1:ub+2)); end
                      
                  end
              
 
                  
            elseif iscell(obj) || isnumeric(obj) || islogical(obj) %%Fix the Column labels
            
                
                Delimiters={'Columns (\d*) ', 'through (\d*)\s', 'Column (\d*)\s'};
       
                for kk=1:length(Delimiters)

                str=Delimiters{kk};
                    
                [tokens,tokenExtents]=regexp(T,str,'tokens','tokenExtents');
                

                Indices1Based=cellfun(@(x) x{1}, tokens, 'uni', 0);

                Indices0Based=cellfun(...
                       @(i) num2str(str2double(i)-1), Indices1Based, 'uni', 0);
                

                  for ii=1:length(Indices1Based)
                  
                      len0=length(Indices0Based{ii});                     
                      
                      ub=tokenExtents{ii}(2);
                      lb=tokenExtents{ii}(1);
                      
                      T(lb:ub)=' ';
                      T(lb:lb+len0-1)=Indices0Based{ii};

                      
                  end
                 

                end    
                
                

            end    

              

            disp(T), disp ' '
            
            
            
        end
        
        
%%Unary ops    
        function  obj=uplus(obj)
       
            
        end

        function  obj=uminus(obj)
        
           obj.data=-obj.data;
            
        end
        
        
        function  obj=not(obj)

            obj.data = ~obj.data ;
            
        end
        
        %%Binary ops
        
        function  obj=plus(L,R)
 
          obj = ZeroBased( recast(L) + recast(R));
            
        end

        function  obj=minus(L,R)
        
          
           obj = ZeroBased( recast(L) - recast(R));
            
        end        
        
        
        
       function  obj=times(L,R)
           
            obj = ZeroBased( recast(L) .* recast(R));
            
       end

        
       function  obj=rdivide(L,R)
       
              
               obj = ZeroBased( recast(L) ./ recast(R), s);
            
        end

        function  obj=ldivide(L,R)
            
             obj = ZeroBased( recast(L) .\ recast(R));
            
        end        
        



        function  obj=power(L,R)
             
             obj = ZeroBased( recast(L) .^ recast(R));
            
        end     

        

        function  obj=lt(L,R)

            obj = ZeroBased( recast(L) < recast(R));

        end   
        
        function  obj=le(L,R)
     
             obj = ZeroBased( recast(L) <= recast(R));

        end         
        
        function  obj=gt(L,R)
    
             obj = ZeroBased( recast(L) > recast(R));

        end      
        
  
        function  obj=ge(L,R)

             obj = ZeroBased( recast(L) >= recast(R));

        end   
     
        function  obj=eq(L,R)

           obj = ZeroBased( recast(L) == recast(R));

        end     
        
        function  obj=ne(L,R)
          
           obj = ZeroBased( recast(L) ~= recast(R));

        end    

        
        
        function  obj=and(L,R)
          
           obj = ZeroBased( recast(L) & recast(R));

        end         
        
        function  obj=or(L,R)

             obj = ZeroBased( recast(L) | recast(R));

        end    
        
       %%Methods for 2D Matrices 
       function  obj=inv(obj)

        
          obj = ZeroBased(inv(recast(obj)));
            

       end
        
      function  obj=triu(obj,varargin)


          obj = ZeroBased(  triu(  recast(obj) , varargin{:} )  );
            
       end
       
       function  obj=tril(obj,varargin)

          obj = ZeroBased( tril(  recast(obj) , varargin{:} ));
            
       end      
       
       
       function  obj=transpose(obj)

          obj.data=obj.data.';
            
       end
       
       function  obj=ctranspose(obj)
 
          obj.data=obj.data';
            
       end   
       
       function  obj=mtimes(L,R)

           
          obj = ZeroBased( recast(L)*recast(R));
            
        end
       
       function  obj=mrdivide(L,R)

          
          obj = ZeroBased( recast(L)/recast(R));
            
        end

        function  obj=mldivide(L,R)
          
          obj = ZeroBased( recast(L)\recast(R));
            
        end        
   
       function  obj=mpower(L,R)

        
         obj = ZeroBased( recast(L)^recast(R));
            
       end   
        
        
       function  obj=sum(obj,varargin)

          obj.data = sum( obj.data , varargin{:});
            
       end    
       
       
       function  obj=prod(obj,varargin)

          obj.data = prod( obj.data , varargin{:});
            
       end    
       
       function  obj=mean(obj,varargin)

          obj.data = mean( obj.data , varargin{:});
            
       end       
       
       
       function  obj=permute(obj,varargin)

          obj.data = permute( obj.data , varargin{:});
            
       end    
       
       function  obj=ipermute(obj,varargin)

          obj.data = ipermute( obj.data , varargin{:});
            
       end          
       
       function  obj=abs(obj)

          obj.data = abs( obj.data);
            
       end        
       
       
       function  obj=all(obj,varargin)

          obj.data = all( obj.data , varargin{:});
            
       end    
       
       function  obj=any(obj,varargin)

          obj.data = any( obj.data , varargin{:});
            
       end    
       
       function  obj=circshift(obj,varargin)

          obj.data = circshift( obj.data , varargin{:});
            
       end    
       
       function  obj=conj(obj,varargin)

          obj.data = conj( obj.data , varargin{:});
            
       end           
       
       

       
       function  Z=conv(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(conv(varargin{:}));
            
       end        
       
       function  Z=conv2(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(conv2(varargin{:}));
            
       end   
       
       function  Z=convn(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(convn(varargin{:}));
            
       end 
       
       
       function  Z=fft(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(fft(varargin{:}));
            
       end        
       
       function  Z=fft2(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(fft2(varargin{:}));
            
       end   
       
       function  Z=fftn(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(fftn(varargin{:}));
            
       end 
       
       function  Z=bsxfun(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(bsxfun(varargin{:}));
            
       end 
       
        function  Z=cat(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(cat(varargin{:}));
            
        end       
       
        function  Z=horzcat(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(horzcat(varargin{:}));
            
        end        
        
        
        function  Z=vertcat(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(horzcat(varargin{:}));
            
        end 
       
        function  out=double(obj)

           out=double(obj.data);
            
        end       
 
        function  out=logical(obj)

           out=logical(obj.data);
            
        end
        
        function  out=sparse(obj)

           out=sparse(obj.data);
            
        end  
        
        function  out=single(obj)

           out=single(obj.data);
            
        end  
        
        
        
        function  obj=flipdim(obj)

           obj.data=flipdim(obj.data);
            
        end        
        
        function  obj=fliplr(obj)

           obj.data=fliplr(obj.data);
            
        end           
        
        function  obj=flipud(obj)

           obj.data=flipud(obj.data);
            
        end   
        
        function  obj=full(obj)

           obj.data=full(obj.data);
            
        end           
        
        function  obj=imag(obj)

           obj.data=imag(obj.data);
            
        end           
  
        
        function  obj=real(obj)

           obj.data=real(obj.data);
            
        end           
             
        
        function  Z=isequal(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(isequal(varargin{:}));
            
            
        end           
  
        
        function  Z=isequalwithequalnans(varargin)

          varargin=recastCell(varargin); 
          Z = ZeroBased(isequalwithequalnans(varargin{:}));
            
        end  
         
        function  obj=isempty(obj)

           obj.data=isempty(obj.data);
            
        end           
  
        
        function  obj=isreal(obj)

           obj.data=isreal(obj.data);
            
        end        
        
        function  obj=issparse(obj)

           obj.data=issparse(obj.data);
            
        end         
    
        function  obj=isfinite(obj)

           obj.data=isfinite(obj.data);
            
        end       
        
        function  obj=isinf(obj)

           obj.data=isinf(obj.data);
            
        end        
        
        function  obj=islogical(obj)

           obj.data=islogical(obj.data);
            
        end         
    
        function  obj=isfloat(obj)

           obj.data=isfloat(obj.data);
            
        end   
        
        
        
        function  obj=isnan(obj)

           obj.data=isnan(obj.data);
            
        end         
   
        function  obj=isnumeric(obj)

           obj.data=isnumeric(obj.data);
            
        end      
        
        function  obj=length(obj)

           obj.data=length(obj.data);
            
        end       
        
        function  obj=loadobj(obj)

           obj=ZeroBased(obj.data);
            
        end       
        
         function  [varargout]=max(obj,varargin)
     
           [varargout{1:nargout}]=max(obj.data,varargin{:});
           if nargout>1, varargout{2}=varargout{2}-1; end
            
           varargout=cellfun(@(c) ZeroBased(c), varargout,'uni',0);
           
         end            
   
         function  [varargout]=min(obj,varargin)
     
           [varargout{1:nargout}]=min(obj.data,varargin{:});
           if nargout>1, varargout{2}=varargout{2}-1; end
           
           varargout=cellfun(@(c) ZeroBased(c), varargout,'uni',0);
           
         end        
         
         
         function  obj=ndims(obj)

           obj.data=ndims(obj.data);
            
         end   
        

         function  obj=nnz(obj)

           obj.data=nnz(obj.data);
            
         end   
         
         function  obj=nonzeros(obj)

           obj.data=nonzeros(obj.data);
            
         end   
        

         function  obj=numel(obj)

           obj.data=numel(obj.data);
            
         end
         
         function  obj=nzmax(obj,varargin)

           obj.data=nzmax(obj.data,varargin{:});
            
         end  
         
         function  obj=repmat(obj,varargin)

           obj.data=repmat(obj.data,varargin{:});
            
         end  
         
         function  obj=reshape(obj,varargin)

           obj.data=reshape(obj.data,varargin{:});
            
         end  
         
         
         function  obj=rot90(obj,varargin)

           obj.data=rot90(obj.data,varargin{:});
            
         end  
         
        
         function  obj=sqrt(obj)

           obj.data=sqrt(obj.data);
            
         end
         
         function  obj=squeeze(obj)

           obj.data=squeeze(obj.data);
            
         end
         
         function  [varargout]=shiftdim(obj,varargin)
     
           [varargout{1:nargout}]=shiftdim(obj.data,varargin{:});
           if nargout>1, varargout{2}=varargout{2}-1; end
           
           varargout=cellfun(@(c) ZeroBased(c), varargout,'uni',0);
           
         end        
         
         
    end
    
end


function out=recast(in)

  if isa(in,'ZeroBased')
   out=in.data;
  else
     out=in; 
  end
  
%   if isa(in,'ZeroBased')
%    out=in.data;
%   elseif isscalar(in)
%      out=in; 
%    else
%        error 'Mixed operations involving ZeroBased array and ordinary 1-based non-scalar arrays are forbidden.'
%   end
end


function outcell=recastCell(incell)

 map=cellfun('isclass',incell,'ZeroBased' );
 incell(map)=cellfun(@(c) c.data,incell(map), 'uni',0);
 outcell=incell;
 
end
    

Contact us