Mercurial > hg > ltpda
view 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 source
% 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