Mercurial > hg > ltpda
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 +