1 //=========================================================
2 // MusE
3 // Linux Music Editor
4 // $Id: ./muse/widgets/mmath.cpp $
5 //
6 // Copyright (C) 1999-2011 by Werner Schweer and others
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License
10 // as published by the Free Software Foundation; version 2 of
11 // the License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 //
22 //=========================================================
23 #include "muse_math.h"
24 #include "mmath.h"
25
26 // QwtMath - a set of mathematical routines
27 //
28 // qwtGetMin -- Find the smallest value in an array
29 // qwtGetMax -- Find the largest value in an array
30 // qwtTwistArray -- invert the order of an array
31 // qwtFloor125 -- Find the largest value fitting in a 1-2-5 pattern
32 // qwtCeil125 -- Find the smallest value fitting in a 1-2-5 pattern
33 // qwtChkMono -- Check for monotony
34 // qwtLinSpace -- construct an array of equally spaced values
35 // qwtLogSpace -- construct an array of logarithmically equally spaced values
36 // qwtMax -- Return the largest of two values
37 // qwtMin -- Return the smallest of two values
38 // qwtAbs -- return the absolute value
39 // qwtSign -- Return the sign of a number
40 // qwtSqr -- Return the square of a number
41 // qwtCopyArray -- Copy an array into another
42 // qwtShiftArray -- Shift an array
43 // qwtSwap -- Swap two values
44 // qwtSort (1) -- Sort two values
45 // qwtSort (2) -- Sort two values
46 // qwtInt -- Return nearest integer
47 // qwtLim -- Limit a values
48
49 namespace MusECore {
50
51 //------------------------------------------------------------
52 //.F qwtGetMin
53 // Find the smallest value in an array
54 //
55 //.u Syntax
56 //.f double qwtGetMin(double *array, int size)
57 //
58 //.u Parameters
59 //.p double *array, int size
60 //
61 //------------------------------------------------------------
62
qwtGetMin(double * array,int size)63 double qwtGetMin(double *array, int size)
64 {
65 double rv;
66 int i;
67
68 if (size > 0)
69 {
70 rv = array[0];
71 for (i=1; i< size; i++)
72 rv = qwtMin(rv, array[i]);
73 return rv;
74 }
75 else
76 return 0.0;
77
78 }
79
80
81 //------------------------------------------------------------
82 //
83 //.F qwtGetMax
84 // Find the largest value in an array
85 //
86 //.u Syntax
87 //.f double qwtGetMax(double *array, int size)
88 //
89 //.u Parameters
90 //.p double *array, int size
91 //
92 //------------------------------------------------------------
qwtGetMax(double * array,int size)93 double qwtGetMax(double *array, int size)
94 {
95 double rv;
96 int i;
97
98 if (size > 0)
99 {
100 rv = array[0];
101 for (i=1; i< size; i++)
102 rv = qwtMax(rv, array[i]);
103 return rv;
104 }
105 else
106 return 0.0;
107
108 }
109
110
111 //------------------------------------------------------------
112 //
113 //.F qwtCeil125
114 // Find the smallest value out of {1,2,5}*10^n with an integer number n
115 // which is greater than or equal to x
116 //
117 //.u Syntax
118 //.f double qwtCeil125(double x)
119 //
120 //.u Parameters
121 //.p double x
122 //
123 //------------------------------------------------------------
qwtCeil125(double x)124 double qwtCeil125( double x)
125 {
126 double lx, rv;
127 double p10, fr;
128 double sign = ( x > 0) ? 1.0 : -1.0;
129
130 if (x == 0.0) return 0.0;
131
132 lx = log10(fabs(x));
133 p10 = floor(lx);
134 fr = exp10(lx - p10);
135 if (fr <=1.0)
136 fr = 1.0;
137 else if (fr <= 2.0)
138 fr = 2.0;
139 else if (fr <= 5.0)
140 fr = 5.0;
141 else
142 fr = 10.0;
143 rv = fr * exp10(p10);
144 return sign * rv;
145 }
146
147
148 //------------------------------------------------------------
149 //
150 //.F qwtFloor125
151 // Find the largest value out of {1,2,5}*10^n with an integer number n
152 // which is smaller than or equal to x
153 //
154 //.u Syntax
155 //.f double qwtFloor125(double x)
156 //
157 //.u Parameters
158 //.p double x
159 //
160 //------------------------------------------------------------
qwtFloor125(double x)161 double qwtFloor125( double x)
162 {
163 double lx, rv;
164 double p10, fr;
165 double sign = ( x > 0) ? 1.0 : -1.0;
166
167 if (x == 0.0) return 0.0;
168
169 lx = log10(fabs(x));
170 p10 = floor(lx);
171 fr = exp10(lx - p10);
172 if (fr >= 10.0)
173 fr = 10.0;
174 else if (fr >= 5.0)
175 fr = 5.0;
176 else if (fr >= 2.0)
177 fr = 2.0;
178 else
179 fr = 1.0;
180 rv = fr * exp10(p10);
181 return sign * rv;
182 }
183
184
185 //------------------------------------------------------------
186 //
187 //.F qwtChkMono
188 // Checks if an array is a strictly monotonic sequence
189 //
190 //.u Syntax
191 //.f int qwtChkMono(double *array, int size)
192 //
193 //.u Parameters
194 //.p double *array -- pointer to a double array
195 // int size -- size of the array
196 //
197 //.u Return Value
198 //.t 0 -- sequence is not strictly monotonic
199 // 1 -- sequence is strictly monotonically increasing
200 // -1 -- sequence is strictly monotonically decreasing
201 //
202 //------------------------------------------------------------
qwtChkMono(double * array,int size)203 int qwtChkMono(double *array, int size)
204 {
205 int rv, i;
206
207 if (size < 2) return 0;
208
209 rv = qwtSign(array[1] - array[0]);
210 for (i=1;i<size-1;i++)
211 {
212 if ( qwtSign(array[i+1] - array[i]) != rv )
213 {
214 rv = 0;
215 break;
216 }
217 }
218 return rv;
219
220 }
221
222 //------------------------------------------------------------
223 //
224 //.F qwtTwistArray
225 // Invert the order of array elements
226 //
227 //.u Syntax
228 //.f void qwtTwistArray(double *array, int size)
229 //
230 //.u Parameters
231 //.p double *array, int size
232 //
233 //------------------------------------------------------------
qwtTwistArray(double * array,int size)234 void qwtTwistArray(double *array, int size)
235 {
236 int itmp;
237 int i, s2;
238 double dtmp;
239
240 s2 = size / 2;
241
242 for (i=0; i < s2; i++)
243 {
244 itmp = size - 1 - i;
245 dtmp = array[i];
246 array[i] = array[itmp];
247 array[itmp] = dtmp;
248 }
249
250 }
251
252
253 //------------------------------------------------------------
254 //
255 //.F qwtLinSpace
256 // Create an array of equally spaced values
257 //
258 //.u Syntax
259 //.f void qwtLinSpace(double *array, int size, double xmin, double xmax)
260 //
261 //.u Parameters
262 //.p double *array -- where to put the values
263 // int size -- size of the array
264 // double xmin -- value associated with index 0
265 // double xmax -- value associated with index (size-1)
266 //
267 //------------------------------------------------------------
qwtLinSpace(double * array,int size,double xmin,double xmax)268 void qwtLinSpace(double *array, int size, double xmin, double xmax)
269 {
270 int i, imax;
271 imax = size -1;
272 double step;
273
274 if (size > 0)
275 {
276 array[0] = xmin;
277 array[imax] = xmax;
278 step = (xmax - xmin) / double(imax);
279
280 for (i=1;i<imax;i++)
281 array[i] = xmin + double(i) * step;
282 }
283
284 }
285
286
287 //------------------------------------------------------------
288 //
289 //.F qwtLogSpace
290 // Create an array of logarithmically equally spaced values
291 //
292 //.u Syntax
293 //.f void qwtLogSpace(double *array, int size, double xmin, double xmax)
294 //
295 //.u Parameters
296 //.p double *array -- where to put the values
297 // int size -- size of the array
298 // double xmin -- value associated with index 0
299 // double xmax -- value associated with index (size-1)
300 //------------------------------------------------------------
qwtLogSpace(double * array,int size,double xmin,double xmax)301 void qwtLogSpace(double *array, int size, double xmin, double xmax)
302 {
303 int i, imax;
304
305 double lxmin,lxmax;
306 double lstep;
307
308 imax = size -1;
309
310 if ((xmin <= 0.0) || (xmax <= 0.0) || (size <= 0))
311 return;
312
313 array[0] = xmin;
314 array[imax] = xmax;
315 lxmin = log(xmin);
316 lxmax = log(xmax);
317
318 lstep = (lxmax - lxmin) / double(imax);
319
320 for (i=1; i<imax;i++)
321 array[i] = exp(lxmin + double(i) * lstep);
322
323 }
324
325 } // namespace MusECore
326