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