1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
44 /*F///////////////////////////////////////////////////////////////////////////////////////
45 // Names: icvJacobiEigens_32f, icvJacobiEigens_64d
46 // Purpose: Eigenvalues & eigenvectors calculation of a symmetric matrix:
49 // Parameters: A(n, n) - source symmetric matrix (n - rows & columns number),
50 // V(n, n) - matrix of its eigenvectors
51 // (i-th row is an eigenvector Vi),
52 // E(n) - vector of its eigenvalues
53 // (i-th element is an eigenvalue Ei),
54 // eps - accuracy of diagonalization.
57 // CV_NO_ERROR or error code
59 // 1. The functions destroy source matrix A, so if you need it further, you
60 // have to copy it before the processing.
61 // 2. Eigenvalies and eigenvectors are sorted in Ei absolute value descending.
62 // 3. Calculation time depends on eps value. If the time isn't very important,
63 // we recommend to set eps = 0.
66 /*=========================== Single precision function ================================*/
68 static CvStatus CV_STDCALL
69 icvJacobiEigens_32f(float *A, float *V, float *E, int n, float eps)
71 int i, j, k, ind, iters = 0;
72 float *AA = A, *VV = V;
73 double Amax, anorm = 0, ax;
75 if( A == NULL || V == NULL || E == NULL )
76 return CV_NULLPTR_ERR;
78 return CV_BADSIZE_ERR;
79 if( eps < DBL_EPSILON )
82 /*-------- Prepare --------*/
83 for( i = 0; i < n; i++, VV += n, AA += n )
85 for( j = 0; j < i; j++ )
91 for( j = 0; j < n; j++ )
96 anorm = sqrt( anorm + anorm );
100 while( Amax > ax && iters++ < 100 )
106 float *V1 = V, *A1 = A;
109 for( p = 0; p < n - 1; p++, A1 += n, V1 += n )
111 float *A2 = A + n * (p + 1), *V2 = V + n * (p + 1);
113 for( q = p + 1; q < n; q++, A2 += n, V2 += n )
115 double x, y, c, s, c2, s2, a;
116 float *A3, Apq = A1[q], App, Aqq, Aip, Aiq, Vpi, Vqi;
118 if( fabs( Apq ) < Amax )
123 /*---- Calculation of rotation angle's sine & cosine ----*/
126 y = 5.0e-1 * (App - Aqq);
127 x = -Apq / sqrt( (double)Apq * Apq + (double)y * y );
130 s = x / sqrt( 2.0 * (1.0 + sqrt( 1.0 - (double)x * x )));
132 c = sqrt( 1.0 - s2 );
134 a = 2.0 * Apq * c * s;
136 /*---- Apq annulation ----*/
138 for( i = 0; i < p; i++, A3 += n )
144 A3[p] = (float) (Aip * c - Aiq * s);
145 A3[q] = (float) (Aiq * c + Aip * s);
146 V1[i] = (float) (Vpi * c - Vqi * s);
147 V2[i] = (float) (Vqi * c + Vpi * s);
149 for( ; i < q; i++, A3 += n )
155 A1[i] = (float) (Aip * c - Aiq * s);
156 A3[q] = (float) (Aiq * c + Aip * s);
157 V1[i] = (float) (Vpi * c - Vqi * s);
158 V2[i] = (float) (Vqi * c + Vpi * s);
166 A1[i] = (float) (Aip * c - Aiq * s);
167 A2[i] = (float) (Aiq * c + Aip * s);
168 V1[i] = (float) (Vpi * c - Vqi * s);
169 V2[i] = (float) (Vqi * c + Vpi * s);
171 A1[p] = (float) (App * c2 + Aqq * s2 - a);
172 A2[q] = (float) (App * s2 + Aqq * c2 + a);
173 A1[q] = A2[p] = 0.0f;
179 } /* while ( Amax > ax ) */
181 for( i = 0, k = 0; i < n; i++, k += n + 1 )
183 /*printf(" M = %d\n", M); */
185 /* -------- ordering -------- */
186 for( i = 0; i < n; i++ )
189 float Em = (float) fabs( E[i] );
191 for( j = i + 1; j < n; j++ )
193 float Ej = (float) fabs( E[j] );
195 m = (Em < Ej) ? j : m;
196 Em = (Em < Ej) ? Ej : Em;
205 for( j = 0, k = i * n, l = m * n; j < n; j++, k++, l++ )
217 /*=========================== Double precision function ================================*/
219 static CvStatus CV_STDCALL
220 icvJacobiEigens_64d(double *A, double *V, double *E, int n, double eps)
222 int i, j, k, p, q, ind, iters = 0;
223 double *A1 = A, *V1 = V, *A2 = A, *V2 = V;
224 double Amax = 0.0, anorm = 0.0, ax;
226 if( A == NULL || V == NULL || E == NULL )
227 return CV_NULLPTR_ERR;
229 return CV_BADSIZE_ERR;
230 if( eps < DBL_EPSILON )
233 /*-------- Prepare --------*/
234 for( i = 0; i < n; i++, V1 += n, A1 += n )
236 for( j = 0; j < i; j++ )
242 for( j = 0; j < n; j++ )
247 anorm = sqrt( anorm + anorm );
248 ax = anorm * eps / n;
251 while( Amax > ax && iters++ < 100 )
259 for( p = 0; p < n - 1; p++, A1 += n, V1 += n )
261 A2 = A + n * (p + 1);
262 V2 = V + n * (p + 1);
263 for( q = p + 1; q < n; q++, A2 += n, V2 += n )
265 double x, y, c, s, c2, s2, a;
266 double *A3, Apq, App, Aqq, App2, Aqq2, Aip, Aiq, Vpi, Vqi;
268 if( fabs( A1[q] ) < Amax )
274 /*---- Calculation of rotation angle's sine & cosine ----*/
277 y = 5.0e-1 * (App - Aqq);
278 x = -Apq / sqrt( Apq * Apq + (double)y * y );
281 s = x / sqrt( 2.0 * (1.0 + sqrt( 1.0 - (double)x * x )));
283 c = sqrt( 1.0 - s2 );
285 a = 2.0 * Apq * c * s;
287 /*---- Apq annulation ----*/
289 for( i = 0; i < p; i++, A3 += n )
295 A3[p] = Aip * c - Aiq * s;
296 A3[q] = Aiq * c + Aip * s;
297 V1[i] = Vpi * c - Vqi * s;
298 V2[i] = Vqi * c + Vpi * s;
300 for( ; i < q; i++, A3 += n )
306 A1[i] = Aip * c - Aiq * s;
307 A3[q] = Aiq * c + Aip * s;
308 V1[i] = Vpi * c - Vqi * s;
309 V2[i] = Vqi * c + Vpi * s;
317 A1[i] = Aip * c - Aiq * s;
318 A2[i] = Aiq * c + Aip * s;
319 V1[i] = Vpi * c - Vqi * s;
320 V2[i] = Vqi * c + Vpi * s;
322 App2 = App * c2 + Aqq * s2 - a;
323 Aqq2 = App * s2 + Aqq * c2 + a;
331 } /* while ( Amax > ax ) */
333 for( i = 0, k = 0; i < n; i++, k += n + 1 )
336 /* -------- ordering -------- */
337 for( i = 0; i < n; i++ )
340 double Em = fabs( E[i] );
342 for( j = i + 1; j < n; j++ )
344 double Ej = fabs( E[j] );
346 m = (Em < Ej) ? j : m;
347 Em = (Em < Ej) ? Ej : Em;
356 for( j = 0, k = i * n, l = m * n; j < n; j++, k++, l++ )
370 cvEigenVV( CvArr* srcarr, CvArr* evectsarr, CvArr* evalsarr, double eps )
373 CV_FUNCNAME( "cvEigenVV" );
377 CvMat sstub, *src = (CvMat*)srcarr;
378 CvMat estub1, *evects = (CvMat*)evectsarr;
379 CvMat estub2, *evals = (CvMat*)evalsarr;
381 if( !CV_IS_MAT( src ))
382 CV_CALL( src = cvGetMat( src, &sstub ));
384 if( !CV_IS_MAT( evects ))
385 CV_CALL( evects = cvGetMat( evects, &estub1 ));
387 if( !CV_IS_MAT( evals ))
388 CV_CALL( evals = cvGetMat( evals, &estub2 ));
390 if( src->cols != src->rows )
391 CV_ERROR( CV_StsUnmatchedSizes, "source is not quadratic matrix" );
393 if( !CV_ARE_SIZES_EQ( src, evects) )
394 CV_ERROR( CV_StsUnmatchedSizes, "eigenvectors matrix has inappropriate size" );
396 if( (evals->rows != src->rows || evals->cols != 1) &&
397 (evals->cols != src->rows || evals->rows != 1))
398 CV_ERROR( CV_StsBadSize, "eigenvalues vector has inappropriate size" );
400 if( !CV_ARE_TYPES_EQ( src, evects ) || !CV_ARE_TYPES_EQ( src, evals ))
401 CV_ERROR( CV_StsUnmatchedFormats,
402 "input matrix, eigenvalues and eigenvectors must have the same type" );
404 if( !CV_IS_MAT_CONT( src->type & evals->type & evects->type ))
405 CV_ERROR( CV_BadStep, "all the matrices must be continuous" );
407 if( CV_MAT_TYPE(src->type) == CV_32FC1 )
409 IPPI_CALL( icvJacobiEigens_32f( src->data.fl,
411 evals->data.fl, src->cols, (float)eps ));
414 else if( CV_MAT_TYPE(src->type) == CV_64FC1 )
416 IPPI_CALL( icvJacobiEigens_64d( src->data.db,
418 evals->data.db, src->cols, eps ));
422 CV_ERROR( CV_StsUnsupportedFormat, "Only 32fC1 and 64fC1 types are supported" );
425 CV_CHECK_NANS( evects );
426 CV_CHECK_NANS( evals );