1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "_cxcore.h"
43
44 CV_IMPL void
cvKMeans2(const CvArr * samples_arr,int cluster_count,CvArr * labels_arr,CvTermCriteria termcrit)45 cvKMeans2( const CvArr* samples_arr, int cluster_count,
46 CvArr* labels_arr, CvTermCriteria termcrit )
47 {
48 CvMat* centers = 0;
49 CvMat* old_centers = 0;
50 CvMat* counters = 0;
51
52 CV_FUNCNAME( "cvKMeans2" );
53
54 __BEGIN__;
55
56 CvMat samples_stub, labels_stub;
57 CvMat* samples = (CvMat*)samples_arr;
58 CvMat* labels = (CvMat*)labels_arr;
59 CvMat* temp = 0;
60 CvRNG rng = CvRNG(-1);
61 int i, j, k, sample_count, dims;
62 int ids_delta, iter;
63 double max_dist;
64
65 if( !CV_IS_MAT( samples ))
66 CV_CALL( samples = cvGetMat( samples, &samples_stub ));
67
68 if( !CV_IS_MAT( labels ))
69 CV_CALL( labels = cvGetMat( labels, &labels_stub ));
70
71 if( cluster_count < 1 )
72 CV_ERROR( CV_StsOutOfRange, "Number of clusters should be positive" );
73
74 if( CV_MAT_DEPTH(samples->type) != CV_32F || CV_MAT_TYPE(labels->type) != CV_32SC1 )
75 CV_ERROR( CV_StsUnsupportedFormat,
76 "samples should be floating-point matrix, cluster_idx - integer vector" );
77
78 if( (labels->rows != 1 && (labels->cols != 1 || !CV_IS_MAT_CONT(labels->type))) ||
79 labels->rows + labels->cols - 1 != samples->rows )
80 CV_ERROR( CV_StsUnmatchedSizes,
81 "cluster_idx should be 1D vector of the same number of elements as samples' number of rows" );
82
83 CV_CALL( termcrit = cvCheckTermCriteria( termcrit, 1e-6, 100 ));
84
85 termcrit.epsilon *= termcrit.epsilon;
86 sample_count = samples->rows;
87
88 if( cluster_count > sample_count )
89 cluster_count = sample_count;
90
91 dims = samples->cols*CV_MAT_CN(samples->type);
92 ids_delta = labels->step ? labels->step/(int)sizeof(int) : 1;
93
94 CV_CALL( centers = cvCreateMat( cluster_count, dims, CV_64FC1 ));
95 CV_CALL( old_centers = cvCreateMat( cluster_count, dims, CV_64FC1 ));
96 CV_CALL( counters = cvCreateMat( 1, cluster_count, CV_32SC1 ));
97
98 // init centers
99 for( i = 0; i < sample_count; i++ )
100 labels->data.i[i] = cvRandInt(&rng) % cluster_count;
101
102 counters->cols = cluster_count; // cut down counters
103 max_dist = termcrit.epsilon*2;
104
105 for( iter = 0; iter < termcrit.max_iter; iter++ )
106 {
107 // computer centers
108 cvZero( centers );
109 cvZero( counters );
110
111 for( i = 0; i < sample_count; i++ )
112 {
113 float* s = (float*)(samples->data.ptr + i*samples->step);
114 k = labels->data.i[i*ids_delta];
115 double* c = (double*)(centers->data.ptr + k*centers->step);
116 for( j = 0; j <= dims - 4; j += 4 )
117 {
118 double t0 = c[j] + s[j];
119 double t1 = c[j+1] + s[j+1];
120
121 c[j] = t0;
122 c[j+1] = t1;
123
124 t0 = c[j+2] + s[j+2];
125 t1 = c[j+3] + s[j+3];
126
127 c[j+2] = t0;
128 c[j+3] = t1;
129 }
130 for( ; j < dims; j++ )
131 c[j] += s[j];
132 counters->data.i[k]++;
133 }
134
135 if( iter > 0 )
136 max_dist = 0;
137
138 for( k = 0; k < cluster_count; k++ )
139 {
140 double* c = (double*)(centers->data.ptr + k*centers->step);
141 if( counters->data.i[k] != 0 )
142 {
143 double scale = 1./counters->data.i[k];
144 for( j = 0; j < dims; j++ )
145 c[j] *= scale;
146 }
147 else
148 {
149 i = cvRandInt( &rng ) % sample_count;
150 float* s = (float*)(samples->data.ptr + i*samples->step);
151 for( j = 0; j < dims; j++ )
152 c[j] = s[j];
153 }
154
155 if( iter > 0 )
156 {
157 double dist = 0;
158 double* c_o = (double*)(old_centers->data.ptr + k*old_centers->step);
159 for( j = 0; j < dims; j++ )
160 {
161 double t = c[j] - c_o[j];
162 dist += t*t;
163 }
164 if( max_dist < dist )
165 max_dist = dist;
166 }
167 }
168
169 // assign labels
170 for( i = 0; i < sample_count; i++ )
171 {
172 float* s = (float*)(samples->data.ptr + i*samples->step);
173 int k_best = 0;
174 double min_dist = DBL_MAX;
175
176 for( k = 0; k < cluster_count; k++ )
177 {
178 double* c = (double*)(centers->data.ptr + k*centers->step);
179 double dist = 0;
180
181 j = 0;
182 for( ; j <= dims - 4; j += 4 )
183 {
184 double t0 = c[j] - s[j];
185 double t1 = c[j+1] - s[j+1];
186 dist += t0*t0 + t1*t1;
187 t0 = c[j+2] - s[j+2];
188 t1 = c[j+3] - s[j+3];
189 dist += t0*t0 + t1*t1;
190 }
191
192 for( ; j < dims; j++ )
193 {
194 double t = c[j] - s[j];
195 dist += t*t;
196 }
197
198 if( min_dist > dist )
199 {
200 min_dist = dist;
201 k_best = k;
202 }
203 }
204
205 labels->data.i[i*ids_delta] = k_best;
206 }
207
208 if( max_dist < termcrit.epsilon )
209 break;
210
211 CV_SWAP( centers, old_centers, temp );
212 }
213
214 cvZero( counters );
215 for( i = 0; i < sample_count; i++ )
216 counters->data.i[labels->data.i[i]]++;
217
218 // ensure that we do not have empty clusters
219 for( k = 0; k < cluster_count; k++ )
220 if( counters->data.i[k] == 0 )
221 for(;;)
222 {
223 i = cvRandInt(&rng) % sample_count;
224 j = labels->data.i[i];
225 if( counters->data.i[j] > 1 )
226 {
227 labels->data.i[i] = k;
228 counters->data.i[j]--;
229 counters->data.i[k]++;
230 break;
231 }
232 }
233
234 __END__;
235
236 cvReleaseMat( ¢ers );
237 cvReleaseMat( &old_centers );
238 cvReleaseMat( &counters );
239 }
240
241
242 /*
243 Finds real roots of cubic, quadratic or linear equation.
244 The original code has been taken from Ken Turkowski web page
245 (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV.
246 Here is the copyright notice.
247
248 -----------------------------------------------------------------------
249 Copyright (C) 1978-1999 Ken Turkowski. <turk@computer.org>
250
251 All rights reserved.
252
253 Warranty Information
254 Even though I have reviewed this software, I make no warranty
255 or representation, either express or implied, with respect to this
256 software, its quality, accuracy, merchantability, or fitness for a
257 particular purpose. As a result, this software is provided "as is,"
258 and you, its user, are assuming the entire risk as to its quality
259 and accuracy.
260
261 This code may be used and freely distributed as long as it includes
262 this copyright notice and the above warranty information.
263 -----------------------------------------------------------------------
264 */
265 CV_IMPL int
cvSolveCubic(const CvMat * coeffs,CvMat * roots)266 cvSolveCubic( const CvMat* coeffs, CvMat* roots )
267 {
268 int n = 0;
269
270 CV_FUNCNAME( "cvSolveCubic" );
271
272 __BEGIN__;
273
274 double a0 = 1., a1, a2, a3;
275 double x0 = 0., x1 = 0., x2 = 0.;
276 int step = 1, coeff_count;
277
278 if( !CV_IS_MAT(coeffs) )
279 CV_ERROR( !coeffs ? CV_StsNullPtr : CV_StsBadArg, "Input parameter is not a valid matrix" );
280
281 if( !CV_IS_MAT(roots) )
282 CV_ERROR( !roots ? CV_StsNullPtr : CV_StsBadArg, "Output parameter is not a valid matrix" );
283
284 if( (CV_MAT_TYPE(coeffs->type) != CV_32FC1 && CV_MAT_TYPE(coeffs->type) != CV_64FC1) ||
285 (CV_MAT_TYPE(roots->type) != CV_32FC1 && CV_MAT_TYPE(roots->type) != CV_64FC1) )
286 CV_ERROR( CV_StsUnsupportedFormat,
287 "Both matrices should be floating-point (single or double precision)" );
288
289 coeff_count = coeffs->rows + coeffs->cols - 1;
290
291 if( (coeffs->rows != 1 && coeffs->cols != 1) || (coeff_count != 3 && coeff_count != 4) )
292 CV_ERROR( CV_StsBadSize,
293 "The matrix of coefficients must be 1-dimensional vector of 3 or 4 elements" );
294
295 if( (roots->rows != 1 && roots->cols != 1) ||
296 roots->rows + roots->cols - 1 != 3 )
297 CV_ERROR( CV_StsBadSize,
298 "The matrix of roots must be 1-dimensional vector of 3 elements" );
299
300 if( CV_MAT_TYPE(coeffs->type) == CV_32FC1 )
301 {
302 const float* c = coeffs->data.fl;
303 if( coeffs->rows > 1 )
304 step = coeffs->step/sizeof(c[0]);
305 if( coeff_count == 4 )
306 a0 = c[0], c += step;
307 a1 = c[0];
308 a2 = c[step];
309 a3 = c[step*2];
310 }
311 else
312 {
313 const double* c = coeffs->data.db;
314 if( coeffs->rows > 1 )
315 step = coeffs->step/sizeof(c[0]);
316 if( coeff_count == 4 )
317 a0 = c[0], c += step;
318 a1 = c[0];
319 a2 = c[step];
320 a3 = c[step*2];
321 }
322
323 if( a0 == 0 )
324 {
325 if( a1 == 0 )
326 {
327 if( a2 == 0 )
328 n = a3 == 0 ? -1 : 0;
329 else
330 {
331 // linear equation
332 x0 = a3/a2;
333 n = 1;
334 }
335 }
336 else
337 {
338 // quadratic equation
339 double d = a2*a2 - 4*a1*a3;
340 if( d >= 0 )
341 {
342 d = sqrt(d);
343 double q = (-a2 + (a2 < 0 ? -d : d)) * 0.5;
344 x0 = q / a1;
345 x1 = a3 / q;
346 n = d > 0 ? 2 : 1;
347 }
348 }
349 }
350 else
351 {
352 a0 = 1./a0;
353 a1 *= a0;
354 a2 *= a0;
355 a3 *= a0;
356
357 double Q = (a1 * a1 - 3 * a2) * (1./9);
358 double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54);
359 double Qcubed = Q * Q * Q;
360 double d = Qcubed - R * R;
361
362 if( d >= 0 )
363 {
364 double theta = acos(R / sqrt(Qcubed));
365 double sqrtQ = sqrt(Q);
366 double t0 = -2 * sqrtQ;
367 double t1 = theta * (1./3);
368 double t2 = a1 * (1./3);
369 x0 = t0 * cos(t1) - t2;
370 x1 = t0 * cos(t1 + (2.*CV_PI/3)) - t2;
371 x2 = t0 * cos(t1 + (4.*CV_PI/3)) - t2;
372 n = 3;
373 }
374 else
375 {
376 double e;
377 d = sqrt(-d);
378 e = pow(d + fabs(R), 0.333333333333);
379 if( R > 0 )
380 e = -e;
381 x0 = (e + Q / e) - a1 * (1./3);
382 n = 1;
383 }
384 }
385
386 step = 1;
387
388 if( CV_MAT_TYPE(roots->type) == CV_32FC1 )
389 {
390 float* r = roots->data.fl;
391 if( roots->rows > 1 )
392 step = roots->step/sizeof(r[0]);
393 r[0] = (float)x0;
394 r[step] = (float)x1;
395 r[step*2] = (float)x2;
396 }
397 else
398 {
399 double* r = roots->data.db;
400 if( roots->rows > 1 )
401 step = roots->step/sizeof(r[0]);
402 r[0] = x0;
403 r[step] = x1;
404 r[step*2] = x2;
405 }
406
407 __END__;
408
409 return n;
410 }
411
412
413 /*
414 Finds real and complex roots of polynomials of any degree with real
415 coefficients. The original code has been taken from Ken Turkowski's web
416 page (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV.
417 Here is the copyright notice.
418
419 -----------------------------------------------------------------------
420 Copyright (C) 1981-1999 Ken Turkowski. <turk@computer.org>
421
422 All rights reserved.
423
424 Warranty Information
425 Even though I have reviewed this software, I make no warranty
426 or representation, either express or implied, with respect to this
427 software, its quality, accuracy, merchantability, or fitness for a
428 particular purpose. As a result, this software is provided "as is,"
429 and you, its user, are assuming the entire risk as to its quality
430 and accuracy.
431
432 This code may be used and freely distributed as long as it includes
433 this copyright notice and the above warranty information.
434 */
435
436
437 /*******************************************************************************
438 * FindPolynomialRoots
439 *
440 * The Bairstow and Newton correction formulae are used for a simultaneous
441 * linear and quadratic iterated synthetic division. The coefficients of
442 * a polynomial of degree n are given as a[i] (i=0,i,..., n) where a[0] is
443 * the constant term. The coefficients are scaled by dividing them by
444 * their geometric mean. The Bairstow or Newton iteration method will
445 * nearly always converge to the number of figures carried, fig, either to
446 * root values or to their reciprocals. If the simultaneous Newton and
447 * Bairstow iteration fails to converge on root values or their
448 * reciprocals in maxiter iterations, the convergence requirement will be
449 * successively reduced by one decimal figure. This program anticipates
450 * and protects against loss of significance in the quadratic synthetic
451 * division. (Refer to "On Programming the Numerical Solution of
452 * Polynomial Equations," by K. W. Ellenberger, Commun. ACM 3 (Dec. 1960),
453 * 644-647.) The real and imaginary part of each root is stated as u[i]
454 * and v[i], respectively.
455 *
456 * ACM algorithm #30 - Numerical Solution of the Polynomial Equation
457 * K. W. Ellenberger
458 * Missle Division, North American Aviation, Downey, California
459 * Converted to C, modified, optimized, and structured by
460 * Ken Turkowski
461 * CADLINC, Inc., Palo Alto, California
462 *******************************************************************************/
463
464 #define MAXN 16
465
icvFindPolynomialRoots(const double * a,double * u,int n,int maxiter,int fig)466 static void icvFindPolynomialRoots(const double *a, double *u, int n, int maxiter, int fig)
467 {
468 int i;
469 int j;
470 double h[MAXN + 3], b[MAXN + 3], c[MAXN + 3], d[MAXN + 3], e[MAXN + 3];
471 // [-2 : n]
472 double K, ps, qs, pt, qt, s, rev, r = 0;
473 int t;
474 double p = 0, q = 0, qq;
475
476 // Zero elements with negative indices
477 b[2 + -1] = b[2 + -2] =
478 c[2 + -1] = c[2 + -2] =
479 d[2 + -1] = d[2 + -2] =
480 e[2 + -1] = e[2 + -2] =
481 h[2 + -1] = h[2 + -2] = 0.0;
482
483 // Copy polynomial coefficients to working storage
484 for (j = n; j >= 0; j--)
485 h[2 + j] = *a++; // Note reversal of coefficients
486
487 t = 1;
488 K = pow(10.0, (double)(fig)); // Relative accuracy
489
490 for (; h[2 + n] == 0.0; n--) { // Look for zero high-order coeff.
491 *u++ = 0.0;
492 *u++ = 0.0;
493 }
494
495 INIT:
496 if (n == 0)
497 return;
498
499 ps = qs = pt = qt = s = 0.0;
500 rev = 1.0;
501 K = pow(10.0, (double)(fig));
502
503 if (n == 1) {
504 r = -h[2 + 1] / h[2 + 0];
505 goto LINEAR;
506 }
507
508 for (j = n; j >= 0; j--) // Find geometric mean of coeff's
509 if (h[2 + j] != 0.0)
510 s += log(fabs(h[2 + j]));
511 s = exp(s / (n + 1));
512
513 for (j = n; j >= 0; j--) // Normalize coeff's by mean
514 h[2 + j] /= s;
515
516 if (fabs(h[2 + 1] / h[2 + 0]) < fabs(h[2 + n - 1] / h[2 + n])) {
517 REVERSE:
518 t = -t;
519 for (j = (n - 1) / 2; j >= 0; j--) {
520 s = h[2 + j];
521 h[2 + j] = h[2 + n - j];
522 h[2 + n - j] = s;
523 }
524 }
525 if (qs != 0.0) {
526 p = ps;
527 q = qs;
528 } else {
529 if (h[2 + n - 2] == 0.0) {
530 q = 1.0;
531 p = -2.0;
532 } else {
533 q = h[2 + n] / h[2 + n - 2];
534 p = (h[2 + n - 1] - q * h[2 + n - 3]) / h[2 + n - 2];
535 }
536 if (n == 2)
537 goto QADRTIC;
538 r = 0.0;
539 }
540 ITERATE:
541 for (i = maxiter; i > 0; i--) {
542
543 for (j = 0; j <= n; j++) { // BAIRSTOW
544 b[2 + j] = h[2 + j] - p * b[2 + j - 1] - q * b[2 + j - 2];
545 c[2 + j] = b[2 + j] - p * c[2 + j - 1] - q * c[2 + j - 2];
546 }
547 if ((h[2 + n - 1] != 0.0) && (b[2 + n - 1] != 0.0)) {
548 if (fabs(h[2 + n - 1] / b[2 + n - 1]) >= K) {
549 b[2 + n] = h[2 + n] - q * b[2 + n - 2];
550 }
551 if (b[2 + n] == 0.0)
552 goto QADRTIC;
553 if (K < fabs(h[2 + n] / b[2 + n]))
554 goto QADRTIC;
555 }
556
557 for (j = 0; j <= n; j++) { // NEWTON
558 d[2 + j] = h[2 + j] + r * d[2 + j - 1]; // Calculate polynomial at r
559 e[2 + j] = d[2 + j] + r * e[2 + j - 1]; // Calculate derivative at r
560 }
561 if (d[2 + n] == 0.0)
562 goto LINEAR;
563 if (K < fabs(h[2 + n] / d[2 + n]))
564 goto LINEAR;
565
566 c[2 + n - 1] = -p * c[2 + n - 2] - q * c[2 + n - 3];
567 s = c[2 + n - 2] * c[2 + n - 2] - c[2 + n - 1] * c[2 + n - 3];
568 if (s == 0.0) {
569 p -= 2.0;
570 q *= (q + 1.0);
571 } else {
572 p += (b[2 + n - 1] * c[2 + n - 2] - b[2 + n] * c[2 + n - 3]) / s;
573 q += (-b[2 + n - 1] * c[2 + n - 1] + b[2 + n] * c[2 + n - 2]) / s;
574 }
575 if (e[2 + n - 1] == 0.0)
576 r -= 1.0; // Minimum step
577 else
578 r -= d[2 + n] / e[2 + n - 1]; // Newton's iteration
579 }
580 ps = pt;
581 qs = qt;
582 pt = p;
583 qt = q;
584 if (rev < 0.0)
585 K /= 10.0;
586 rev = -rev;
587 goto REVERSE;
588
589 LINEAR:
590 if (t < 0)
591 r = 1.0 / r;
592 n--;
593 *u++ = r;
594 *u++ = 0.0;
595
596 for (j = n; j >= 0; j--) { // Polynomial deflation by lin-nomial
597 if ((d[2 + j] != 0.0) && (fabs(h[2 + j] / d[2 + j]) < K))
598 h[2 + j] = d[2 + j];
599 else
600 h[2 + j] = 0.0;
601 }
602
603 if (n == 0)
604 return;
605 goto ITERATE;
606
607 QADRTIC:
608 if (t < 0) {
609 p /= q;
610 q = 1.0 / q;
611 }
612 n -= 2;
613
614 if (0.0 < (q - (p * p / 4.0))) { // Two complex roots
615 s = sqrt(q - (p * p / 4.0));
616 *u++ = -p / 2.0;
617 *u++ = s;
618 *u++ = -p / 2.0;
619 *u++ = -s;
620 } else { // Two real roots
621 s = sqrt(((p * p / 4.0)) - q);
622 if (p < 0.0)
623 *u++ = qq = -p / 2.0 + s;
624 else
625 *u++ = qq = -p / 2.0 - s;
626 *u++ = 0.0;
627 *u++ = q / qq;
628 *u++ = 0.0;
629 }
630
631 for (j = n; j >= 0; j--) { // Polynomial deflation by quadratic
632 if ((b[2 + j] != 0.0) && (fabs(h[2 + j] / b[2 + j]) < K))
633 h[2 + j] = b[2 + j];
634 else
635 h[2 + j] = 0.0;
636 }
637 goto INIT;
638 }
639
640 #undef MAXN
641
cvSolvePoly(const CvMat * a,CvMat * r,int maxiter,int fig)642 void cvSolvePoly(const CvMat* a, CvMat *r, int maxiter, int fig)
643 {
644 __BEGIN__;
645
646 int m, n;
647 double *ad = 0, *rd = 0;
648
649 CV_FUNCNAME("cvSolvePoly");
650
651 if (CV_MAT_TYPE(a->type) != CV_32FC1 &&
652 CV_MAT_TYPE(a->type) != CV_64FC1)
653 CV_ERROR(CV_StsUnsupportedFormat, "coeffs must be either CV_32FC1 or CV_64FC1");
654 if (CV_MAT_TYPE(r->type) != CV_32FC2 &&
655 CV_MAT_TYPE(r->type) != CV_64FC2)
656 CV_ERROR(CV_StsUnsupportedFormat, "roots must be either CV_32FC2 or CV_64FC2");
657 m = a->rows * a->cols;
658 n = r->rows * r->cols;
659
660 if (m - 1 != n)
661 CV_ERROR(CV_StsUnmatchedFormats, "must have n + 1 coefficients");
662
663 if( CV_MAT_TYPE(a->type) == CV_32F || !CV_IS_MAT_CONT(a->type))
664 {
665 ad = (double*)cvStackAlloc(m*sizeof(ad[0]));
666 CvMat _a = cvMat( a->rows, a->cols, CV_64F, ad );
667 cvConvert( a, &_a );
668 }
669 else
670 ad = a->data.db;
671
672 if( CV_MAT_TYPE(r->type) == CV_32F || !CV_IS_MAT_CONT(r->type))
673 rd = (double*)cvStackAlloc(n*sizeof(ad[0]));
674 else
675 rd = r->data.db;
676
677 icvFindPolynomialRoots( ad, rd, n, maxiter, fig);
678 if( rd != r->data.db )
679 {
680 CvMat _r = cvMat( r->rows, r->cols, CV_64F, rd );
681 cvConvert( &_r, r );
682 }
683
684 __END__;
685 }
686
687
cvNormalize(const CvArr * src,CvArr * dst,double a,double b,int norm_type,const CvArr * mask)688 CV_IMPL void cvNormalize( const CvArr* src, CvArr* dst,
689 double a, double b, int norm_type, const CvArr* mask )
690 {
691 CvMat* tmp = 0;
692
693 CV_FUNCNAME( "cvNormalize" );
694
695 __BEGIN__;
696
697 double scale, shift;
698
699 if( norm_type == CV_MINMAX )
700 {
701 double smin = 0, smax = 0;
702 double dmin = MIN( a, b ), dmax = MAX( a, b );
703 cvMinMaxLoc( src, &smin, &smax, 0, 0, mask );
704 scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0);
705 shift = dmin - smin*scale;
706 }
707 else if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C )
708 {
709 CvMat *s = (CvMat*)src, *d = (CvMat*)dst;
710
711 if( CV_IS_MAT(s) && CV_IS_MAT(d) && CV_IS_MAT_CONT(s->type & d->type) &&
712 CV_ARE_TYPES_EQ(s,d) && CV_ARE_SIZES_EQ(s,d) && !mask &&
713 s->cols*s->rows <= CV_MAX_INLINE_MAT_OP_SIZE*CV_MAX_INLINE_MAT_OP_SIZE )
714 {
715 int i, len = s->cols*s->rows;
716 double norm = 0, v;
717
718 if( CV_MAT_TYPE(s->type) == CV_32FC1 )
719 {
720 const float* sptr = s->data.fl;
721 float* dptr = d->data.fl;
722
723 if( norm_type == CV_L2 )
724 {
725 for( i = 0; i < len; i++ )
726 {
727 v = sptr[i];
728 norm += v*v;
729 }
730 norm = sqrt(norm);
731 }
732 else if( norm_type == CV_L1 )
733 for( i = 0; i < len; i++ )
734 {
735 v = fabs((double)sptr[i]);
736 norm += v;
737 }
738 else
739 for( i = 0; i < len; i++ )
740 {
741 v = fabs((double)sptr[i]);
742 norm = MAX(norm,v);
743 }
744
745 norm = norm > DBL_EPSILON ? 1./norm : 0.;
746 for( i = 0; i < len; i++ )
747 dptr[i] = (float)(sptr[i]*norm);
748 EXIT;
749 }
750
751 if( CV_MAT_TYPE(s->type) == CV_64FC1 )
752 {
753 const double* sptr = s->data.db;
754 double* dptr = d->data.db;
755
756 if( norm_type == CV_L2 )
757 {
758 for( i = 0; i < len; i++ )
759 {
760 v = sptr[i];
761 norm += v*v;
762 }
763 norm = sqrt(norm);
764 }
765 else if( norm_type == CV_L1 )
766 for( i = 0; i < len; i++ )
767 {
768 v = fabs(sptr[i]);
769 norm += v;
770 }
771 else
772 for( i = 0; i < len; i++ )
773 {
774 v = fabs(sptr[i]);
775 norm = MAX(norm,v);
776 }
777
778 norm = norm > DBL_EPSILON ? 1./norm : 0.;
779 for( i = 0; i < len; i++ )
780 dptr[i] = sptr[i]*norm;
781 EXIT;
782 }
783 }
784
785 scale = cvNorm( src, 0, norm_type, mask );
786 scale = scale > DBL_EPSILON ? 1./scale : 0.;
787 shift = 0;
788 }
789 else
790 CV_ERROR( CV_StsBadArg, "Unknown/unsupported norm type" );
791
792 if( !mask )
793 cvConvertScale( src, dst, scale, shift );
794 else
795 {
796 CvMat stub, *dmat;
797 CV_CALL( dmat = cvGetMat(dst, &stub));
798 CV_CALL( tmp = cvCreateMat(dmat->rows, dmat->cols, dmat->type) );
799 cvConvertScale( src, tmp, scale, shift );
800 cvCopy( tmp, dst, mask );
801 }
802
803 __END__;
804
805 if( tmp )
806 cvReleaseMat( &tmp );
807 }
808
809
cvRandShuffle(CvArr * arr,CvRNG * rng,double iter_factor)810 CV_IMPL void cvRandShuffle( CvArr* arr, CvRNG* rng, double iter_factor )
811 {
812 CV_FUNCNAME( "cvRandShuffle" );
813
814 __BEGIN__;
815
816 const int sizeof_int = (int)sizeof(int);
817 CvMat stub, *mat = (CvMat*)arr;
818 int i, j, k, iters, delta = 0;
819 int cont_flag, arr_size, elem_size, cols, step;
820 const int pair_buf_sz = 100;
821 int* pair_buf = (int*)cvStackAlloc( pair_buf_sz*sizeof(pair_buf[0])*2 );
822 CvMat _pair_buf = cvMat( 1, pair_buf_sz*2, CV_32S, pair_buf );
823 CvRNG _rng = cvRNG(-1);
824 uchar* data = 0;
825 int* idata = 0;
826
827 if( !CV_IS_MAT(mat) )
828 CV_CALL( mat = cvGetMat( mat, &stub ));
829
830 if( !rng )
831 rng = &_rng;
832
833 cols = mat->cols;
834 step = mat->step;
835 arr_size = cols*mat->rows;
836 iters = cvRound(iter_factor*arr_size)*2;
837 cont_flag = CV_IS_MAT_CONT(mat->type);
838 elem_size = CV_ELEM_SIZE(mat->type);
839 if( elem_size % sizeof_int == 0 && (cont_flag || step % sizeof_int == 0) )
840 {
841 idata = mat->data.i;
842 step /= sizeof_int;
843 elem_size /= sizeof_int;
844 }
845 else
846 data = mat->data.ptr;
847
848 for( i = 0; i < iters; i += delta )
849 {
850 delta = MIN( iters - i, pair_buf_sz*2 );
851 _pair_buf.cols = delta;
852 cvRandArr( rng, &_pair_buf, CV_RAND_UNI, cvRealScalar(0), cvRealScalar(arr_size) );
853
854 if( cont_flag )
855 {
856 if( idata )
857 for( j = 0; j < delta; j += 2 )
858 {
859 int* p = idata + pair_buf[j]*elem_size, *q = idata + pair_buf[j+1]*elem_size, t;
860 for( k = 0; k < elem_size; k++ )
861 CV_SWAP( p[k], q[k], t );
862 }
863 else
864 for( j = 0; j < delta; j += 2 )
865 {
866 uchar* p = data + pair_buf[j]*elem_size, *q = data + pair_buf[j+1]*elem_size, t;
867 for( k = 0; k < elem_size; k++ )
868 CV_SWAP( p[k], q[k], t );
869 }
870 }
871 else
872 {
873 if( idata )
874 for( j = 0; j < delta; j += 2 )
875 {
876 int idx1 = pair_buf[j], idx2 = pair_buf[j+1], row1, row2;
877 int* p, *q, t;
878 row1 = idx1/step; row2 = idx2/step;
879 p = idata + row1*step + (idx1 - row1*cols)*elem_size;
880 q = idata + row2*step + (idx2 - row2*cols)*elem_size;
881
882 for( k = 0; k < elem_size; k++ )
883 CV_SWAP( p[k], q[k], t );
884 }
885 else
886 for( j = 0; j < delta; j += 2 )
887 {
888 int idx1 = pair_buf[j], idx2 = pair_buf[j+1], row1, row2;
889 uchar* p, *q, t;
890 row1 = idx1/step; row2 = idx2/step;
891 p = data + row1*step + (idx1 - row1*cols)*elem_size;
892 q = data + row2*step + (idx2 - row2*cols)*elem_size;
893
894 for( k = 0; k < elem_size; k++ )
895 CV_SWAP( p[k], q[k], t );
896 }
897 }
898 }
899
900 __END__;
901 }
902
903
904 CV_IMPL CvArr*
cvRange(CvArr * arr,double start,double end)905 cvRange( CvArr* arr, double start, double end )
906 {
907 int ok = 0;
908
909 CV_FUNCNAME( "cvRange" );
910
911 __BEGIN__;
912
913 CvMat stub, *mat = (CvMat*)arr;
914 double delta;
915 int type, step;
916 double val = start;
917 int i, j;
918 int rows, cols;
919
920 if( !CV_IS_MAT(mat) )
921 CV_CALL( mat = cvGetMat( mat, &stub) );
922
923 rows = mat->rows;
924 cols = mat->cols;
925 type = CV_MAT_TYPE(mat->type);
926 delta = (end-start)/(rows*cols);
927
928 if( CV_IS_MAT_CONT(mat->type) )
929 {
930 cols *= rows;
931 rows = 1;
932 step = 1;
933 }
934 else
935 step = mat->step / CV_ELEM_SIZE(type);
936
937 if( type == CV_32SC1 )
938 {
939 int* idata = mat->data.i;
940 int ival = cvRound(val), idelta = cvRound(delta);
941
942 if( fabs(val - ival) < DBL_EPSILON &&
943 fabs(delta - idelta) < DBL_EPSILON )
944 {
945 for( i = 0; i < rows; i++, idata += step )
946 for( j = 0; j < cols; j++, ival += idelta )
947 idata[j] = ival;
948 }
949 else
950 {
951 for( i = 0; i < rows; i++, idata += step )
952 for( j = 0; j < cols; j++, val += delta )
953 idata[j] = cvRound(val);
954 }
955 }
956 else if( type == CV_32FC1 )
957 {
958 float* fdata = mat->data.fl;
959 for( i = 0; i < rows; i++, fdata += step )
960 for( j = 0; j < cols; j++, val += delta )
961 fdata[j] = (float)val;
962 }
963 else
964 CV_ERROR( CV_StsUnsupportedFormat, "The function only supports 32sC1 and 32fC1 datatypes" );
965
966 ok = 1;
967
968 __END__;
969
970 return ok ? arr : 0;
971 }
972
973
974 #define ICV_LT_BY_IDX(a, b) (aux[a] < aux[b])
975
976 static CV_IMPLEMENT_QSORT_EX( icvSortIdx64f, int, ICV_LT_BY_IDX, const double* )
977 static CV_IMPLEMENT_QSORT_EX( icvSortIdx32f, int, ICV_LT_BY_IDX, const float* )
978 static CV_IMPLEMENT_QSORT_EX( icvSortIdx32s, int, ICV_LT_BY_IDX, const int* )
979 static CV_IMPLEMENT_QSORT_EX( icvSortIdx16u, int, ICV_LT_BY_IDX, const ushort* )
980 static CV_IMPLEMENT_QSORT_EX( icvSortIdx16s, int, ICV_LT_BY_IDX, const short* )
981 static CV_IMPLEMENT_QSORT_EX( icvSortIdx8u, int, ICV_LT_BY_IDX, const uchar* )
982 static CV_IMPLEMENT_QSORT_EX( icvSortIdx8s, int, ICV_LT_BY_IDX, const schar* )
983
984 static CV_IMPLEMENT_QSORT_EX( icvSort64f, double, CV_LT, int )
985 static CV_IMPLEMENT_QSORT_EX( icvSort32f, float, CV_LT, int )
986 static CV_IMPLEMENT_QSORT_EX( icvSort32s, int, CV_LT, int )
987 static CV_IMPLEMENT_QSORT_EX( icvSort16u, ushort, CV_LT, int )
988 static CV_IMPLEMENT_QSORT_EX( icvSort16s, short, CV_LT, int )
989 static CV_IMPLEMENT_QSORT_EX( icvSort8u, uchar, CV_LT, int )
990 static CV_IMPLEMENT_QSORT_EX( icvSort8s, schar, CV_LT, int )
991
992 typedef void (*CvSortFunc)( void* arr, size_t n, int );
993 typedef void (*CvSortIdxFunc)( int* arr, size_t n, const void* );
994
995 static inline void
icvCopy1D(const void * src,int s,void * dst,int d,int n,int elemSize)996 icvCopy1D( const void* src, int s, void* dst, int d, int n, int elemSize )
997 {
998 int i;
999 switch( elemSize )
1000 {
1001 case 1:
1002 for( i = 0; i < n; i++ )
1003 ((uchar*)dst)[i*d] = ((uchar*)src)[i*s];
1004 break;
1005 case 2:
1006 for( i = 0; i < n; i++ )
1007 ((ushort*)dst)[i*d] = ((ushort*)src)[i*s];
1008 break;
1009 case 4:
1010 for( i = 0; i < n; i++ )
1011 ((int*)dst)[i*d] = ((int*)src)[i*s];
1012 break;
1013 case 8:
1014 for( i = 0; i < n; i++ )
1015 ((int64*)dst)[i*d] = ((int64*)src)[i*s];
1016 break;
1017 default:
1018 assert(0);
1019 }
1020 }
1021
1022 static void
icvShuffle1D(const uchar * src,const int * idx,uchar * dst,int d,int n,int elemSize)1023 icvShuffle1D( const uchar* src, const int* idx, uchar* dst, int d, int n, int elemSize )
1024 {
1025 int i;
1026 switch( elemSize )
1027 {
1028 case 1:
1029 for( i = 0; i < n; i++ )
1030 dst[i*d] = src[idx[i]];
1031 break;
1032 case 2:
1033 for( i = 0; i < n; i++ )
1034 ((ushort*)dst)[i*d] = ((ushort*)src)[idx[i]];
1035 break;
1036 case 4:
1037 for( i = 0; i < n; i++ )
1038 ((int*)dst)[i*d] = ((int*)src)[idx[i]];
1039 break;
1040 case 8:
1041 for( i = 0; i < n; i++ )
1042 ((int64*)dst)[i*d] = ((int64*)src)[idx[i]];
1043 break;
1044 default:
1045 assert(0);
1046 }
1047 }
1048
1049
1050 CV_IMPL void
cvSort(const CvArr * _src,CvArr * _dst,CvArr * _idx,int flags)1051 cvSort( const CvArr* _src, CvArr* _dst, CvArr* _idx, int flags )
1052 {
1053 uchar *tsrc = 0;
1054 int* tidx = 0;
1055
1056 CV_FUNCNAME("cvSort");
1057
1058 __BEGIN__;
1059
1060 CvMat sstub, *src = cvGetMat(_src, &sstub);
1061 CvMat dstub, *dst = _dst ? cvGetMat(_dst, &dstub) : 0;
1062 CvMat istub, *idx = _idx ? cvGetMat(_idx, &istub) : 0;
1063 int type = CV_MAT_TYPE(src->type), elemSize = CV_ELEM_SIZE(type);
1064 int sstep = src->step, dstep = dst ? dst->step : 0;
1065 int istep = idx ? idx->step/sizeof(int) : 0;
1066 int i, len = src->cols;
1067 CvSortFunc sortFunc = 0;
1068 CvSortIdxFunc sortIdxFunc = 0;
1069
1070 if( CV_MAT_CN( src->type ) != 1 )
1071 CV_ERROR( CV_StsUnsupportedFormat, "The input matrix should be a one-channel matrix." );
1072 if( idx )
1073 {
1074 if( CV_MAT_TYPE( idx->type ) != CV_32SC1)
1075 CV_ERROR( CV_StsUnsupportedFormat, "The index matrix must be CV_32SC1." );
1076
1077 if( !CV_ARE_SIZES_EQ( idx, src ))
1078 CV_ERROR( CV_StsUnmatchedSizes, "The input matrix and index matrix must be of the same size" );
1079 }
1080
1081 if( dst )
1082 {
1083 if( !CV_ARE_TYPES_EQ(src, dst) )
1084 CV_ERROR( CV_StsUnmatchedFormats, "The input and output matrix must be of the same type" );
1085
1086 if( !CV_ARE_SIZES_EQ(src, dst) )
1087 CV_ERROR( CV_StsUnmatchedSizes, "The input and output matrix must be of the same size" );
1088 }
1089
1090 if( !idx && !dst )
1091 CV_ERROR( CV_StsNullPtr, "At least one of index array or destination array must be non-NULL" );
1092
1093 if( type == CV_8U )
1094 sortIdxFunc = (CvSortIdxFunc)icvSortIdx8u, sortFunc = (CvSortFunc)icvSort8u;
1095 else if( type == CV_8S )
1096 sortIdxFunc = (CvSortIdxFunc)icvSortIdx8s, sortFunc = (CvSortFunc)icvSort8s;
1097 else if( type == CV_16U )
1098 sortIdxFunc = (CvSortIdxFunc)icvSortIdx16u, sortFunc = (CvSortFunc)icvSort16u;
1099 else if( type == CV_16S )
1100 sortIdxFunc = (CvSortIdxFunc)icvSortIdx16s, sortFunc = (CvSortFunc)icvSort16s;
1101 else if( type == CV_32S )
1102 sortIdxFunc = (CvSortIdxFunc)icvSortIdx32s, sortFunc = (CvSortFunc)icvSort32s;
1103 else if( type == CV_32F )
1104 sortIdxFunc = (CvSortIdxFunc)icvSortIdx32f, sortFunc = (CvSortFunc)icvSort32f;
1105 else if( type == CV_64F )
1106 sortIdxFunc = (CvSortIdxFunc)icvSortIdx64f, sortFunc = (CvSortFunc)icvSort64f;
1107 else
1108 CV_ERROR( CV_StsUnsupportedFormat, "Unsupported format of the input array" );
1109
1110 // single-column case, where all of src, idx & dst arrays are continuous, is
1111 // equivalent to "sort every row" mode.
1112 if( (flags & CV_SORT_EVERY_COLUMN) &&
1113 (src->cols > 1 || !CV_IS_MAT_CONT(src->type &
1114 (dst ? dst->type : -1) & (idx ? idx->type : -1))) )
1115 {
1116 uchar* dptr = dst ? dst->data.ptr : 0;
1117 int* idxptr = idx ? idx->data.i : 0;
1118
1119 len = src->rows;
1120 tsrc = (uchar*)cvAlloc(len*elemSize);
1121 if( idx )
1122 {
1123 tidx = (int*)cvAlloc(len*sizeof(tidx[0]));
1124 for( i = 0; i < len; i++ )
1125 tidx[i] = i;
1126 }
1127
1128 if( flags & CV_SORT_DESCENDING )
1129 {
1130 dptr += dstep*(src->rows - 1);
1131 dstep = -dstep;
1132 idxptr += istep*(src->rows - 1);
1133 istep = -istep;
1134 }
1135
1136 sstep /= elemSize;
1137 dstep /= elemSize;
1138
1139 for( i = 0; i < src->cols; i++ )
1140 {
1141 icvCopy1D( src->data.ptr + i*elemSize, sstep, tsrc, 1, len, elemSize );
1142 if( tidx )
1143 {
1144 sortIdxFunc( tidx, len, tsrc );
1145 if( dst )
1146 icvShuffle1D( tsrc, tidx, dptr + i*elemSize, dstep, len, elemSize );
1147 icvCopy1D( tidx, 1, idxptr + i, istep, len, sizeof(int) );
1148 }
1149 else
1150 {
1151 sortFunc( tsrc, len, 0 );
1152 icvCopy1D( tsrc, 1, dptr + i*elemSize, dstep, len, elemSize );
1153 }
1154 }
1155 }
1156 else
1157 {
1158 int j, t, count = src->rows;
1159 if( flags & CV_SORT_EVERY_COLUMN )
1160 CV_SWAP( len, count, t );
1161
1162 if( (flags & CV_SORT_DESCENDING) || (idx && dst && dst->data.ptr == src->data.ptr) )
1163 tsrc = (uchar*)cvAlloc(len*elemSize);
1164
1165 for( i = 0; i < count; i++ )
1166 {
1167 if( !idx )
1168 {
1169 const uchar* sptr = src->data.ptr + i*sstep;
1170 uchar* dptr = dst->data.ptr + i*dstep;
1171 uchar* ptr = flags & CV_SORT_DESCENDING ? tsrc : dptr;
1172 if( ptr != sptr )
1173 icvCopy1D( sptr, 1, ptr, 1, len, elemSize );
1174 sortFunc( ptr, len, 0 );
1175 if( flags & CV_SORT_DESCENDING )
1176 icvCopy1D( ptr + (len-1)*elemSize, -1, dptr, 1, len, elemSize );
1177 }
1178 else
1179 {
1180 int* idx_ = idx->data.i + istep*i;
1181 const uchar* sptr = src->data.ptr + sstep*i;
1182 uchar* dptr = dst ? dst->data.ptr + dstep*i : 0;
1183 for( j = 0; j < len; j++ )
1184 idx_[j] = j;
1185 if( dptr && dptr == sptr )
1186 {
1187 icvCopy1D( sptr, 1, tsrc, 1, len, elemSize );
1188 sptr = tsrc;
1189 }
1190 sortIdxFunc( idx_, len, sptr );
1191 if( flags & CV_SORT_DESCENDING )
1192 for( j = 0; j < len/2; j++ )
1193 CV_SWAP(idx_[j], idx_[len-j-1], t);
1194 if( dptr )
1195 icvShuffle1D( sptr, idx_, dptr, 1, len, elemSize );
1196 }
1197 }
1198 }
1199
1200 __END__;
1201
1202 cvFree( &tsrc );
1203 cvFree( &tidx );
1204 }
1205
1206 /* End of file. */
1207