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