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
44CV_IMPL void
45cvKMeans2( 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( &centers );
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*/
265CV_IMPL int
266cvSolveCubic( 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
466static 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
642void 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
688CV_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
810CV_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
904CV_IMPL CvArr*
905cvRange( 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
976static CV_IMPLEMENT_QSORT_EX( icvSortIdx64f, int, ICV_LT_BY_IDX, const double* )
977static CV_IMPLEMENT_QSORT_EX( icvSortIdx32f, int, ICV_LT_BY_IDX, const float* )
978static CV_IMPLEMENT_QSORT_EX( icvSortIdx32s, int, ICV_LT_BY_IDX, const int* )
979static CV_IMPLEMENT_QSORT_EX( icvSortIdx16u, int, ICV_LT_BY_IDX, const ushort* )
980static CV_IMPLEMENT_QSORT_EX( icvSortIdx16s, int, ICV_LT_BY_IDX, const short* )
981static CV_IMPLEMENT_QSORT_EX( icvSortIdx8u, int, ICV_LT_BY_IDX, const uchar* )
982static CV_IMPLEMENT_QSORT_EX( icvSortIdx8s, int, ICV_LT_BY_IDX, const schar* )
983
984static CV_IMPLEMENT_QSORT_EX( icvSort64f, double, CV_LT, int )
985static CV_IMPLEMENT_QSORT_EX( icvSort32f, float, CV_LT, int )
986static CV_IMPLEMENT_QSORT_EX( icvSort32s, int, CV_LT, int )
987static CV_IMPLEMENT_QSORT_EX( icvSort16u, ushort, CV_LT, int )
988static CV_IMPLEMENT_QSORT_EX( icvSort16s, short, CV_LT, int )
989static CV_IMPLEMENT_QSORT_EX( icvSort8u, uchar, CV_LT, int )
990static CV_IMPLEMENT_QSORT_EX( icvSort8s, schar, CV_LT, int )
991
992typedef void (*CvSortFunc)( void* arr, size_t n, int );
993typedef void (*CvSortIdxFunc)( int* arr, size_t n, const void* );
994
995static inline void
996icvCopy1D( 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
1022static void
1023icvShuffle1D( 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
1050CV_IMPL void
1051cvSort( 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