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