Mercurial > hg > ltpda
comparison m-toolbox/classes/@unit/simplify.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 % SIMPLIFY the units. | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % | |
4 % DESCRIPTION: SIMPLIFY the units. | |
5 % | |
6 % CALL: a = a.simplify | |
7 % | |
8 % VERSION: $Id: simplify.m,v 1.10 2011/02/18 16:48:55 ingo Exp $ | |
9 % | |
10 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
11 | |
12 function v = simplify(v, exceptions) | |
13 | |
14 v = copy(v, nargout); | |
15 | |
16 if nargin == 1 | |
17 exceptions = {}; | |
18 elseif nargin == 2 | |
19 if ischar(exceptions) | |
20 exceptions = cellstr(exceptions); | |
21 end | |
22 end | |
23 | |
24 udef = struct('vals', [], 'exps', []); | |
25 ustruct = struct(); | |
26 ex = struct('strs', {{}}, 'vals', [], 'exps', []); | |
27 remain_val = 1; | |
28 | |
29 % Create a structure with the different units as the fields | |
30 % For example: 'mm um ks^2 s' | |
31 % | |
32 % ustruct.m: vals = [1e-3 1e-6] | |
33 % exps = [1 1] | |
34 % ustruct.s: vals = [1e3 1] | |
35 % exps = [2 1] | |
36 % | |
37 % 1.) Initialize structure with empty 'vals' and 'exps' fields | |
38 % 2.) Fill 'vals' and 'exps' fields | |
39 for ii = unique(v.strs) | |
40 if ~utils.helper.ismember(ii, exceptions) | |
41 ustruct.(cell2mat(ii)) = udef; | |
42 end | |
43 end | |
44 for ii = 1:numel(v.strs) | |
45 if ~(utils.helper.ismember(v.strs{ii}, exceptions) || utils.helper.ismember(sprintf('%s%s', unit.val2prefix(v.vals(ii)), v.strs{ii}), exceptions)) | |
46 ustruct.(v.strs{ii}).vals = [ustruct.(v.strs{ii}).vals v.vals(ii)]; | |
47 ustruct.(v.strs{ii}).exps = [ustruct.(v.strs{ii}).exps v.exps(ii)]; | |
48 else | |
49 % Collext all units which are in the exception list | |
50 ex.strs = [ex.strs v.strs(ii)]; | |
51 ex.vals = [ex.vals v.vals(ii)]; | |
52 ex.exps = [ex.exps v.exps(ii)]; | |
53 end | |
54 end | |
55 | |
56 % Simplify all supported units | |
57 fields = fieldnames(ustruct); | |
58 for ii = 1:numel(fields) | |
59 field = fields{ii}; | |
60 | |
61 exp = sum(ustruct.(field).exps); | |
62 if exp == 0 | |
63 % The unit is canced. Keep prefix | |
64 remain_val = remain_val * power(10,sum(log10(ustruct.(field).vals) .* ustruct.(field).exps)); | |
65 ustruct = rmfield(ustruct, field); | |
66 continue | |
67 end | |
68 | |
69 [N,D] = rat(sum( log10(ustruct.(field).vals) .* ustruct.(field).exps ./ exp)); | |
70 | |
71 if D ~= 1 || ~any(N==[-24:3:-3 -2:1:2 3:3:24]) | |
72 % The value is not a supported prefix -> Don't simplify | |
73 continue | |
74 end | |
75 | |
76 % Simplify the units | |
77 ustruct.(field).vals = eval(['1e' num2str(N)]); | |
78 ustruct.(field).exps = exp; | |
79 end | |
80 | |
81 % Prepare output unit-object | |
82 % All information of the output object is in 'ustruct' | |
83 v.strs = {}; | |
84 v.vals = []; | |
85 v.exps = []; | |
86 fields = fieldnames(ustruct); | |
87 for ii = 1:numel(fields) | |
88 field = fields{ii}; | |
89 strs = {}; | |
90 strs(1:numel(ustruct.(field).vals)) = {field}; | |
91 v.strs = [v.strs strs]; | |
92 v.vals = [v.vals ustruct.(field).vals]; | |
93 v.exps = [v.exps ustruct.(field).exps]; | |
94 end | |
95 | |
96 if remain_val ~= 1 && numel(v.vals) >= 1 | |
97 % It might be that the units are canceled out but not the prefixes | |
98 % For example: 'mm m^-1 Hz' | |
99 % Add in this case the prefix to the remaining unit | |
100 % Result: 'mHz' | |
101 [N,D] = rat((log10(v.vals) .* v.exps + log10(remain_val) ) ./ v.exps); | |
102 idx = find(D==1); | |
103 | |
104 found = false; | |
105 for ii = 1:numel(idx) | |
106 valexp = N(idx(ii)); | |
107 if ~any(valexp==[-24:3:-3 -2:1:2 3:3:24]) | |
108 % It is not possibple to add the remaining prefix to one of the other | |
109 % units without having an not suported prefix | |
110 continue | |
111 else | |
112 found = true; | |
113 break | |
114 end | |
115 end | |
116 | |
117 if ~found | |
118 % If it is not possible to add the remaining prefix to an other unit | |
119 % then retrun the input unit | |
120 v = copy(v, 1); | |
121 return | |
122 else | |
123 idx = idx(ii); | |
124 end | |
125 | |
126 v.vals(idx) = eval(['1e' num2str(N(idx))]); | |
127 | |
128 % It might be that it is possible to simplify the units again | |
129 v.simplify(exceptions); | |
130 | |
131 elseif remain_val ~= 1 && isempty(v.vals) | |
132 % It might be that the units are canceled out but not the prefixes | |
133 % For example: 'mm m^-1' | |
134 % But it is possible that there is no unit left. Return in this case | |
135 % the input object. | |
136 % Result: 'mm m^-1' | |
137 v = copy(v, 1); | |
138 return | |
139 end | |
140 | |
141 % Add units which are in the exception list | |
142 v.strs = [v.strs ex.strs]; | |
143 v.vals = [v.vals ex.vals]; | |
144 v.exps = [v.exps ex.exps]; | |
145 | |
146 end |