Mercurial > hg > ltpda
diff m-toolbox/classes/@unit/unit.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/@unit/unit.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,339 @@ +% UNIT a helper class for implementing units in LTPDA. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% UNIT a helper class for implementing units in LTPDA. +% +% SUPERCLASSES: ltpda_nuo < ltpda_obj +% +% CONSTRUCTORS: +% +% u = unit(str); +% +% EXAMPLES: +% +% u = unit('m'); - Create a simple unit +% u = unit('m^3'); - With an exponent +% u = unit('m^1/2'); +% u = unit('m^1.5'); +% u = unit('pm^2'); - With a prefix +% u = unit('m s^-2 kg'); - Multiple units +% u = unit('m/s'); - Units with division +% u = unit('m^.5 / s^2'); +% +% SUPPORTED PREFIXES: unit.supportedPrefixes +% SUPPORTED UNITS: unit.supportedUnits +% +% VERSION: $Id: unit.m,v 1.54 2011/08/16 04:52:19 hewitson Exp $ +% +% SEE ALSO: ltpda_obj, ltpda_nuo +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%classdef unit + +classdef (Hidden = true) unit < ltpda_nuo + + %---------------------------------------- + %- Private properties + %---------------------------------------- + properties (SetAccess = protected) + strs = {}; % unit sign + exps = []; % exponent of the units + vals = []; % prefixes of the units (all SI prefixes are supported) + end + + %---------------------------------------- + %- Public methods + %---------------------------------------- + methods + + %---------------------------------------- + %- Constructor + %---------------------------------------- + function u = unit(varargin) + + switch nargin + case 0 + % Empty constructor + case 1 + if ischar(varargin{1}) + % String input + ustr = strtrim(varargin{1}); + if ~isempty(ustr) + + % Handle the output of char(unit) + ustr = strtrim(strrep(strrep(ustr, '[', ' '), ']', ' ')); + + % split on whitespace + expr_unit = '([1a-zA-Z]+)'; + expr_frac = '([+-]?[0-9]*(\.[0-9]+)?(/-?[0-9]+)?)'; + expr = [' *' expr_unit '(\^(\(' expr_frac '\)|' expr_frac '))* *']; + %expr = ' *([1a-zA-Z]+)(\^(\((-?[0-9]+(\/-?[0-9]+)?)\)|(-?[0-9]+(\/-?[0-9]+)?)))* *'; + tks = strtrim(regexp(ustr, expr, 'match')); + ops = strtrim(regexp(ustr, expr, 'split')); + + % combine each unit + for j=1:numel(tks) + % Parse string + if tks{j} == '1' % Special case for '1/s' + u2.strs = ''; + u2.exps = []; + u2.vals = []; + else + [us, exp, val] = unit.parse(tks{j}); + u2.strs = {us}; + u2.exps = exp; + u2.vals = val; + end + + switch ops{j} + case '' + u.strs = [u.strs u2.strs]; + u.exps = [u.exps u2.exps]; + u.vals = [u.vals u2.vals]; + case '+' + u2 = unit(u2); + u = u + u2; + case '-' + u2 = unit(u2); + u = u - u2; + case {'*', '.*'} + u2 = unit(u2); + u = u * u2; + case {'/', './'} + u2 = unit(u2); + u = u / u2; + otherwise + error('### Unknown operator [%s]', ops{j}); + end + end + end + + elseif isstruct(varargin{1}) + u = fromStruct(u, varargin{1}); + + elseif isa(varargin{1}, 'double') + + if isempty(varargin{1}) + else + s = unit.supportedUnits; + if numel(varargin{1}) == numel(s) + positions = not(varargin{1}==0); + u.strs = s(positions); + u.exps = varargin{1}(positions); + u.vals = ones(1, sum(positions)); + else + error('variable unit.supportedUnits does not match'); + end + end + + elseif isa(varargin{1}, 'unit') + u = varargin{1}; + + elseif iscell(varargin{1}) + + for kk=1:numel(varargin{1}) + u(kk) = unit(varargin{1}{kk}); + end + + else + error('### Unknown single argument constructor. The constructor doesn''t support the class [%s]', class(varargin{1})); + end + + case 2 + if isa(varargin{1}, 'org.apache.xerces.dom.DeferredElementImpl') && ... + isa(varargin{2}, 'history') + u = fromDom(u, varargin{1}, varargin{2}); + + elseif (isa(varargin{1}, 'unit') || ischar(varargin{1})) && ... + (isa(varargin{2}, 'unit') || ischar(varargin{2})) + u = varargin{1}; + u = [u unit(varargin{2})]; + + else + error('### Unknown constructor method for two inputs.'); + end + + otherwise + u = varargin{1}; + for i=2:numel(varargin) + u = [u unit(varargin{i})]; + end + end + + end % End constructor + + end % End public methods + + %---------------------------------------- + %- Private Static methods + %---------------------------------------- + methods (Static=true, Access=private) + + %---------------------------------------- + %- Parse a unit definition string + %---------------------------------------- + function [us, exp, val] = parse(ustr) + + % get exp + [s,t] = strtok(ustr, '^'); + if ~isempty(t) + % drop any () + t = strrep(t(2:end),'(',''); + t = strrep(t,')',''); + exp = eval(t); + else + exp = 1; + end + + if length(s) > 1 && utils.helper.ismember(s(1), unit.supportedPrefixes) && utils.helper.ismember(s(2:end), unit.supportedUnits) + % check for prefix + sp = s(1); + val = unit.prefix2val(sp); + sm = s(2:end); + elseif length(s) > 2 && utils.helper.ismember(s(1:2), unit.supportedPrefixes) && utils.helper.ismember(s(3:end), unit.supportedUnits) + % special case for the prefix 'da' + sp = s(1:2); + val = unit.prefix2val(sp); + sm = s(3:end); + else + val = 1; + sp = ''; + sm = s; + end + + % Check unit + if ~utils.helper.ismember(sm, unit.supportedUnits) + error(['### Unsupported unit: [' sm ']']); + end + + % set unit string + us = [sm]; + + end % End parse + + + + %---------------------------------------- + %- Get the value associated with a prefix + %---------------------------------------- + function val = prefix2val(p) + [pfxs, pfxvals] = unit.supportedPrefixes; + val = pfxvals(strcmp(p, pfxs)); + end + + %---------------------------------------- + %- Get the prefix associated with a value + %---------------------------------------- + function p = val2prefix(val) + [pfxs, pfxvals] = unit.supportedPrefixes; + res = val==pfxvals; + if any(res) + p = pfxs{val==pfxvals}; + else + p = ''; + end + end + end % End static private methods + + %---------------------------------------- + %- Public static methods + %---------------------------------------- + methods (Static=true) + + function out = VEROUT() + out = '$Id: unit.m,v 1.54 2011/08/16 04:52:19 hewitson Exp $'; + end + + function ii = getInfo(varargin) + ii = utils.helper.generic_getInfo(varargin{:}, 'unit'); + end + + function out = SETS() + out = {'Default'}; + end + + function out = getDefaultPlist(set) + switch lower(set) + case 'default' + out = plist(); + otherwise + error('### Unknown set [%s]', set); + end + end + + function obj = initObjectWithSize(n,m) + obj = unit.newarray([n m]); + end + + %---------------------------------------- + %- Return a list of supported prefixes + %---------------------------------------- + function varargout = supportedPrefixes + pfxs = {... + 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd', '', ... + 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'}; + pfxvals = [... + 1e-24 1e-21 1e-18 1e-15 1e-12 1e-9 1e-6 1e-3 1e-2 1e-1 1 ... + 10 100 1000 1e6 1e9 1e12 1e15 1e18 1e21 1e24]; + + if nargout == 1 + varargout{1} = pfxs; + elseif nargout == 2 + varargout{1} = pfxs; + varargout{2} = pfxvals; + else + for kk=1:numel(pfxs) + fprintf('%-3s[%g]\n', pfxs{kk}, pfxvals(kk)); + end + end + + end + + %---------------------------------------- + %- Return a list of supported units + %---------------------------------------- + function bu = supportedUnits + ltpdaUnits = {'', 'm', 'kg', 's', 'A', 'K', 'mol', 'cd', ... + 'rad', 'deg', 'sr', 'Hz', 'N', 'Pa', 'J', 'W', 'C', 'V', 'F', ... + 'Ohm', 'S', 'Wb', 'T', 'H', 'degC', ... + 'Count', 'arb', 'Index'}; + + prefs = getappdata(0, 'LTPDApreferences'); + userUnits = prefs.getMiscPrefs.getUnits; + bu = [ltpdaUnits cell(1, userUnits.size)]; + for kk=0:userUnits.size-1 + bu{numel(ltpdaUnits) + kk + 1} = char(userUnits.get(kk)); + end + + end + + end + + %---------------------------------------- + %- Static hidden methods + %---------------------------------------- + + methods (Static = true, Hidden = true) + varargout = loadobj(varargin) + varargout = update_struct(varargin) + end + + %---------------------------------------- + %- Private methods + %---------------------------------------- + + methods (Access = private) + end + + %---------------------------------------- + %- Protected methods + %---------------------------------------- + + methods (Access = protected) + varargout = fromStruct(varargin) + varargout = fromDom(varargin) + end + + methods (Hidden = true) + varargout = attachToDom(varargin) + end +end