diff m-toolbox/classes/@matrix/elementOp.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m-toolbox/classes/@matrix/elementOp.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,154 @@
+% ELEMENTOP applies the given operator to the input matrices.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: ELEMENTOP applies the given operator to the input matrices.
+%
+% CALL:        a = elementOp(op, opname, opsym, infoObj, pl, fcnArgIn, varNames)
+%
+% PARAMETERS:  op       - MATLAB operation name
+%              opname   - Name for displaying
+%              opsym    - Operation symbol
+%              infoObj  - minfo object
+%              pl       - default plist
+%              fcnArgIn - Input argument list of the calling fcn.
+%              varNames - Variable names of the input
+%
+% VERSION:     $Id: elementOp.m,v 1.10 2011/02/11 12:30:29 hewitson Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function varargout = elementOp(varargin)
+  
+  import utils.const.*
+  
+  % Settings
+  callerIsMethod = varargin{1};
+  op     = varargin{2};
+  opname = varargin{3};
+  opsym  = varargin{4};
+  
+  infoObj = varargin{5};
+  pl      = varargin{6};
+  
+  fcnArgIn = varargin{7};
+  varNames = varargin{8};
+  
+  if numel(fcnArgIn) ~=2
+    error('### The operator %s can only operate on two inputs', op);
+  end
+  
+  mat1 = fcnArgIn{1};
+  mat2 = fcnArgIn{2};
+    
+  if isnumeric(mat1) || ischar(mat1)
+    if ischar(mat1)
+      mat1 = eval(mat1);
+    end
+    nums = mat1;
+    varNames{1} = utils.helper.mat2str(nums);
+    % build a numeric/char object of the same size of mat2
+    mat1 = copy(mat2,1);
+    for ii=1:numel(mat1.objs)
+      if numel(nums) == numel(mat1.objs)
+        expr = nums(ii);
+      else
+        expr = nums;
+      end
+      mat1.objs(ii) = feval(class(mat2.objs), expr);
+      mat1.objs(ii).setName(num2str(expr));
+      if isprop(mat2.objs(ii), 'xunits') || (isa(mat2.objs(ii), 'ao') && ...
+          isprop(mat2.objs(ii).data, 'xunits'))
+        mat1.objs(ii).setXunits(mat2.objs(ii).xunits);
+      end
+    end
+  end
+  if isnumeric(mat2) || ischar(mat2)
+    if ischar(mat2)
+      mat2 = eval(mat2);
+    end
+    nums = mat2;
+    varNames{2} = utils.helper.mat2str(nums);
+    % build a numeric/char object of the same size of mat1
+    mat2 = copy(mat1,1);
+    for ii=1:numel(mat2.objs)
+      if numel(nums) == numel(mat2.objs)
+        expr = nums(ii);
+      else
+        expr = nums;
+      end
+      mat2.objs(ii) = feval(class(mat1.objs), expr);
+      mat2.objs(ii).setName(utils.helper.num2str(expr));
+      if isprop(mat2.objs(ii), 'xunits') || (isa(mat2.objs(ii), 'ao') && ...
+          isprop(mat2.objs(ii).data, 'xunits'))
+        mat2.objs(ii).setXunits(mat1.objs(ii).xunits);
+      end
+    end
+  end
+  
+  % matrix objects must all contain the same class
+  if ~strcmp(class(mat1.objs), class(mat2.objs))
+    error('### The %s operator can only apply to matrix objects containing the same class of objects. [%s .* %s]', op, class(mat1.objs), class(mat2.objs));
+  end
+  
+  
+  % init output
+  mat = copy(mat1,1);
+    
+  %%%%%%%%%%   If the first or second input is only one object then   %%%%%%%%%%
+  %%%%%%%%%%   resize the input to the size of the other object.      %%%%%%%%%%
+  if numel(mat1.objs) == 1 && numel(mat1.objs) ~= numel(mat2.objs)
+    h1 = mat1.hist;
+    obj1 = mat1.objs;
+    obj1(1:numel(mat2.objs)) = obj1;
+    obj1 = reshape(obj1, size(mat2.objs));
+    mat1 = matrix(obj1);
+    mat1.name = varNames{1};
+    mat1.hist = h1;
+  end
+  if numel(mat2.objs) == 1 && numel(mat2.objs) ~= numel(mat1.objs)
+    h2 = mat2.hist;
+    obj2 = mat2.objs;
+    obj2(1:numel(mat1.objs)) = obj2;
+    obj2 = reshape(obj2, size(mat1.objs));
+    mat2 = matrix(obj2);
+    mat2.name = varNames{2};
+    mat2.hist = h2;
+  end
+  
+  if ~all(size(mat1.objs) == size(mat2.objs))
+    error('### The Input objects must have the same size. Size of mat1 [%d %d], mat2 [%d %d]', size(mat1.objs,1),  size(mat1.objs,2), size(mat2.objs,1), size(mat2.objs,2));
+  end
+  
+  % switch between operations
+  switch lower(op)
+    case 'plus'
+      % plus operation
+      for kk = 1:numel(mat1.objs)
+        mat.objs(kk) = mat1.objs(kk) + mat2.objs(kk);
+      end
+    case 'minus'
+      % minus operation
+      for kk = 1:numel(mat1.objs)
+        mat.objs(kk) = mat1.objs(kk) - mat2.objs(kk);
+      end
+    case 'times'
+      % times operation
+      for kk = 1:numel(mat1.objs)
+        mat.objs(kk) = mat1.objs(kk) .* mat2.objs(kk);
+      end
+    case 'rdivide'
+      % rdivide operation
+      for kk = 1:numel(mat1.objs)
+        mat.objs(kk) = mat1.objs(kk) ./ mat2.objs(kk);
+      end
+  end
+  
+  if ~callerIsMethod
+    mat.name = [varNames{1} opsym varNames{2}];
+    mat.addHistory(infoObj, pl, varNames, [mat1.hist mat2.hist]);  
+  end
+  
+  varargout{1} = mat;
+  
+end
+