diff m-toolbox/classes/@smodel/mtimes.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/@smodel/mtimes.m	Wed Nov 23 19:22:13 2011 +0100
@@ -0,0 +1,167 @@
+% MTIMES implements mtimes operator for smodel objects.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DESCRIPTION: MTIMES implements mtimes operator for smodel objects.
+%
+% CALL:        obj = obj1 * obj2
+%              obj = mtimes(obj1,obj2);
+%
+% <a href="matlab:utils.helper.displayMethodInfo('smodel', 'mtimes')">Parameters Description</a>
+%
+% VERSION:     $Id: mtimes.m,v 1.7 2011/05/10 21:00:15 mauro Exp $
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function mdl = mtimes(varargin)
+  
+  callerIsMethod = utils.helper.callerIsMethod;
+  
+  % Check if this is a call for parameters
+  if utils.helper.isinfocall(varargin{:})
+    mdl = getInfo(varargin{3});
+    return
+  end
+  
+  if nargout == 0
+    error('### Matrix multiplication operator can not be used as a modifier.');
+  end
+  
+  mdl1 = varargin{1};
+  mdl2 = varargin{2};
+  
+  % Convert numbers into a smodel object
+  if isnumeric(mdl1)
+    mdl1 = smodel(mdl1);
+  end
+  if isnumeric(mdl2)
+    mdl2 = smodel(mdl2);
+  end
+  
+  %----------------- Gather the input objects names and history
+  in_names = cell(size(varargin));
+  for ii = 1:nargin,in_names{ii} = inputname(ii);end
+  
+  % Convert cdata aos into a smodel object
+  if isa(mdl2, 'ao')
+    if isa(mdl2.data, 'cdata') && numel(mdl2.data.y) == 1
+      mdl2 = smodel(mdl2.y);
+    else
+      error('### It is not possible to multiply the two objects!');
+    end
+  end
+  
+  [rw1,cl1] = size(mdl1);
+  [rw2,cl2] = size(mdl2);
+  
+  % Check input model dimensions
+  if ((rw1 == 1) && (rw2 == 1) && (cl1 == 1) && (cl2 == 1))
+    ids = '1D';
+  else
+    if (cl1 ~= rw2)
+      error('!!! Matrices inner dimensions must agree')
+    else
+      ids = 'ND';
+    end
+  end
+  
+  switch ids
+    case '1D'
+      
+      mdl = copy(mdl1, true);
+      mdl.expr = msym(['(' mdl.expr.s ')*(' mdl2.expr.s ')']);
+      mdl.name = ['(' mdl.name ')*(' mdl2.name ')'];
+
+      smodel.mergeFields(mdl1, mdl2, mdl, 'params', 'values');
+      smodel.mergeFields(mdl1, mdl2, mdl, 'aliasNames', 'aliasValues');
+      smodel.mergeFields(mdl1, mdl2, mdl, 'xvar', 'xvals');
+      smodel.mergeFields(mdl1, mdl2, mdl, 'xvar', 'xunits');
+      smodel.mergeFields(mdl1, mdl2, mdl, 'xvar', 'trans');
+      
+      if ~callerIsMethod
+        mdl.addHistory(getInfo('None'), [], in_names, [mdl1.hist mdl2.hist]);
+      end
+      
+    case 'ND'
+      % some consistence checks
+      if ~all(strcmp({mdl2(:).xvar}, mdl1(1).xvar))
+        warning('### The models have different X variables. Taking the first');
+      end
+      if ~all(cellfun(@(x)isequal(x, mdl1(1).xvals),{mdl2(:).xvals}))
+        warning('### The models have different X data. Taking the first');
+      end
+      
+      % init output
+      mdl = smodel.newarray([rw1 cl2]);
+      % init expression strins array
+      tmst = cell(rw1,cl2);
+      % do raw by colum product
+      for kk = 1:rw1
+        for jj = 1:cl2
+          tmst{kk,jj} = ['(' mdl1(kk,1).expr.s ').*(' mdl2(1,jj).expr.s ')'];
+          mdl(kk,jj).params = [mdl1(kk,1).params mdl2(1,jj).params];
+          mdl(kk,jj).values = [mdl1(kk,1).values mdl2(1,jj).values];
+          unt = simplify(unit(mdl1(kk,1).yunits).*unit(mdl2(1,jj).yunits));
+          for rr = 2:cl1
+            tmst{kk,jj} = ['(' tmst{kk,jj} ')+(' '(' mdl1(kk,rr).expr.s ').*(' mdl2(rr,jj).expr.s ')' ')'];
+            mdl(kk,jj).params = [mdl(kk,jj).params mdl1(kk,rr).params mdl2(rr,jj).params];
+            mdl(kk,jj).values = [mdl(kk,jj).values mdl1(kk,rr).values mdl2(rr,jj).values];
+            % check on yunits
+            unt2 = simplify(unit(mdl1(kk,rr).yunits).*unit(mdl2(rr,jj).yunits));
+            if ~eq(unt, unt2)
+              error('!!! Units for the elements of %s*%s[%d,%d] must be the same',in_names{1},in_names{2},kk,jj);
+            end
+          end
+          mdl(kk,jj).expr = msym(tmst{kk,jj});
+          mdl(kk,jj).name = ['(' in_names{1} '*' in_names{2} ')[' num2str(kk) ',' num2str(jj) ']'];
+          [mdl(kk,jj).params,i,j] = unique(mdl(kk,jj).params, 'first');
+          mdl(kk,jj).values = mdl(kk,jj).values(i);
+          mdl(kk,jj).xvar = mdl1(kk,1).xvar;
+          mdl(kk,jj).xvals = mdl1(kk,1).xvals;
+          mdl(kk,jj).xunits = mdl1(kk,1).xunits;
+          mdl(kk,jj).yunits = unt;
+        end
+      end
+      
+      if ~callerIsMethod
+        mdl(:).addHistory(getInfo('None'), [], in_names, [mdl1.hist, mdl2.hist]);
+      end
+      
+  end
+  
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                               Local Functions                               %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%--------------------------------------------------------------------------
+% Get Info Object
+%--------------------------------------------------------------------------
+function ii = getInfo(varargin)
+  
+  if nargin == 1 && strcmpi(varargin{1}, 'None')
+    sets = {};
+    pl   = [];
+  else
+    sets = {'Default'};
+    pl   = getDefaultPlist();
+  end
+  % Build info object
+  ii = minfo(mfilename, 'smodel', 'ltpda', utils.const.categories.aop, '$Id: mtimes.m,v 1.7 2011/05/10 21:00:15 mauro Exp $', sets, pl);
+  ii.setArgsmin(2);
+  ii.setModifier(false);
+end
+
+%--------------------------------------------------------------------------
+% Get Default Plist
+%--------------------------------------------------------------------------
+function plout = getDefaultPlist()
+  persistent pl;  
+  if ~exist('pl', 'var') || isempty(pl)
+    pl = buildplist();
+  end
+  plout = pl;  
+end
+
+function pl = buildplist()
+  pl = plist.EMPTY_PLIST;
+end