comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % UNIT a helper class for implementing units in LTPDA.
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % UNIT a helper class for implementing units in LTPDA.
5 %
6 % SUPERCLASSES: ltpda_nuo < ltpda_obj
7 %
8 % CONSTRUCTORS:
9 %
10 % u = unit(str);
11 %
12 % EXAMPLES:
13 %
14 % u = unit('m'); - Create a simple unit
15 % u = unit('m^3'); - With an exponent
16 % u = unit('m^1/2');
17 % u = unit('m^1.5');
18 % u = unit('pm^2'); - With a prefix
19 % u = unit('m s^-2 kg'); - Multiple units
20 % u = unit('m/s'); - Units with division
21 % u = unit('m^.5 / s^2');
22 %
23 % SUPPORTED PREFIXES: unit.supportedPrefixes
24 % SUPPORTED UNITS: unit.supportedUnits
25 %
26 % VERSION: $Id: unit.m,v 1.54 2011/08/16 04:52:19 hewitson Exp $
27 %
28 % SEE ALSO: ltpda_obj, ltpda_nuo
29 %
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%classdef unit
31
32 classdef (Hidden = true) unit < ltpda_nuo
33
34 %----------------------------------------
35 %- Private properties
36 %----------------------------------------
37 properties (SetAccess = protected)
38 strs = {}; % unit sign
39 exps = []; % exponent of the units
40 vals = []; % prefixes of the units (all SI prefixes are supported)
41 end
42
43 %----------------------------------------
44 %- Public methods
45 %----------------------------------------
46 methods
47
48 %----------------------------------------
49 %- Constructor
50 %----------------------------------------
51 function u = unit(varargin)
52
53 switch nargin
54 case 0
55 % Empty constructor
56 case 1
57 if ischar(varargin{1})
58 % String input
59 ustr = strtrim(varargin{1});
60 if ~isempty(ustr)
61
62 % Handle the output of char(unit)
63 ustr = strtrim(strrep(strrep(ustr, '[', ' '), ']', ' '));
64
65 % split on whitespace
66 expr_unit = '([1a-zA-Z]+)';
67 expr_frac = '([+-]?[0-9]*(\.[0-9]+)?(/-?[0-9]+)?)';
68 expr = [' *' expr_unit '(\^(\(' expr_frac '\)|' expr_frac '))* *'];
69 %expr = ' *([1a-zA-Z]+)(\^(\((-?[0-9]+(\/-?[0-9]+)?)\)|(-?[0-9]+(\/-?[0-9]+)?)))* *';
70 tks = strtrim(regexp(ustr, expr, 'match'));
71 ops = strtrim(regexp(ustr, expr, 'split'));
72
73 % combine each unit
74 for j=1:numel(tks)
75 % Parse string
76 if tks{j} == '1' % Special case for '1/s'
77 u2.strs = '';
78 u2.exps = [];
79 u2.vals = [];
80 else
81 [us, exp, val] = unit.parse(tks{j});
82 u2.strs = {us};
83 u2.exps = exp;
84 u2.vals = val;
85 end
86
87 switch ops{j}
88 case ''
89 u.strs = [u.strs u2.strs];
90 u.exps = [u.exps u2.exps];
91 u.vals = [u.vals u2.vals];
92 case '+'
93 u2 = unit(u2);
94 u = u + u2;
95 case '-'
96 u2 = unit(u2);
97 u = u - u2;
98 case {'*', '.*'}
99 u2 = unit(u2);
100 u = u * u2;
101 case {'/', './'}
102 u2 = unit(u2);
103 u = u / u2;
104 otherwise
105 error('### Unknown operator [%s]', ops{j});
106 end
107 end
108 end
109
110 elseif isstruct(varargin{1})
111 u = fromStruct(u, varargin{1});
112
113 elseif isa(varargin{1}, 'double')
114
115 if isempty(varargin{1})
116 else
117 s = unit.supportedUnits;
118 if numel(varargin{1}) == numel(s)
119 positions = not(varargin{1}==0);
120 u.strs = s(positions);
121 u.exps = varargin{1}(positions);
122 u.vals = ones(1, sum(positions));
123 else
124 error('variable unit.supportedUnits does not match');
125 end
126 end
127
128 elseif isa(varargin{1}, 'unit')
129 u = varargin{1};
130
131 elseif iscell(varargin{1})
132
133 for kk=1:numel(varargin{1})
134 u(kk) = unit(varargin{1}{kk});
135 end
136
137 else
138 error('### Unknown single argument constructor. The constructor doesn''t support the class [%s]', class(varargin{1}));
139 end
140
141 case 2
142 if isa(varargin{1}, 'org.apache.xerces.dom.DeferredElementImpl') && ...
143 isa(varargin{2}, 'history')
144 u = fromDom(u, varargin{1}, varargin{2});
145
146 elseif (isa(varargin{1}, 'unit') || ischar(varargin{1})) && ...
147 (isa(varargin{2}, 'unit') || ischar(varargin{2}))
148 u = varargin{1};
149 u = [u unit(varargin{2})];
150
151 else
152 error('### Unknown constructor method for two inputs.');
153 end
154
155 otherwise
156 u = varargin{1};
157 for i=2:numel(varargin)
158 u = [u unit(varargin{i})];
159 end
160 end
161
162 end % End constructor
163
164 end % End public methods
165
166 %----------------------------------------
167 %- Private Static methods
168 %----------------------------------------
169 methods (Static=true, Access=private)
170
171 %----------------------------------------
172 %- Parse a unit definition string
173 %----------------------------------------
174 function [us, exp, val] = parse(ustr)
175
176 % get exp
177 [s,t] = strtok(ustr, '^');
178 if ~isempty(t)
179 % drop any ()
180 t = strrep(t(2:end),'(','');
181 t = strrep(t,')','');
182 exp = eval(t);
183 else
184 exp = 1;
185 end
186
187 if length(s) > 1 && utils.helper.ismember(s(1), unit.supportedPrefixes) && utils.helper.ismember(s(2:end), unit.supportedUnits)
188 % check for prefix
189 sp = s(1);
190 val = unit.prefix2val(sp);
191 sm = s(2:end);
192 elseif length(s) > 2 && utils.helper.ismember(s(1:2), unit.supportedPrefixes) && utils.helper.ismember(s(3:end), unit.supportedUnits)
193 % special case for the prefix 'da'
194 sp = s(1:2);
195 val = unit.prefix2val(sp);
196 sm = s(3:end);
197 else
198 val = 1;
199 sp = '';
200 sm = s;
201 end
202
203 % Check unit
204 if ~utils.helper.ismember(sm, unit.supportedUnits)
205 error(['### Unsupported unit: [' sm ']']);
206 end
207
208 % set unit string
209 us = [sm];
210
211 end % End parse
212
213
214
215 %----------------------------------------
216 %- Get the value associated with a prefix
217 %----------------------------------------
218 function val = prefix2val(p)
219 [pfxs, pfxvals] = unit.supportedPrefixes;
220 val = pfxvals(strcmp(p, pfxs));
221 end
222
223 %----------------------------------------
224 %- Get the prefix associated with a value
225 %----------------------------------------
226 function p = val2prefix(val)
227 [pfxs, pfxvals] = unit.supportedPrefixes;
228 res = val==pfxvals;
229 if any(res)
230 p = pfxs{val==pfxvals};
231 else
232 p = '';
233 end
234 end
235 end % End static private methods
236
237 %----------------------------------------
238 %- Public static methods
239 %----------------------------------------
240 methods (Static=true)
241
242 function out = VEROUT()
243 out = '$Id: unit.m,v 1.54 2011/08/16 04:52:19 hewitson Exp $';
244 end
245
246 function ii = getInfo(varargin)
247 ii = utils.helper.generic_getInfo(varargin{:}, 'unit');
248 end
249
250 function out = SETS()
251 out = {'Default'};
252 end
253
254 function out = getDefaultPlist(set)
255 switch lower(set)
256 case 'default'
257 out = plist();
258 otherwise
259 error('### Unknown set [%s]', set);
260 end
261 end
262
263 function obj = initObjectWithSize(n,m)
264 obj = unit.newarray([n m]);
265 end
266
267 %----------------------------------------
268 %- Return a list of supported prefixes
269 %----------------------------------------
270 function varargout = supportedPrefixes
271 pfxs = {...
272 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm', 'c', 'd', '', ...
273 'da', 'h', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
274 pfxvals = [...
275 1e-24 1e-21 1e-18 1e-15 1e-12 1e-9 1e-6 1e-3 1e-2 1e-1 1 ...
276 10 100 1000 1e6 1e9 1e12 1e15 1e18 1e21 1e24];
277
278 if nargout == 1
279 varargout{1} = pfxs;
280 elseif nargout == 2
281 varargout{1} = pfxs;
282 varargout{2} = pfxvals;
283 else
284 for kk=1:numel(pfxs)
285 fprintf('%-3s[%g]\n', pfxs{kk}, pfxvals(kk));
286 end
287 end
288
289 end
290
291 %----------------------------------------
292 %- Return a list of supported units
293 %----------------------------------------
294 function bu = supportedUnits
295 ltpdaUnits = {'', 'm', 'kg', 's', 'A', 'K', 'mol', 'cd', ...
296 'rad', 'deg', 'sr', 'Hz', 'N', 'Pa', 'J', 'W', 'C', 'V', 'F', ...
297 'Ohm', 'S', 'Wb', 'T', 'H', 'degC', ...
298 'Count', 'arb', 'Index'};
299
300 prefs = getappdata(0, 'LTPDApreferences');
301 userUnits = prefs.getMiscPrefs.getUnits;
302 bu = [ltpdaUnits cell(1, userUnits.size)];
303 for kk=0:userUnits.size-1
304 bu{numel(ltpdaUnits) + kk + 1} = char(userUnits.get(kk));
305 end
306
307 end
308
309 end
310
311 %----------------------------------------
312 %- Static hidden methods
313 %----------------------------------------
314
315 methods (Static = true, Hidden = true)
316 varargout = loadobj(varargin)
317 varargout = update_struct(varargin)
318 end
319
320 %----------------------------------------
321 %- Private methods
322 %----------------------------------------
323
324 methods (Access = private)
325 end
326
327 %----------------------------------------
328 %- Protected methods
329 %----------------------------------------
330
331 methods (Access = protected)
332 varargout = fromStruct(varargin)
333 varargout = fromDom(varargin)
334 end
335
336 methods (Hidden = true)
337 varargout = attachToDom(varargin)
338 end
339 end