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.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
48 static const int MAX_BLOCK_SIZE = 1024;
50 typedef CvStatus (CV_STDCALL * MathFunc)(const void* src, void* dst, int len);
52 #define ICV_MATH_BLOCK_SIZE 256
54 #define _CV_SQRT_MAGIC 0xbe6f0000
56 #define _CV_SQRT_MAGIC_DBL CV_BIG_UINT(0xbfcd460000000000)
58 #define _CV_ATAN_CF0 (-15.8131890796f)
59 #define _CV_ATAN_CF1 (61.0941945596f)
60 #define _CV_ATAN_CF2 0.f /*(-0.140500406322f)*/
62 static const float icvAtanTab[8] = { 0.f + _CV_ATAN_CF2, 90.f - _CV_ATAN_CF2,
63 180.f - _CV_ATAN_CF2, 90.f + _CV_ATAN_CF2,
64 360.f - _CV_ATAN_CF2, 270.f + _CV_ATAN_CF2,
65 180.f + _CV_ATAN_CF2, 270.f - _CV_ATAN_CF2
68 static const int icvAtanSign[8] =
69 { 0, 0x80000000, 0x80000000, 0, 0x80000000, 0, 0, 0x80000000 };
71 float fastAtan2( float y, float x )
73 double a, x2 = (double)x*x, y2 = (double)y*y;
76 a = (180./CV_PI)*x*y/(x2 + 0.28*y2 + DBL_EPSILON);
77 return (float)(x < 0 ? a + 180 : y >= 0 ? a : 360+a);
79 a = (180./CV_PI)*x*y/(y2 + 0.28*x2 + DBL_EPSILON);
80 return (float)(y >= 0 ? 90 - a : 270 - a);
83 static CvStatus CV_STDCALL FastAtan2_32f(const float *Y, const float *X, float *angle, int len, bool angleInDegrees=true )
85 if( !Y || !X || !angle || len < 0 )
86 return CV_BADFACTOR_ERR;
89 float scale = angleInDegrees ? (float)(180/CV_PI) : 1.f;
92 static const int CV_DECL_ALIGNED(16) iabsmask[] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff};
93 __m128 eps = _mm_set1_ps((float)DBL_EPSILON), absmask = _mm_load_ps((const float*)iabsmask);
94 __m128 _90 = _mm_set1_ps((float)(CV_PI*0.5)), _180 = _mm_set1_ps((float)CV_PI), _360 = _mm_set1_ps((float)(CV_PI*2));
95 __m128 zero = _mm_setzero_ps(), _0_28 = _mm_set1_ps(0.28f), scale4 = _mm_set1_ps(scale);
97 for( ; i <= len - 4; i += 4 )
99 __m128 x4 = _mm_loadu_ps(X + i), y4 = _mm_loadu_ps(Y + i);
100 __m128 xq4 = _mm_mul_ps(x4, x4), yq4 = _mm_mul_ps(y4, y4);
101 __m128 xly = _mm_cmplt_ps(xq4, yq4);
102 __m128 z4 = _mm_div_ps(_mm_mul_ps(x4, y4), _mm_add_ps(_mm_add_ps(_mm_max_ps(xq4, yq4),
103 _mm_mul_ps(_mm_min_ps(xq4, yq4), _0_28)), eps));
105 // a4 <- x < y ? 90 : 0;
106 __m128 a4 = _mm_and_ps(xly, _90);
107 // a4 <- (y < 0 ? 360 - a4 : a4) == ((x < y ? y < 0 ? 270 : 90) : (y < 0 ? 360 : 0))
108 __m128 mask = _mm_cmplt_ps(y4, zero);
109 a4 = _mm_or_ps(_mm_and_ps(_mm_sub_ps(_360, a4), mask), _mm_andnot_ps(mask, a4));
110 // a4 <- (x < 0 && !(x < y) ? 180 : a4)
111 mask = _mm_andnot_ps(xly, _mm_cmplt_ps(x4, zero));
112 a4 = _mm_or_ps(_mm_and_ps(_180, mask), _mm_andnot_ps(mask, a4));
114 // a4 <- (x < y ? a4 - z4 : a4 + z4)
115 a4 = _mm_mul_ps(_mm_add_ps(_mm_xor_ps(z4, _mm_andnot_ps(absmask, xly)), a4), scale4);
116 _mm_storeu_ps(angle + i, a4);
120 for( ; i < len; i++ )
122 float x = X[i], y = Y[i];
123 float a, x2 = x*x, y2 = y*y;
125 a = x*y/(x2 + 0.28f*y2 + (float)DBL_EPSILON) + (float)(x < 0 ? CV_PI : y >= 0 ? 0 : CV_PI*2);
127 a = (float)(y >= 0 ? CV_PI*0.5 : CV_PI*1.5) - x*y/(y2 + 0.28f*x2 + (float)DBL_EPSILON);
135 /* ************************************************************************** *\
136 Fast cube root by Ken Turkowski
137 (http://www.worldserver.com/turk/computergraphics/papers.html)
138 \* ************************************************************************** */
139 float cubeRoot( float value )
147 ix = v.i & 0x7fffffff;
148 s = v.i & 0x80000000;
149 ex = (ix >> 23) - 127;
151 shx -= shx >= 0 ? 3 : 0;
152 ex = (ex - shx) / 3; /* exponent of cube root */
153 v.i = (ix & ((1<<23)-1)) | ((shx + 127)<<23);
156 /* 0.125 <= fr < 1.0 */
157 /* Use quartic rational polynomial with error < 2^(-24) */
158 fr = (float)(((((45.2548339756803022511987494 * fr +
159 192.2798368355061050458134625) * fr +
160 119.1654824285581628956914143) * fr +
161 13.43250139086239872172837314) * fr +
162 0.1636161226585754240958355063)/
163 ((((14.80884093219134573786480845 * fr +
164 151.9714051044435648658557668) * fr +
165 168.5254414101568283957668343) * fr +
166 33.9905941350215598754191872) * fr +
169 /* fr *= 2^ex * sign */
172 v.i = (v.i + (ex << 23) + s) & (m.i*2 != 0 ? -1 : 0);
176 template<typename T> static CvStatus CV_STDCALL InvSqrt(const T* src, T* dst, int len)
178 for( int i = 0; i < len; i++ )
179 dst[i] = 1/std::sqrt(src[i]);
184 template<typename T> static CvStatus CV_STDCALL Sqrt(const T* src, T* dst, int len)
186 for( int i = 0; i < len; i++ )
187 dst[i] = std::sqrt(src[i]);
191 template<typename T> static CvStatus CV_STDCALL
192 Magnitude(const T* x, const T* y, T* mag, int len)
195 for( i = 0; i <= len - 4; i += 4 )
197 T x0 = x[i], y0 = y[i], x1 = x[i+1], y1 = y[i+1];
203 x0 = x[i+2], y0 = y[i+2];
204 x1 = x[i+3], y1 = y[i+3];
211 for( ; i < len; i++ )
213 T x0 = x[i], y0 = y[i];
214 mag[i] = x0*x0 + y0*y0;
216 Sqrt( mag, mag, len );
223 template<> CvStatus CV_STDCALL InvSqrt(const float* src, float* dst, int len)
226 __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f);
227 if( (((size_t)src|(size_t)dst) & 15) == 0 )
228 for( ; i <= len - 8; i += 8 )
230 __m128 t0 = _mm_load_ps(src + i), t1 = _mm_load_ps(src + i + 4);
231 __m128 h0 = _mm_mul_ps(t0, _0_5), h1 = _mm_mul_ps(t1, _0_5);
232 t0 = _mm_rsqrt_ps(t0); t1 = _mm_rsqrt_ps(t1);
233 t0 = _mm_mul_ps(t0, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t0,t0),h0)));
234 t1 = _mm_mul_ps(t1, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t1,t1),h1)));
235 _mm_store_ps(dst + i, t0); _mm_store_ps(dst + i + 4, t1);
238 for( ; i <= len - 8; i += 8 )
240 __m128 t0 = _mm_loadu_ps(src + i), t1 = _mm_loadu_ps(src + i + 4);
241 __m128 h0 = _mm_mul_ps(t0, _0_5), h1 = _mm_mul_ps(t1, _0_5);
242 t0 = _mm_rsqrt_ps(t0); t1 = _mm_rsqrt_ps(t1);
243 t0 = _mm_mul_ps(t0, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t0,t0),h0)));
244 t1 = _mm_mul_ps(t1, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t1,t1),h1)));
245 _mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1);
247 for( ; i < len; i++ )
248 dst[i] = 1/std::sqrt(src[i]);
252 template<> CvStatus CV_STDCALL Sqrt(const float* src, float* dst, int len)
255 if( (((size_t)src|(size_t)dst) & 15) == 0 )
256 for( ; i <= len - 8; i += 8 )
258 __m128 t0 = _mm_load_ps(src + i), t1 = _mm_load_ps(src + i + 4);
259 t0 = _mm_sqrt_ps(t0); t1 = _mm_sqrt_ps(t1);
260 _mm_store_ps(dst + i, t0); _mm_store_ps(dst + i + 4, t1);
263 for( ; i <= len - 8; i += 8 )
265 __m128 t0 = _mm_loadu_ps(src + i), t1 = _mm_loadu_ps(src + i + 4);
266 t0 = _mm_sqrt_ps(t0); t1 = _mm_sqrt_ps(t1);
267 _mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1);
269 for( ; i < len; i++ )
270 dst[i] = std::sqrt(src[i]);
274 template<> CvStatus CV_STDCALL Sqrt(const double* src, double* dst, int len)
277 if( (((size_t)src|(size_t)dst) & 15) == 0 )
278 for( ; i <= len - 4; i += 4 )
280 __m128d t0 = _mm_load_pd(src + i), t1 = _mm_load_pd(src + i + 2);
281 t0 = _mm_sqrt_pd(t0); t1 = _mm_sqrt_pd(t1);
282 _mm_store_pd(dst + i, t0); _mm_store_pd(dst + i + 2, t1);
285 for( ; i <= len - 4; i += 4 )
287 __m128d t0 = _mm_loadu_pd(src + i), t1 = _mm_loadu_pd(src + i + 2);
288 t0 = _mm_sqrt_pd(t0); t1 = _mm_sqrt_pd(t1);
289 _mm_storeu_pd(dst + i, t0); _mm_storeu_pd(dst + i + 2, t1);
291 for( ; i < len; i++ )
292 dst[i] = std::sqrt(src[i]);
296 template<> CvStatus CV_STDCALL
297 Magnitude(const float* x, const float* y, float* mag, int len)
300 for( ; i <= len - 8; i += 8 )
302 __m128 x0 = _mm_loadu_ps(x + i), x1 = _mm_loadu_ps(x + i + 4);
303 __m128 y0 = _mm_loadu_ps(y + i), y1 = _mm_loadu_ps(y + i + 4);
304 x0 = _mm_add_ps(_mm_mul_ps(x0, x0), _mm_mul_ps(y0, y0));
305 x1 = _mm_add_ps(_mm_mul_ps(x1, x1), _mm_mul_ps(y1, y1));
306 x0 = _mm_sqrt_ps(x0); x1 = _mm_sqrt_ps(x1);
307 _mm_storeu_ps(mag + i, x0); _mm_storeu_ps(mag + i + 4, x1);
309 for( ; i < len; i++ )
311 float x0 = x[i], y0 = y[i];
312 mag[i] = std::sqrt(x0*x0 + y0*y0);
318 static CvStatus CV_STDCALL Sqrt_32f(const float* src, float* dst, int len)
320 return Sqrt( src, dst, len );
323 static CvStatus CV_STDCALL InvSqrt_32f(const float* src, float* dst, int len)
325 return InvSqrt( src, dst, len );
328 static CvStatus CV_STDCALL Sqrt_64f(const double* src, double* dst, int len)
330 return Sqrt( src, dst, len );
333 static CvStatus CV_STDCALL InvSqrt_64f(const double* src, double* dst, int len)
335 return InvSqrt( src, dst, len );
339 /****************************************************************************************\
340 * Cartezian -> Polar *
341 \****************************************************************************************/
343 void magnitude( const Mat& X, const Mat& Y, Mat& Mag )
345 int type = X.type(), depth = X.depth(), cn = X.channels();
346 CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
347 Mag.create( X.size(), type );
349 Size size = getContinuousSize( X, Y, Mag, cn );
351 if( depth == CV_32F )
353 const float *x = (const float*)X.data, *y = (const float*)Y.data;
354 float *mag = (float*)Mag.data;
355 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
356 size_t mstep = Mag.step/sizeof(mag[0]);
358 for( ; size.height--; x += xstep, y += ystep, mag += mstep )
359 Magnitude( x, y, mag, size.width );
363 const double *x = (const double*)X.data, *y = (const double*)Y.data;
364 double *mag = (double*)Mag.data;
365 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
366 size_t mstep = Mag.step/sizeof(mag[0]);
368 for( ; size.height--; x += xstep, y += ystep, mag += mstep )
369 Magnitude( x, y, mag, size.width );
373 void phase( const Mat& X, const Mat& Y, Mat& Angle, bool angleInDegrees )
375 float buf[2][MAX_BLOCK_SIZE];
376 int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
378 CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
379 Angle.create( X.size(), type );
381 Size size = getContinuousSize( X, Y, Angle, cn );
383 if( depth == CV_32F )
385 const float *x = (const float*)X.data, *y = (const float*)Y.data;
386 float *angle = (float*)Angle.data;
387 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
388 size_t astep = Angle.step/sizeof(angle[0]);
390 for( ; size.height--; x += xstep, y += ystep, angle += astep )
391 FastAtan2_32f( y, x, angle, size.width, angleInDegrees );
395 const double *x = (const double*)X.data, *y = (const double*)Y.data;
396 double *angle = (double*)Angle.data;
397 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
398 size_t astep = Angle.step/sizeof(angle[0]);
400 for( ; size.height--; x += xstep, y += ystep, angle += astep )
402 for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
404 int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
405 for( j = 0; j < block_size; j++ )
407 buf[0][j] = (float)x[i + j];
408 buf[1][j] = (float)y[i + j];
410 FastAtan2_32f( buf[1], buf[0], buf[0], block_size, angleInDegrees );
411 for( j = 0; j < block_size; j++ )
412 angle[i + j] = buf[0][j];
418 void cartToPolar( const Mat& X, const Mat& Y, Mat& Mag, Mat& Angle, bool angleInDegrees )
420 float buf[2][MAX_BLOCK_SIZE];
421 int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
423 CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
424 Mag.create( X.size(), type );
425 Angle.create( X.size(), type );
427 Size size = getContinuousSize( X, Y, Mag, Angle, cn );
428 bool inplace = Mag.data == X.data || Mag.data == Y.data;
430 if( depth == CV_32F )
432 const float *x = (const float*)X.data, *y = (const float*)Y.data;
433 float *mag = (float*)Mag.data, *angle = (float*)Angle.data;
434 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
435 size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
437 for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
439 for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
441 int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
442 Magnitude( x + i, y + i, inplace ? buf[0] : mag + i, block_size );
443 FastAtan2_32f( y + i, x + i, angle + i, block_size, angleInDegrees );
445 for( j = 0; j < block_size; j++ )
446 mag[i + j] = buf[0][j];
452 const double *x = (const double*)X.data, *y = (const double*)Y.data;
453 double *mag = (double*)Mag.data, *angle = (double*)Angle.data;
454 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
455 size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
457 for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
459 for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
461 int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
462 for( j = 0; j < block_size; j++ )
464 buf[0][j] = (float)x[i + j];
465 buf[1][j] = (float)y[i + j];
467 FastAtan2_32f( buf[1], buf[0], buf[0], block_size, angleInDegrees );
468 Magnitude( x + i, y + i, mag + i, block_size );
469 for( j = 0; j < block_size; j++ )
470 angle[i + j] = buf[0][j];
477 /****************************************************************************************\
478 * Polar -> Cartezian *
479 \****************************************************************************************/
481 static CvStatus CV_STDCALL
482 SinCos_32f( const float *angle,float *sinval, float* cosval,
483 int len, int angle_in_degrees )
487 static const double sin_table[] =
489 0.00000000000000000000, 0.09801714032956060400,
490 0.19509032201612825000, 0.29028467725446233000,
491 0.38268343236508978000, 0.47139673682599764000,
492 0.55557023301960218000, 0.63439328416364549000,
493 0.70710678118654746000, 0.77301045336273699000,
494 0.83146961230254524000, 0.88192126434835494000,
495 0.92387953251128674000, 0.95694033573220894000,
496 0.98078528040323043000, 0.99518472667219682000,
497 1.00000000000000000000, 0.99518472667219693000,
498 0.98078528040323043000, 0.95694033573220894000,
499 0.92387953251128674000, 0.88192126434835505000,
500 0.83146961230254546000, 0.77301045336273710000,
501 0.70710678118654757000, 0.63439328416364549000,
502 0.55557023301960218000, 0.47139673682599786000,
503 0.38268343236508989000, 0.29028467725446239000,
504 0.19509032201612861000, 0.09801714032956082600,
505 0.00000000000000012246, -0.09801714032956059000,
506 -0.19509032201612836000, -0.29028467725446211000,
507 -0.38268343236508967000, -0.47139673682599764000,
508 -0.55557023301960196000, -0.63439328416364527000,
509 -0.70710678118654746000, -0.77301045336273666000,
510 -0.83146961230254524000, -0.88192126434835494000,
511 -0.92387953251128652000, -0.95694033573220882000,
512 -0.98078528040323032000, -0.99518472667219693000,
513 -1.00000000000000000000, -0.99518472667219693000,
514 -0.98078528040323043000, -0.95694033573220894000,
515 -0.92387953251128663000, -0.88192126434835505000,
516 -0.83146961230254546000, -0.77301045336273688000,
517 -0.70710678118654768000, -0.63439328416364593000,
518 -0.55557023301960218000, -0.47139673682599792000,
519 -0.38268343236509039000, -0.29028467725446250000,
520 -0.19509032201612872000, -0.09801714032956050600,
523 static const double k2 = (2*CV_PI)/N;
525 static const double sin_a0 = -0.166630293345647*k2*k2*k2;
526 static const double sin_a2 = k2;
528 static const double cos_a0 = -0.499818138450326*k2*k2;
529 /*static const double cos_a2 = 1;*/
534 if( !angle_in_degrees )
539 for( i = 0; i < len; i++ )
541 double t = angle[i]*k1;
544 int sin_idx = it & (N - 1);
545 int cos_idx = (N/4 - sin_idx) & (N - 1);
547 double sin_b = (sin_a0*t*t + sin_a2)*t;
548 double cos_b = cos_a0*t*t + 1;
550 double sin_a = sin_table[sin_idx];
551 double cos_a = sin_table[cos_idx];
553 double sin_val = sin_a*cos_b + cos_a*sin_b;
554 double cos_val = cos_a*cos_b - sin_a*sin_b;
556 sinval[i] = (float)sin_val;
557 cosval[i] = (float)cos_val;
564 void polarToCart( const Mat& Mag, const Mat& Angle, Mat& X, Mat& Y, bool angleInDegrees )
566 int i, j, type = Angle.type(), depth = Angle.depth();
569 CV_Assert( depth == CV_32F || depth == CV_64F );
570 X.create( Angle.size(), type );
571 Y.create( Angle.size(), type );
575 CV_Assert( Mag.size() == Angle.size() && Mag.type() == Angle.type() );
576 size = getContinuousSize( Mag, Angle, X, Y, Angle.channels() );
579 size = getContinuousSize( Angle, X, Y, Angle.channels() );
581 if( depth == CV_32F )
583 float *x = (float*)X.data, *y = (float*)Y.data;
584 const float *mag = (const float*)Mag.data, *angle = (const float*)Angle.data;
585 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
586 size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
588 for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
590 for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
592 int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
593 SinCos_32f( angle + i, y + i, x + i, block_size, angleInDegrees );
594 for( j = 0; j < block_size; j++ )
596 float m = mag ? mag[i + j] : 1.f;
597 float t0 = x[i + j]*m, t1 = y[i + j]*m;
598 x[i + j] = t0; y[i + j] = t1;
605 double *x = (double*)X.data, *y = (double*)Y.data;
606 const double *mag = (const double*)Mag.data, *angle = (const double*)Angle.data;
607 size_t xstep = X.step/sizeof(x[0]), ystep = Y.step/sizeof(y[0]);
608 size_t mstep = Mag.step/sizeof(mag[0]), astep = Angle.step/sizeof(angle[0]);
609 double ascale = angleInDegrees ? CV_PI/180. : 1;
611 for( ; size.height--; x += xstep, y += ystep, mag += mstep, angle += astep )
613 for( j = 0; j < size.width; j++ )
615 double alpha = angle[j]*ascale, m = mag ? mag[j] : 1.;
616 double a = cos(alpha), b = sin(alpha);
617 x[j] = m*a; y[j] = m*b;
623 /****************************************************************************************\
625 \****************************************************************************************/
630 #if ( defined( WORDS_BIGENDIAN ) && !defined( OPENCV_UNIVERSAL_BUILD ) ) || defined( __BIG_ENDIAN__ )
644 #define EXPTAB_SCALE 6
645 #define EXPTAB_MASK ((1 << EXPTAB_SCALE) - 1)
647 #define EXPPOLY_32F_A0 .9670371139572337719125840413672004409288e-2
649 static const double expTab[] = {
650 1.0 * EXPPOLY_32F_A0,
651 1.0108892860517004600204097905619 * EXPPOLY_32F_A0,
652 1.0218971486541166782344801347833 * EXPPOLY_32F_A0,
653 1.0330248790212284225001082839705 * EXPPOLY_32F_A0,
654 1.0442737824274138403219664787399 * EXPPOLY_32F_A0,
655 1.0556451783605571588083413251529 * EXPPOLY_32F_A0,
656 1.0671404006768236181695211209928 * EXPPOLY_32F_A0,
657 1.0787607977571197937406800374385 * EXPPOLY_32F_A0,
658 1.0905077326652576592070106557607 * EXPPOLY_32F_A0,
659 1.1023825833078409435564142094256 * EXPPOLY_32F_A0,
660 1.1143867425958925363088129569196 * EXPPOLY_32F_A0,
661 1.126521618608241899794798643787 * EXPPOLY_32F_A0,
662 1.1387886347566916537038302838415 * EXPPOLY_32F_A0,
663 1.151189229952982705817759635202 * EXPPOLY_32F_A0,
664 1.1637248587775775138135735990922 * EXPPOLY_32F_A0,
665 1.1763969916502812762846457284838 * EXPPOLY_32F_A0,
666 1.1892071150027210667174999705605 * EXPPOLY_32F_A0,
667 1.2021567314527031420963969574978 * EXPPOLY_32F_A0,
668 1.2152473599804688781165202513388 * EXPPOLY_32F_A0,
669 1.2284805361068700056940089577928 * EXPPOLY_32F_A0,
670 1.2418578120734840485936774687266 * EXPPOLY_32F_A0,
671 1.2553807570246910895793906574423 * EXPPOLY_32F_A0,
672 1.2690509571917332225544190810323 * EXPPOLY_32F_A0,
673 1.2828700160787782807266697810215 * EXPPOLY_32F_A0,
674 1.2968395546510096659337541177925 * EXPPOLY_32F_A0,
675 1.3109612115247643419229917863308 * EXPPOLY_32F_A0,
676 1.3252366431597412946295370954987 * EXPPOLY_32F_A0,
677 1.3396675240533030053600306697244 * EXPPOLY_32F_A0,
678 1.3542555469368927282980147401407 * EXPPOLY_32F_A0,
679 1.3690024229745906119296011329822 * EXPPOLY_32F_A0,
680 1.3839098819638319548726595272652 * EXPPOLY_32F_A0,
681 1.3989796725383111402095281367152 * EXPPOLY_32F_A0,
682 1.4142135623730950488016887242097 * EXPPOLY_32F_A0,
683 1.4296133383919700112350657782751 * EXPPOLY_32F_A0,
684 1.4451808069770466200370062414717 * EXPPOLY_32F_A0,
685 1.4609177941806469886513028903106 * EXPPOLY_32F_A0,
686 1.476826145939499311386907480374 * EXPPOLY_32F_A0,
687 1.4929077282912648492006435314867 * EXPPOLY_32F_A0,
688 1.5091644275934227397660195510332 * EXPPOLY_32F_A0,
689 1.5255981507445383068512536895169 * EXPPOLY_32F_A0,
690 1.5422108254079408236122918620907 * EXPPOLY_32F_A0,
691 1.5590044002378369670337280894749 * EXPPOLY_32F_A0,
692 1.5759808451078864864552701601819 * EXPPOLY_32F_A0,
693 1.5931421513422668979372486431191 * EXPPOLY_32F_A0,
694 1.6104903319492543081795206673574 * EXPPOLY_32F_A0,
695 1.628027421857347766848218522014 * EXPPOLY_32F_A0,
696 1.6457554781539648445187567247258 * EXPPOLY_32F_A0,
697 1.6636765803267364350463364569764 * EXPPOLY_32F_A0,
698 1.6817928305074290860622509524664 * EXPPOLY_32F_A0,
699 1.7001063537185234695013625734975 * EXPPOLY_32F_A0,
700 1.7186192981224779156293443764563 * EXPPOLY_32F_A0,
701 1.7373338352737062489942020818722 * EXPPOLY_32F_A0,
702 1.7562521603732994831121606193753 * EXPPOLY_32F_A0,
703 1.7753764925265212525505592001993 * EXPPOLY_32F_A0,
704 1.7947090750031071864277032421278 * EXPPOLY_32F_A0,
705 1.8142521755003987562498346003623 * EXPPOLY_32F_A0,
706 1.8340080864093424634870831895883 * EXPPOLY_32F_A0,
707 1.8539791250833855683924530703377 * EXPPOLY_32F_A0,
708 1.8741676341102999013299989499544 * EXPPOLY_32F_A0,
709 1.8945759815869656413402186534269 * EXPPOLY_32F_A0,
710 1.9152065613971472938726112702958 * EXPPOLY_32F_A0,
711 1.9360617934922944505980559045667 * EXPPOLY_32F_A0,
712 1.9571441241754002690183222516269 * EXPPOLY_32F_A0,
713 1.9784560263879509682582499181312 * EXPPOLY_32F_A0,
716 static const double exp_prescale = 1.4426950408889634073599246810019 * (1 << EXPTAB_SCALE);
717 static const double exp_postscale = 1./(1 << EXPTAB_SCALE);
718 static const double exp_max_val = 3000.*(1 << EXPTAB_SCALE); // log10(DBL_MAX) < 3000
720 static CvStatus CV_STDCALL Exp_32f( const float *_x, float *y, int n )
723 EXPPOLY_32F_A4 = 1.000000000000002438532970795181890933776 / EXPPOLY_32F_A0,
724 EXPPOLY_32F_A3 = .6931471805521448196800669615864773144641 / EXPPOLY_32F_A0,
725 EXPPOLY_32F_A2 = .2402265109513301490103372422686535526573 / EXPPOLY_32F_A0,
726 EXPPOLY_32F_A1 = .5550339366753125211915322047004666939128e-1 / EXPPOLY_32F_A0;
730 (((((x) + EXPPOLY_32F_A1)*(x) + EXPPOLY_32F_A2)*(x) + EXPPOLY_32F_A3)*(x) + EXPPOLY_32F_A4)
734 const Cv32suf* x = (const Cv32suf*)_x;
737 return CV_NULLPTR_ERR;
739 return CV_BADSIZE_ERR;
741 buf[0].i.lo = buf[1].i.lo = buf[2].i.lo = buf[3].i.lo = 0;
743 for( ; i <= n - 4; i += 4 )
745 double x0 = x[i].f * exp_prescale;
746 double x1 = x[i + 1].f * exp_prescale;
747 double x2 = x[i + 2].f * exp_prescale;
748 double x3 = x[i + 3].f * exp_prescale;
749 int val0, val1, val2, val3, t;
751 if( ((x[i].i >> 23) & 255) > 127 + 10 )
752 x0 = x[i].i < 0 ? -exp_max_val : exp_max_val;
754 if( ((x[i+1].i >> 23) & 255) > 127 + 10 )
755 x1 = x[i+1].i < 0 ? -exp_max_val : exp_max_val;
757 if( ((x[i+2].i >> 23) & 255) > 127 + 10 )
758 x2 = x[i+2].i < 0 ? -exp_max_val : exp_max_val;
760 if( ((x[i+3].i >> 23) & 255) > 127 + 10 )
761 x3 = x[i+3].i < 0 ? -exp_max_val : exp_max_val;
768 x0 = (x0 - val0)*exp_postscale;
769 x1 = (x1 - val1)*exp_postscale;
770 x2 = (x2 - val2)*exp_postscale;
771 x3 = (x3 - val3)*exp_postscale;
773 t = (val0 >> EXPTAB_SCALE) + 1023;
774 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
775 buf[0].i.hi = t << 20;
777 t = (val1 >> EXPTAB_SCALE) + 1023;
778 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
779 buf[1].i.hi = t << 20;
781 t = (val2 >> EXPTAB_SCALE) + 1023;
782 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
783 buf[2].i.hi = t << 20;
785 t = (val3 >> EXPTAB_SCALE) + 1023;
786 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
787 buf[3].i.hi = t << 20;
789 x0 = buf[0].d * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 );
790 x1 = buf[1].d * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 );
793 y[i + 1] = (float)x1;
795 x2 = buf[2].d * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 );
796 x3 = buf[3].d * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 );
798 y[i + 2] = (float)x2;
799 y[i + 3] = (float)x3;
804 double x0 = x[i].f * exp_prescale;
807 if( ((x[i].i >> 23) & 255) > 127 + 10 )
808 x0 = x[i].i < 0 ? -exp_max_val : exp_max_val;
811 t = (val0 >> EXPTAB_SCALE) + 1023;
812 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
814 buf[0].i.hi = t << 20;
815 x0 = (x0 - val0)*exp_postscale;
817 y[i] = (float)(buf[0].d * expTab[val0 & EXPTAB_MASK] * EXPPOLY(x0));
824 static CvStatus CV_STDCALL Exp_64f( const double *_x, double *y, int n )
827 A5 = .99999999999999999998285227504999 / EXPPOLY_32F_A0,
828 A4 = .69314718055994546743029643825322 / EXPPOLY_32F_A0,
829 A3 = .24022650695886477918181338054308 / EXPPOLY_32F_A0,
830 A2 = .55504108793649567998466049042729e-1 / EXPPOLY_32F_A0,
831 A1 = .96180973140732918010002372686186e-2 / EXPPOLY_32F_A0,
832 A0 = .13369713757180123244806654839424e-2 / EXPPOLY_32F_A0;
835 #define EXPPOLY(x) (((((A0*(x) + A1)*(x) + A2)*(x) + A3)*(x) + A4)*(x) + A5)
839 const Cv64suf* x = (const Cv64suf*)_x;
842 return CV_NULLPTR_ERR;
844 return CV_BADSIZE_ERR;
846 buf[0].i.lo = buf[1].i.lo = buf[2].i.lo = buf[3].i.lo = 0;
848 for( ; i <= n - 4; i += 4 )
850 double x0 = x[i].f * exp_prescale;
851 double x1 = x[i + 1].f * exp_prescale;
852 double x2 = x[i + 2].f * exp_prescale;
853 double x3 = x[i + 3].f * exp_prescale;
855 double y0, y1, y2, y3;
856 int val0, val1, val2, val3, t;
858 t = (int)(x[i].i >> 52);
859 if( (t & 2047) > 1023 + 10 )
860 x0 = t < 0 ? -exp_max_val : exp_max_val;
862 t = (int)(x[i+1].i >> 52);
863 if( (t & 2047) > 1023 + 10 )
864 x1 = t < 0 ? -exp_max_val : exp_max_val;
866 t = (int)(x[i+2].i >> 52);
867 if( (t & 2047) > 1023 + 10 )
868 x2 = t < 0 ? -exp_max_val : exp_max_val;
870 t = (int)(x[i+3].i >> 52);
871 if( (t & 2047) > 1023 + 10 )
872 x3 = t < 0 ? -exp_max_val : exp_max_val;
879 x0 = (x0 - val0)*exp_postscale;
880 x1 = (x1 - val1)*exp_postscale;
881 x2 = (x2 - val2)*exp_postscale;
882 x3 = (x3 - val3)*exp_postscale;
884 t = (val0 >> EXPTAB_SCALE) + 1023;
885 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
886 buf[0].i.hi = t << 20;
888 t = (val1 >> EXPTAB_SCALE) + 1023;
889 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
890 buf[1].i.hi = t << 20;
892 t = (val2 >> EXPTAB_SCALE) + 1023;
893 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
894 buf[2].i.hi = t << 20;
896 t = (val3 >> EXPTAB_SCALE) + 1023;
897 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
898 buf[3].i.hi = t << 20;
900 y0 = buf[0].d * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 );
901 y1 = buf[1].d * expTab[val1 & EXPTAB_MASK] * EXPPOLY( x1 );
906 y2 = buf[2].d * expTab[val2 & EXPTAB_MASK] * EXPPOLY( x2 );
907 y3 = buf[3].d * expTab[val3 & EXPTAB_MASK] * EXPPOLY( x3 );
915 double x0 = x[i].f * exp_prescale;
918 t = (int)(x[i].i >> 52);
919 if( (t & 2047) > 1023 + 10 )
920 x0 = t < 0 ? -exp_max_val : exp_max_val;
923 t = (val0 >> EXPTAB_SCALE) + 1023;
924 t = (t | ((t < 2047) - 1)) & (((t < 0) - 1) & 2047);
926 buf[0].i.hi = t << 20;
927 x0 = (x0 - val0)*exp_postscale;
929 y[i] = buf[0].d * expTab[val0 & EXPTAB_MASK] * EXPPOLY( x0 );
937 #undef EXPPOLY_32F_A0
941 #define Exp_32f ippsExp_32f_A21
942 #define Exp_64f ippsExp_64f_A50
946 void exp( const Mat& src, Mat& dst )
948 int depth = src.depth();
949 dst.create( src.size(), src.type() );
950 Size size = getContinuousSize( src, dst, src.channels() );
952 MathFunc func = depth == CV_32F ? (MathFunc)Exp_32f : depth == CV_64F ? (MathFunc)Exp_64f : 0;
953 CV_Assert(func != 0);
955 for( int y = 0; y < size.height; y++ )
956 func( src.data + src.step*y, dst.data + dst.step*y, size.width );
960 /****************************************************************************************\
962 \****************************************************************************************/
966 #define LOGTAB_SCALE 8
967 #define LOGTAB_MASK ((1 << LOGTAB_SCALE) - 1)
968 #define LOGTAB_MASK2 ((1 << (20 - LOGTAB_SCALE)) - 1)
969 #define LOGTAB_MASK2_32F ((1 << (23 - LOGTAB_SCALE)) - 1)
971 static const double icvLogTab[] = {
972 0.0000000000000000000000000000000000000000, 1.000000000000000000000000000000000000000,
973 .00389864041565732288852075271279318258166, .9961089494163424124513618677042801556420,
974 .00778214044205494809292034119607706088573, .9922480620155038759689922480620155038760,
975 .01165061721997527263705585198749759001657, .9884169884169884169884169884169884169884,
976 .01550418653596525274396267235488267033361, .9846153846153846153846153846153846153846,
977 .01934296284313093139406447562578250654042, .9808429118773946360153256704980842911877,
978 .02316705928153437593630670221500622574241, .9770992366412213740458015267175572519084,
979 .02697658769820207233514075539915211265906, .9733840304182509505703422053231939163498,
980 .03077165866675368732785500469617545604706, .9696969696969696969696969696969696969697,
981 .03455238150665972812758397481047722976656, .9660377358490566037735849056603773584906,
982 .03831886430213659461285757856785494368522, .9624060150375939849624060150375939849624,
983 .04207121392068705056921373852674150839447, .9588014981273408239700374531835205992509,
984 .04580953603129420126371940114040626212953, .9552238805970149253731343283582089552239,
985 .04953393512227662748292900118940451648088, .9516728624535315985130111524163568773234,
986 .05324451451881227759255210685296333394944, .9481481481481481481481481481481481481481,
987 .05694137640013842427411105973078520037234, .9446494464944649446494464944649446494465,
988 .06062462181643483993820353816772694699466, .9411764705882352941176470588235294117647,
989 .06429435070539725460836422143984236754475, .9377289377289377289377289377289377289377,
990 .06795066190850773679699159401934593915938, .9343065693430656934306569343065693430657,
991 .07159365318700880442825962290953611955044, .9309090909090909090909090909090909090909,
992 .07522342123758751775142172846244648098944, .9275362318840579710144927536231884057971,
993 .07884006170777602129362549021607264876369, .9241877256317689530685920577617328519856,
994 .08244366921107458556772229485432035289706, .9208633093525179856115107913669064748201,
995 .08603433734180314373940490213499288074675, .9175627240143369175627240143369175627240,
996 .08961215868968712416897659522874164395031, .9142857142857142857142857142857142857143,
997 .09317722485418328259854092721070628613231, .9110320284697508896797153024911032028470,
998 .09672962645855109897752299730200320482256, .9078014184397163120567375886524822695035,
999 .10026945316367513738597949668474029749630, .9045936395759717314487632508833922261484,
1000 .10379679368164355934833764649738441221420, .9014084507042253521126760563380281690141,
1001 .10731173578908805021914218968959175981580, .8982456140350877192982456140350877192982,
1002 .11081436634029011301105782649756292812530, .8951048951048951048951048951048951048951,
1003 .11430477128005862852422325204315711744130, .8919860627177700348432055749128919860627,
1004 .11778303565638344185817487641543266363440, .8888888888888888888888888888888888888889,
1005 .12124924363286967987640707633545389398930, .8858131487889273356401384083044982698962,
1006 .12470347850095722663787967121606925502420, .8827586206896551724137931034482758620690,
1007 .12814582269193003360996385708858724683530, .8797250859106529209621993127147766323024,
1008 .13157635778871926146571524895989568904040, .8767123287671232876712328767123287671233,
1009 .13499516453750481925766280255629681050780, .8737201365187713310580204778156996587031,
1010 .13840232285911913123754857224412262439730, .8707482993197278911564625850340136054422,
1011 .14179791186025733629172407290752744302150, .8677966101694915254237288135593220338983,
1012 .14518200984449788903951628071808954700830, .8648648648648648648648648648648648648649,
1013 .14855469432313711530824207329715136438610, .8619528619528619528619528619528619528620,
1014 .15191604202584196858794030049466527998450, .8590604026845637583892617449664429530201,
1015 .15526612891112392955683674244937719777230, .8561872909698996655518394648829431438127,
1016 .15860503017663857283636730244325008243330, .8533333333333333333333333333333333333333,
1017 .16193282026931324346641360989451641216880, .8504983388704318936877076411960132890365,
1018 .16524957289530714521497145597095368430010, .8476821192052980132450331125827814569536,
1019 .16855536102980664403538924034364754334090, .8448844884488448844884488448844884488449,
1020 .17185025692665920060697715143760433420540, .8421052631578947368421052631578947368421,
1021 .17513433212784912385018287750426679849630, .8393442622950819672131147540983606557377,
1022 .17840765747281828179637841458315961062910, .8366013071895424836601307189542483660131,
1023 .18167030310763465639212199675966985523700, .8338762214983713355048859934853420195440,
1024 .18492233849401198964024217730184318497780, .8311688311688311688311688311688311688312,
1025 .18816383241818296356839823602058459073300, .8284789644012944983818770226537216828479,
1026 .19139485299962943898322009772527962923050, .8258064516129032258064516129032258064516,
1027 .19461546769967164038916962454095482826240, .8231511254019292604501607717041800643087,
1028 .19782574332991986754137769821682013571260, .8205128205128205128205128205128205128205,
1029 .20102574606059073203390141770796617493040, .8178913738019169329073482428115015974441,
1030 .20421554142869088876999228432396193966280, .8152866242038216560509554140127388535032,
1031 .20739519434607056602715147164417430758480, .8126984126984126984126984126984126984127,
1032 .21056476910734961416338251183333341032260, .8101265822784810126582278481012658227848,
1033 .21372432939771812687723695489694364368910, .8075709779179810725552050473186119873817,
1034 .21687393830061435506806333251006435602900, .8050314465408805031446540880503144654088,
1035 .22001365830528207823135744547471404075630, .8025078369905956112852664576802507836991,
1036 .22314355131420973710199007200571941211830, .8000000000000000000000000000000000000000,
1037 .22626367865045338145790765338460914790630, .7975077881619937694704049844236760124611,
1038 .22937410106484582006380890106811420992010, .7950310559006211180124223602484472049689,
1039 .23247487874309405442296849741978803649550, .7925696594427244582043343653250773993808,
1040 .23556607131276688371634975283086532726890, .7901234567901234567901234567901234567901,
1041 .23864773785017498464178231643018079921600, .7876923076923076923076923076923076923077,
1042 .24171993688714515924331749374687206000090, .7852760736196319018404907975460122699387,
1043 .24478272641769091566565919038112042471760, .7828746177370030581039755351681957186544,
1044 .24783616390458124145723672882013488560910, .7804878048780487804878048780487804878049,
1045 .25088030628580937353433455427875742316250, .7781155015197568389057750759878419452888,
1046 .25391520998096339667426946107298135757450, .7757575757575757575757575757575757575758,
1047 .25694093089750041913887912414793390780680, .7734138972809667673716012084592145015106,
1048 .25995752443692604627401010475296061486000, .7710843373493975903614457831325301204819,
1049 .26296504550088134477547896494797896593800, .7687687687687687687687687687687687687688,
1050 .26596354849713793599974565040611196309330, .7664670658682634730538922155688622754491,
1051 .26895308734550393836570947314612567424780, .7641791044776119402985074626865671641791,
1052 .27193371548364175804834985683555714786050, .7619047619047619047619047619047619047619,
1053 .27490548587279922676529508862586226314300, .7596439169139465875370919881305637982196,
1054 .27786845100345625159121709657483734190480, .7573964497041420118343195266272189349112,
1055 .28082266290088775395616949026589281857030, .7551622418879056047197640117994100294985,
1056 .28376817313064456316240580235898960381750, .7529411764705882352941176470588235294118,
1057 .28670503280395426282112225635501090437180, .7507331378299120234604105571847507331378,
1058 .28963329258304265634293983566749375313530, .7485380116959064327485380116959064327485,
1059 .29255300268637740579436012922087684273730, .7463556851311953352769679300291545189504,
1060 .29546421289383584252163927885703742504130, .7441860465116279069767441860465116279070,
1061 .29836697255179722709783618483925238251680, .7420289855072463768115942028985507246377,
1062 .30126133057816173455023545102449133992200, .7398843930635838150289017341040462427746,
1063 .30414733546729666446850615102448500692850, .7377521613832853025936599423631123919308,
1064 .30702503529491181888388950937951449304830, .7356321839080459770114942528735632183908,
1065 .30989447772286465854207904158101882785550, .7335243553008595988538681948424068767908,
1066 .31275571000389684739317885942000430077330, .7314285714285714285714285714285714285714,
1067 .31560877898630329552176476681779604405180, .7293447293447293447293447293447293447293,
1068 .31845373111853458869546784626436419785030, .7272727272727272727272727272727272727273,
1069 .32129061245373424782201254856772720813750, .7252124645892351274787535410764872521246,
1070 .32411946865421192853773391107097268104550, .7231638418079096045197740112994350282486,
1071 .32694034499585328257253991068864706903700, .7211267605633802816901408450704225352113,
1072 .32975328637246797969240219572384376078850, .7191011235955056179775280898876404494382,
1073 .33255833730007655635318997155991382896900, .7170868347338935574229691876750700280112,
1074 .33535554192113781191153520921943709254280, .7150837988826815642458100558659217877095,
1075 .33814494400871636381467055798566434532400, .7130919220055710306406685236768802228412,
1076 .34092658697059319283795275623560883104800, .7111111111111111111111111111111111111111,
1077 .34370051385331840121395430287520866841080, .7091412742382271468144044321329639889197,
1078 .34646676734620857063262633346312213689100, .7071823204419889502762430939226519337017,
1079 .34922538978528827602332285096053965389730, .7052341597796143250688705234159779614325,
1080 .35197642315717814209818925519357435405250, .7032967032967032967032967032967032967033,
1081 .35471990910292899856770532096561510115850, .7013698630136986301369863013698630136986,
1082 .35745588892180374385176833129662554711100, .6994535519125683060109289617486338797814,
1083 .36018440357500774995358483465679455548530, .6975476839237057220708446866485013623978,
1084 .36290549368936841911903457003063522279280, .6956521739130434782608695652173913043478,
1085 .36561919956096466943762379742111079394830, .6937669376693766937669376693766937669377,
1086 .36832556115870762614150635272380895912650, .6918918918918918918918918918918918918919,
1087 .37102461812787262962487488948681857436900, .6900269541778975741239892183288409703504,
1088 .37371640979358405898480555151763837784530, .6881720430107526881720430107526881720430,
1089 .37640097516425302659470730759494472295050, .6863270777479892761394101876675603217158,
1090 .37907835293496944251145919224654790014030, .6844919786096256684491978609625668449198,
1091 .38174858149084833769393299007788300514230, .6826666666666666666666666666666666666667,
1092 .38441169891033200034513583887019194662580, .6808510638297872340425531914893617021277,
1093 .38706774296844825844488013899535872042180, .6790450928381962864721485411140583554377,
1094 .38971675114002518602873692543653305619950, .6772486772486772486772486772486772486772,
1095 .39235876060286384303665840889152605086580, .6754617414248021108179419525065963060686,
1096 .39499380824086893770896722344332374632350, .6736842105263157894736842105263157894737,
1097 .39762193064713846624158577469643205404280, .6719160104986876640419947506561679790026,
1098 .40024316412701266276741307592601515352730, .6701570680628272251308900523560209424084,
1099 .40285754470108348090917615991202183067800, .6684073107049608355091383812010443864230,
1100 .40546510810816432934799991016916465014230, .6666666666666666666666666666666666666667,
1101 .40806588980822172674223224930756259709600, .6649350649350649350649350649350649350649,
1102 .41065992498526837639616360320360399782650, .6632124352331606217616580310880829015544,
1103 .41324724855021932601317757871584035456180, .6614987080103359173126614987080103359173,
1104 .41582789514371093497757669865677598863850, .6597938144329896907216494845360824742268,
1105 .41840189913888381489925905043492093682300, .6580976863753213367609254498714652956298,
1106 .42096929464412963239894338585145305842150, .6564102564102564102564102564102564102564,
1107 .42353011550580327293502591601281892508280, .6547314578005115089514066496163682864450,
1108 .42608439531090003260516141381231136620050, .6530612244897959183673469387755102040816,
1109 .42863216738969872610098832410585600882780, .6513994910941475826972010178117048346056,
1110 .43117346481837132143866142541810404509300, .6497461928934010152284263959390862944162,
1111 .43370832042155937902094819946796633303180, .6481012658227848101265822784810126582278,
1112 .43623676677491801667585491486534010618930, .6464646464646464646464646464646464646465,
1113 .43875883620762790027214350629947148263450, .6448362720403022670025188916876574307305,
1114 .44127456080487520440058801796112675219780, .6432160804020100502512562814070351758794,
1115 .44378397241030093089975139264424797147500, .6416040100250626566416040100250626566416,
1116 .44628710262841947420398014401143882423650, .6400000000000000000000000000000000000000,
1117 .44878398282700665555822183705458883196130, .6384039900249376558603491271820448877805,
1118 .45127464413945855836729492693848442286250, .6368159203980099502487562189054726368159,
1119 .45375911746712049854579618113348260521900, .6352357320099255583126550868486352357320,
1120 .45623743348158757315857769754074979573500, .6336633663366336633663366336633663366337,
1121 .45870962262697662081833982483658473938700, .6320987654320987654320987654320987654321,
1122 .46117571512217014895185229761409573256980, .6305418719211822660098522167487684729064,
1123 .46363574096303250549055974261136725544930, .6289926289926289926289926289926289926290,
1124 .46608972992459918316399125615134835243230, .6274509803921568627450980392156862745098,
1125 .46853771156323925639597405279346276074650, .6259168704156479217603911980440097799511,
1126 .47097971521879100631480241645476780831830, .6243902439024390243902439024390243902439,
1127 .47341577001667212165614273544633761048330, .6228710462287104622871046228710462287105,
1128 .47584590486996386493601107758877333253630, .6213592233009708737864077669902912621359,
1129 .47827014848147025860569669930555392056700, .6198547215496368038740920096852300242131,
1130 .48068852934575190261057286988943815231330, .6183574879227053140096618357487922705314,
1131 .48310107575113581113157579238759353756900, .6168674698795180722891566265060240963855,
1132 .48550781578170076890899053978500887751580, .6153846153846153846153846153846153846154,
1133 .48790877731923892879351001283794175833480, .6139088729016786570743405275779376498801,
1134 .49030398804519381705802061333088204264650, .6124401913875598086124401913875598086124,
1135 .49269347544257524607047571407747454941280, .6109785202863961813842482100238663484487,
1136 .49507726679785146739476431321236304938800, .6095238095238095238095238095238095238095,
1137 .49745538920281889838648226032091770321130, .6080760095011876484560570071258907363420,
1138 .49982786955644931126130359189119189977650, .6066350710900473933649289099526066350711,
1139 .50219473456671548383667413872899487614650, .6052009456264775413711583924349881796690,
1140 .50455601075239520092452494282042607665050, .6037735849056603773584905660377358490566,
1141 .50691172444485432801997148999362252652650, .6023529411764705882352941176470588235294,
1142 .50926190178980790257412536448100581765150, .6009389671361502347417840375586854460094,
1143 .51160656874906207391973111953120678663250, .5995316159250585480093676814988290398126,
1144 .51394575110223428282552049495279788970950, .5981308411214953271028037383177570093458,
1145 .51627947444845445623684554448118433356300, .5967365967365967365967365967365967365967,
1146 .51860776420804555186805373523384332656850, .5953488372093023255813953488372093023256,
1147 .52093064562418522900344441950437612831600, .5939675174013921113689095127610208816705,
1148 .52324814376454775732838697877014055848100, .5925925925925925925925925925925925925926,
1149 .52556028352292727401362526507000438869000, .5912240184757505773672055427251732101617,
1150 .52786708962084227803046587723656557500350, .5898617511520737327188940092165898617512,
1151 .53016858660912158374145519701414741575700, .5885057471264367816091954022988505747126,
1152 .53246479886947173376654518506256863474850, .5871559633027522935779816513761467889908,
1153 .53475575061602764748158733709715306758900, .5858123569794050343249427917620137299771,
1154 .53704146589688361856929077475797384977350, .5844748858447488584474885844748858447489,
1155 .53932196859560876944783558428753167390800, .5831435079726651480637813211845102505695,
1156 .54159728243274429804188230264117009937750, .5818181818181818181818181818181818181818,
1157 .54386743096728351609669971367111429572100, .5804988662131519274376417233560090702948,
1158 .54613243759813556721383065450936555862450, .5791855203619909502262443438914027149321,
1159 .54839232556557315767520321969641372561450, .5778781038374717832957110609480812641084,
1160 .55064711795266219063194057525834068655950, .5765765765765765765765765765765765765766,
1161 .55289683768667763352766542084282264113450, .5752808988764044943820224719101123595506,
1162 .55514150754050151093110798683483153581600, .5739910313901345291479820627802690582960,
1163 .55738115013400635344709144192165695130850, .5727069351230425055928411633109619686801,
1164 .55961578793542265941596269840374588966350, .5714285714285714285714285714285714285714,
1165 .56184544326269181269140062795486301183700, .5701559020044543429844097995545657015590,
1166 .56407013828480290218436721261241473257550, .5688888888888888888888888888888888888889,
1167 .56628989502311577464155334382667206227800, .5676274944567627494456762749445676274945,
1168 .56850473535266865532378233183408156037350, .5663716814159292035398230088495575221239,
1169 .57071468100347144680739575051120482385150, .5651214128035320088300220750551876379691,
1170 .57291975356178548306473885531886480748650, .5638766519823788546255506607929515418502,
1171 .57511997447138785144460371157038025558000, .5626373626373626373626373626373626373626,
1172 .57731536503482350219940144597785547375700, .5614035087719298245614035087719298245614,
1173 .57950594641464214795689713355386629700650, .5601750547045951859956236323851203501094,
1174 .58169173963462239562716149521293118596100, .5589519650655021834061135371179039301310,
1175 .58387276558098266665552955601015128195300, .5577342047930283224400871459694989106754,
1176 .58604904500357812846544902640744112432000, .5565217391304347826086956521739130434783,
1177 .58822059851708596855957011939608491957200, .5553145336225596529284164859002169197397,
1178 .59038744660217634674381770309992134571100, .5541125541125541125541125541125541125541,
1179 .59254960960667157898740242671919986605650, .5529157667386609071274298056155507559395,
1180 .59470710774669277576265358220553025603300, .5517241379310344827586206896551724137931,
1181 .59685996110779382384237123915227130055450, .5505376344086021505376344086021505376344,
1182 .59900818964608337768851242799428291618800, .5493562231759656652360515021459227467811,
1183 .60115181318933474940990890900138765573500, .5481798715203426124197002141327623126338,
1184 .60329085143808425240052883964381180703650, .5470085470085470085470085470085470085470,
1185 .60542532396671688843525771517306566238400, .5458422174840085287846481876332622601279,
1186 .60755525022454170969155029524699784815300, .5446808510638297872340425531914893617021,
1187 .60968064953685519036241657886421307921400, .5435244161358811040339702760084925690021,
1188 .61180154110599282990534675263916142284850, .5423728813559322033898305084745762711864,
1189 .61391794401237043121710712512140162289150, .5412262156448202959830866807610993657505,
1190 .61602987721551394351138242200249806046500, .5400843881856540084388185654008438818565,
1191 .61813735955507864705538167982012964785100, .5389473684210526315789473684210526315789,
1192 .62024040975185745772080281312810257077200, .5378151260504201680672268907563025210084,
1193 .62233904640877868441606324267922900617100, .5366876310272536687631027253668763102725,
1194 .62443328801189346144440150965237990021700, .5355648535564853556485355648535564853556,
1195 .62652315293135274476554741340805776417250, .5344467640918580375782881002087682672234,
1196 .62860865942237409420556559780379757285100, .5333333333333333333333333333333333333333,
1197 .63068982562619868570408243613201193511500, .5322245322245322245322245322245322245322,
1198 .63276666957103777644277897707070223987100, .5311203319502074688796680497925311203320,
1199 .63483920917301017716738442686619237065300, .5300207039337474120082815734989648033126,
1200 .63690746223706917739093569252872839570050, .5289256198347107438016528925619834710744,
1201 .63897144645792069983514238629140891134750, .5278350515463917525773195876288659793814,
1202 .64103117942093124081992527862894348800200, .5267489711934156378600823045267489711934,
1203 .64308667860302726193566513757104985415950, .5256673511293634496919917864476386036961,
1204 .64513796137358470073053240412264131009600, .5245901639344262295081967213114754098361,
1205 .64718504499530948859131740391603671014300, .5235173824130879345603271983640081799591,
1206 .64922794662510974195157587018911726772800, .5224489795918367346938775510204081632653,
1207 .65126668331495807251485530287027359008800, .5213849287169042769857433808553971486762,
1208 .65330127201274557080523663898929953575150, .5203252032520325203252032520325203252033,
1209 .65533172956312757406749369692988693714150, .5192697768762677484787018255578093306288,
1210 .65735807270835999727154330685152672231200, .5182186234817813765182186234817813765182,
1211 .65938031808912778153342060249997302889800, .5171717171717171717171717171717171717172,
1212 .66139848224536490484126716182800009846700, .5161290322580645161290322580645161290323,
1213 .66341258161706617713093692145776003599150, .5150905432595573440643863179074446680080,
1214 .66542263254509037562201001492212526500250, .5140562248995983935742971887550200803213,
1215 .66742865127195616370414654738851822912700, .5130260521042084168336673346693386773547,
1216 .66943065394262923906154583164607174694550, .5120000000000000000000000000000000000000,
1217 .67142865660530226534774556057527661323550, .5109780439121756487025948103792415169661,
1218 .67342267521216669923234121597488410770900, .5099601593625498007968127490039840637450,
1219 .67541272562017662384192817626171745359900, .5089463220675944333996023856858846918489,
1220 .67739882359180603188519853574689477682100, .5079365079365079365079365079365079365079,
1221 .67938098479579733801614338517538271844400, .5069306930693069306930693069306930693069,
1222 .68135922480790300781450241629499942064300, .5059288537549407114624505928853754940711,
1223 .68333355911162063645036823800182901322850, .5049309664694280078895463510848126232742,
1224 .68530400309891936760919861626462079584600, .5039370078740157480314960629921259842520,
1225 .68727057207096020619019327568821609020250, .5029469548133595284872298624754420432220,
1226 .68923328123880889251040571252815425395950, .5019607843137254901960784313725490196078,
1227 .69314718055994530941723212145818, 5.0e-01,
1232 #define LOGTAB_TRANSLATE(x,h) (((x) - 1.)*icvLogTab[(h)+1])
1233 static const double ln_2 = 0.69314718055994530941723212145818;
1235 static CvStatus CV_STDCALL Log_32f( const float *_x, float *y, int n )
1237 static const double shift[] = { 0, -1./512 };
1239 A0 = 0.3333333333333333333333333,
1244 #define LOGPOLY(x,k) ((x)+=shift[k],((A0*(x) + A1)*(x) + A2)*(x))
1254 const int* x = (const int*)_x;
1257 return CV_NULLPTR_ERR;
1259 return CV_BADSIZE_ERR;
1261 for( i = 0; i <= n - 4; i += 4 )
1263 double x0, x1, x2, x3;
1264 double y0, y1, y2, y3;
1269 buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23);
1270 buf[1].i = (h1 & LOGTAB_MASK2_32F) | (127 << 23);
1272 y0 = (((h0 >> 23) & 0xff) - 127) * ln_2;
1273 y1 = (((h1 >> 23) & 0xff) - 127) * ln_2;
1275 h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1276 h1 = (h1 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1278 y0 += icvLogTab[h0];
1279 y1 += icvLogTab[h1];
1284 x0 = LOGTAB_TRANSLATE( buf[0].f, h0 );
1285 x1 = LOGTAB_TRANSLATE( buf[1].f, h1 );
1287 buf[2].i = (h2 & LOGTAB_MASK2_32F) | (127 << 23);
1288 buf[3].i = (h3 & LOGTAB_MASK2_32F) | (127 << 23);
1290 y2 = (((h2 >> 23) & 0xff) - 127) * ln_2;
1291 y3 = (((h3 >> 23) & 0xff) - 127) * ln_2;
1293 h2 = (h2 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1294 h3 = (h3 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1296 y2 += icvLogTab[h2];
1297 y3 += icvLogTab[h3];
1299 x2 = LOGTAB_TRANSLATE( buf[2].f, h2 );
1300 x3 = LOGTAB_TRANSLATE( buf[3].f, h3 );
1302 y0 += LOGPOLY( x0, h0 == 510 );
1303 y1 += LOGPOLY( x1, h1 == 510 );
1306 y[i + 1] = (float) y1;
1308 y2 += LOGPOLY( x2, h2 == 510 );
1309 y3 += LOGPOLY( x3, h3 == 510 );
1311 y[i + 2] = (float) y2;
1312 y[i + 3] = (float) y3;
1320 y0 = (((h0 >> 23) & 0xff) - 127) * ln_2;
1322 buf[0].i = (h0 & LOGTAB_MASK2_32F) | (127 << 23);
1323 h0 = (h0 >> (23 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1325 y0 += icvLogTab[h0];
1326 x0 = LOGTAB_TRANSLATE( buf[0].f, h0 );
1327 y0 += LOGPOLY( x0, h0 == 510 );
1336 static CvStatus CV_STDCALL Log_64f( const double *x, double *y, int n )
1338 static const double shift[] = { 0, -1./512 };
1342 A5 = 0.333333333333333314829616256247390992939472198486328125,
1345 A2 = -0.1666666666666666574148081281236954964697360992431640625,
1346 A1 = 0.1428571428571428769682682968777953647077083587646484375,
1350 #define LOGPOLY(x,k) ((x)+=shift[k], xq = (x)*(x),\
1351 (((A0*xq + A2)*xq + A4)*xq + A6)*xq + \
1352 (((A1*xq + A3)*xq + A5)*xq + A7)*(x))
1356 DBLINT *X = (DBLINT *) x;
1359 return CV_NULLPTR_ERR;
1361 return CV_BADSIZE_ERR;
1363 for( ; i <= n - 4; i += 4 )
1366 double x0, x1, x2, x3;
1367 double y0, y1, y2, y3;
1377 buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20);
1378 buf[1].i.hi = (h1 & LOGTAB_MASK2) | (1023 << 20);
1380 y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2;
1381 y1 = (((h1 >> 20) & 0x7ff) - 1023) * ln_2;
1388 h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1389 h1 = (h1 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1391 y0 += icvLogTab[h0];
1392 y1 += icvLogTab[h1];
1397 x0 = LOGTAB_TRANSLATE( buf[0].d, h0 );
1398 x1 = LOGTAB_TRANSLATE( buf[1].d, h1 );
1400 buf[2].i.hi = (h2 & LOGTAB_MASK2) | (1023 << 20);
1401 buf[3].i.hi = (h3 & LOGTAB_MASK2) | (1023 << 20);
1403 y2 = (((h2 >> 20) & 0x7ff) - 1023) * ln_2;
1404 y3 = (((h3 >> 20) & 0x7ff) - 1023) * ln_2;
1406 h2 = (h2 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1407 h3 = (h3 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1409 y2 += icvLogTab[h2];
1410 y3 += icvLogTab[h3];
1412 x2 = LOGTAB_TRANSLATE( buf[2].d, h2 );
1413 x3 = LOGTAB_TRANSLATE( buf[3].d, h3 );
1415 y0 += LOGPOLY( x0, h0 == 510 );
1416 y1 += LOGPOLY( x1, h1 == 510 );
1421 y2 += LOGPOLY( x2, h2 == 510 );
1422 y3 += LOGPOLY( x3, h3 == 510 );
1432 double x0, y0 = (((h0 >> 20) & 0x7ff) - 1023) * ln_2;
1434 buf[0].i.hi = (h0 & LOGTAB_MASK2) | (1023 << 20);
1435 buf[0].i.lo = X[i].i.lo;
1436 h0 = (h0 >> (20 - LOGTAB_SCALE - 1)) & LOGTAB_MASK * 2;
1438 y0 += icvLogTab[h0];
1439 x0 = LOGTAB_TRANSLATE( buf[0].d, h0 );
1440 y0 += LOGPOLY( x0, h0 == 510 );
1449 #define Log_32f ippsLn_32f_A21
1450 #define Log_64f ippsLn_64f_A50
1454 void log( const Mat& src, Mat& dst )
1456 int depth = src.depth();
1457 dst.create( src.size(), src.type() );
1458 Size size = getContinuousSize( src, dst, src.channels() );
1460 MathFunc func = depth == CV_32F ? (MathFunc)Log_32f : depth == CV_64F ? (MathFunc)Log_64f : 0;
1461 CV_Assert(func != 0);
1463 for( int y = 0; y < size.height; y++ )
1464 func( src.data + src.step*y, dst.data + dst.step*y, size.width );
1468 /****************************************************************************************\
1470 \****************************************************************************************/
1472 template<typename T, typename WT>
1473 static CvStatus CV_STDCALL
1474 IPow( const void* _src, void* _dst, int len, int power )
1477 const T* src = (const T*)_src;
1479 for( i = 0; i < len; i++ )
1481 WT a = 1, b = src[i];
1492 dst[i] = saturate_cast<T>(a);
1497 typedef CvStatus (CV_STDCALL * IPowFunc)( const void* src, void* dst, int len, int power );
1499 void pow( const Mat& _src, double power, Mat& dst )
1501 int ipower = cvRound( power ), i, j;
1503 int depth = _src.depth();
1504 const Mat* src = &_src;
1506 dst.create( _src.size(), _src.type() );
1508 if( fabs(ipower - power) < DBL_EPSILON )
1512 divide( 1., _src, dst );
1522 dst = Scalar::all(1);
1528 multiply(*src, *src, dst);
1535 CV_Assert( depth == CV_32F || depth == CV_64F );
1537 Size size = getContinuousSize( *src, dst, src->channels() );
1541 static IPowFunc tab[] =
1543 IPow<uchar, int>, 0, IPow<ushort, int>, IPow<short, int>, IPow<int, int>,
1544 IPow<float, float>, IPow<double, double>, 0
1547 IPowFunc func = tab[depth];
1548 CV_Assert( func != 0 );
1549 for( i = 0; i < size.height; i++ )
1550 func( src->data + src->step*i, dst.data + dst.step*i, size.width, ipower );
1552 else if( fabs(fabs(power) - 0.5) < DBL_EPSILON )
1554 MathFunc func = power < 0 ?
1555 (depth == CV_32F ? (MathFunc)InvSqrt_32f : (MathFunc)InvSqrt_64f) :
1556 (depth == CV_32F ? (MathFunc)Sqrt_32f : (MathFunc)Sqrt_64f);
1558 for( i = 0; i < size.height; i++ )
1559 func( src->data + src->step*i, dst.data + dst.step*i, size.width );
1561 else if( depth == CV_32F )
1563 const float *x = (const float*)src->data;
1564 float *y = (float*)dst.data;
1565 size_t xstep = src->step/sizeof(x[0]), ystep = dst.step/sizeof(y[0]);
1566 float p = (float)power;
1568 for( ; size.height--; x += xstep, y += ystep )
1570 for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
1572 int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
1573 Log_32f(x + i, y + i, block_size);
1574 for( j = 0; j < block_size; j++ )
1576 Exp_32f(y + i, y + i, block_size);
1582 const double *x = (const double*)src->data;
1583 double *y = (double*)dst.data;
1584 size_t xstep = src->step/sizeof(x[0]), ystep = dst.step/sizeof(y[0]);
1586 for( ; size.height--; x += xstep, y += ystep )
1588 for( i = 0; i < size.width; i += MAX_BLOCK_SIZE )
1590 int block_size = std::min(MAX_BLOCK_SIZE, size.width - i);
1591 Log_64f(x + i, y + i, block_size);
1592 for( j = 0; j < block_size; j++ )
1594 Exp_64f(y + i, y + i, block_size);
1600 void sqrt(const Mat& a, Mat& b)
1605 /************************** CheckArray for NaN's, Inf's *********************************/
1607 bool checkRange(const Mat& src, bool quiet, Point* pt,
1608 double minVal, double maxVal)
1610 int depth = src.depth();
1611 Point badPt(-1, -1);
1612 double badValue = 0;
1614 if( depth < CV_32F )
1616 double m = 0, M = 0, badValue = 0;
1617 Point mp, MP, badPt(-1,-1);
1618 minMaxLoc(src.reshape(1,0), &m, &M, &mp, &MP);
1624 else if( m < minVal )
1633 Size size = getContinuousSize( src, src.channels() );
1635 if( depth == CV_32F )
1639 const int* isrc = (const int*)src.data;
1640 size_t step = src.step/sizeof(isrc[0]);
1642 a.f = (float)std::max(minVal, (double)-FLT_MAX);
1643 b.f = (float)std::min(maxVal, (double)FLT_MAX);
1645 ia = CV_TOGGLE_FLT(a.i);
1646 ib = CV_TOGGLE_FLT(b.i);
1648 for( ; badPt.x < 0 && size.height--; loc += size.width, isrc += step )
1650 for( i = 0; i < size.width; i++ )
1653 val = CV_TOGGLE_FLT(val);
1655 if( val < ia || val >= ib )
1657 badPt = Point((loc + i) % src.cols, (loc + i) / src.cols);
1658 badValue = ((const float*)isrc)[i];
1668 const int64* isrc = (const int64*)src.data;
1669 size_t step = src.step/sizeof(isrc[0]);
1674 ia = CV_TOGGLE_DBL(a.i);
1675 ib = CV_TOGGLE_DBL(b.i);
1677 for( ; badPt.x < 0 && size.height--; loc += size.width, isrc += step )
1679 for( i = 0; i < size.width; i++ )
1681 int64 val = isrc[i];
1682 val = CV_TOGGLE_DBL(val);
1684 if( val < ia || val >= ib )
1686 badPt = Point((loc + i) % src.cols, (loc + i) / src.cols);
1687 badValue = ((const double*)isrc)[i];
1700 CV_Error_( CV_StsOutOfRange,
1701 ("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue));
1708 CV_IMPL float cvCbrt(float value) { return cv::cubeRoot(value); }
1709 CV_IMPL float cvFastArctan(float y, float x) { return cv::fastAtan2(y, x); }
1712 cvCartToPolar( const CvArr* xarr, const CvArr* yarr,
1713 CvArr* magarr, CvArr* anglearr,
1714 int angle_in_degrees )
1716 cv::Mat X = cv::cvarrToMat(xarr), Y = cv::cvarrToMat(yarr), Mag, Angle;
1719 Mag = cv::cvarrToMat(magarr);
1720 CV_Assert( Mag.size() == X.size() && Mag.type() == X.type() );
1724 Angle = cv::cvarrToMat(anglearr);
1725 CV_Assert( Angle.size() == X.size() && Angle.type() == X.type() );
1730 cv::cartToPolar( X, Y, Mag, Angle, angle_in_degrees != 0 );
1732 cv::magnitude( X, Y, Mag );
1735 cv::phase( X, Y, Angle, angle_in_degrees != 0 );
1739 cvPolarToCart( const CvArr* magarr, const CvArr* anglearr,
1740 CvArr* xarr, CvArr* yarr, int angle_in_degrees )
1742 cv::Mat X, Y, Angle = cv::cvarrToMat(anglearr), Mag;
1745 Mag = cv::cvarrToMat(magarr);
1746 CV_Assert( Mag.size() == Angle.size() && Mag.type() == Angle.type() );
1750 X = cv::cvarrToMat(xarr);
1751 CV_Assert( X.size() == Angle.size() && X.type() == Angle.type() );
1755 Y = cv::cvarrToMat(yarr);
1756 CV_Assert( Y.size() == Angle.size() && Y.type() == Angle.type() );
1759 cv::polarToCart( Mag, Angle, X, Y, angle_in_degrees != 0 );
1762 CV_IMPL void cvExp( const CvArr* srcarr, CvArr* dstarr )
1764 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
1765 CV_Assert( src.type() == dst.type() && src.size() == dst.size() );
1766 cv::exp( src, dst );
1769 CV_IMPL void cvLog( const CvArr* srcarr, CvArr* dstarr )
1771 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
1772 CV_Assert( src.type() == dst.type() && src.size() == dst.size() );
1773 cv::log( src, dst );
1776 CV_IMPL void cvPow( const CvArr* srcarr, CvArr* dstarr, double power )
1778 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
1779 CV_Assert( src.type() == dst.type() && src.size() == dst.size() );
1780 cv::pow( src, power, dst );
1783 CV_IMPL int cvCheckArr( const CvArr* arr, int flags,
1784 double minVal, double maxVal )
1786 if( (flags & CV_CHECK_RANGE) == 0 )
1787 minVal = -DBL_MAX, maxVal = DBL_MAX;
1788 return cv::checkRange(cv::cvarrToMat(arr), (flags & CV_CHECK_QUIET) != 0, 0, minVal, maxVal );
1793 Finds real roots of cubic, quadratic or linear equation.
1794 The original code has been taken from Ken Turkowski web page
1795 (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV.
1796 Here is the copyright notice.
1798 -----------------------------------------------------------------------
1799 Copyright (C) 1978-1999 Ken Turkowski. <turk@computer.org>
1801 All rights reserved.
1803 Warranty Information
1804 Even though I have reviewed this software, I make no warranty
1805 or representation, either express or implied, with respect to this
1806 software, its quality, accuracy, merchantability, or fitness for a
1807 particular purpose. As a result, this software is provided "as is,"
1808 and you, its user, are assuming the entire risk as to its quality
1811 This code may be used and freely distributed as long as it includes
1812 this copyright notice and the above warranty information.
1813 -----------------------------------------------------------------------
1816 cvSolveCubic( const CvMat* coeffs, CvMat* roots )
1820 double a0 = 1., a1, a2, a3;
1821 double x0 = 0., x1 = 0., x2 = 0.;
1825 if( !CV_IS_MAT(coeffs) )
1826 CV_Error( !coeffs ? CV_StsNullPtr : CV_StsBadArg, "Input parameter is not a valid matrix" );
1828 if( !CV_IS_MAT(roots) )
1829 CV_Error( !roots ? CV_StsNullPtr : CV_StsBadArg, "Output parameter is not a valid matrix" );
1831 if( (CV_MAT_TYPE(coeffs->type) != CV_32FC1 && CV_MAT_TYPE(coeffs->type) != CV_64FC1) ||
1832 (CV_MAT_TYPE(roots->type) != CV_32FC1 && CV_MAT_TYPE(roots->type) != CV_64FC1) )
1833 CV_Error( CV_StsUnsupportedFormat,
1834 "Both matrices should be floating-point (single or double precision)" );
1836 coeff_count = coeffs->rows + coeffs->cols - 1;
1838 if( (coeffs->rows != 1 && coeffs->cols != 1) || (coeff_count != 3 && coeff_count != 4) )
1839 CV_Error( CV_StsBadSize,
1840 "The matrix of coefficients must be 1-dimensional vector of 3 or 4 elements" );
1842 if( (roots->rows != 1 && roots->cols != 1) ||
1843 roots->rows + roots->cols - 1 != 3 )
1844 CV_Error( CV_StsBadSize,
1845 "The matrix of roots must be 1-dimensional vector of 3 elements" );
1847 if( CV_MAT_TYPE(coeffs->type) == CV_32FC1 )
1849 const float* c = coeffs->data.fl;
1850 if( coeffs->rows > 1 )
1851 step = coeffs->step/sizeof(c[0]);
1852 if( coeff_count == 4 )
1853 a0 = c[0], c += step;
1860 const double* c = coeffs->data.db;
1861 if( coeffs->rows > 1 )
1862 step = coeffs->step/sizeof(c[0]);
1863 if( coeff_count == 4 )
1864 a0 = c[0], c += step;
1875 n = a3 == 0 ? -1 : 0;
1885 // quadratic equation
1886 double d = a2*a2 - 4*a1*a3;
1890 double q = (-a2 + (a2 < 0 ? -d : d)) * 0.5;
1904 double Q = (a1 * a1 - 3 * a2) * (1./9);
1905 double R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) * (1./54);
1906 double Qcubed = Q * Q * Q;
1907 double d = Qcubed - R * R;
1911 double theta = acos(R / sqrt(Qcubed));
1912 double sqrtQ = sqrt(Q);
1913 double t0 = -2 * sqrtQ;
1914 double t1 = theta * (1./3);
1915 double t2 = a1 * (1./3);
1916 x0 = t0 * cos(t1) - t2;
1917 x1 = t0 * cos(t1 + (2.*CV_PI/3)) - t2;
1918 x2 = t0 * cos(t1 + (4.*CV_PI/3)) - t2;
1925 e = pow(d + fabs(R), 0.333333333333);
1928 x0 = (e + Q / e) - a1 * (1./3);
1935 if( CV_MAT_TYPE(roots->type) == CV_32FC1 )
1937 float* r = roots->data.fl;
1938 if( roots->rows > 1 )
1939 step = roots->step/sizeof(r[0]);
1941 r[step] = (float)x1;
1942 r[step*2] = (float)x2;
1946 double* r = roots->data.db;
1947 if( roots->rows > 1 )
1948 step = roots->step/sizeof(r[0]);
1959 Finds real and complex roots of polynomials of any degree with real
1960 coefficients. The original code has been taken from Ken Turkowski's web
1961 page (http://www.worldserver.com/turk/opensource/) and adopted for OpenCV.
1962 Here is the copyright notice.
1964 -----------------------------------------------------------------------
1965 Copyright (C) 1981-1999 Ken Turkowski. <turk@computer.org>
1967 All rights reserved.
1969 Warranty Information
1970 Even though I have reviewed this software, I make no warranty
1971 or representation, either express or implied, with respect to this
1972 software, its quality, accuracy, merchantability, or fitness for a
1973 particular purpose. As a result, this software is provided "as is,"
1974 and you, its user, are assuming the entire risk as to its quality
1977 This code may be used and freely distributed as long as it includes
1978 this copyright notice and the above warranty information.
1982 /*******************************************************************************
1983 * FindPolynomialRoots
1985 * The Bairstow and Newton correction formulae are used for a simultaneous
1986 * linear and quadratic iterated synthetic division. The coefficients of
1987 * a polynomial of degree n are given as a[i] (i=0,i,..., n) where a[0] is
1988 * the constant term. The coefficients are scaled by dividing them by
1989 * their geometric mean. The Bairstow or Newton iteration method will
1990 * nearly always converge to the number of figures carried, fig, either to
1991 * root values or to their reciprocals. If the simultaneous Newton and
1992 * Bairstow iteration fails to converge on root values or their
1993 * reciprocals in maxiter iterations, the convergence requirement will be
1994 * successively reduced by one decimal figure. This program anticipates
1995 * and protects against loss of significance in the quadratic synthetic
1996 * division. (Refer to "On Programming the Numerical Solution of
1997 * Polynomial Equations," by K. W. Ellenberger, Commun. ACM 3 (Dec. 1960),
1998 * 644-647.) The real and imaginary part of each root is stated as u[i]
1999 * and v[i], respectively.
2001 * ACM algorithm #30 - Numerical Solution of the Polynomial Equation
2003 * Missle Division, North American Aviation, Downey, California
2004 * Converted to C, modified, optimized, and structured by
2006 * CADLINC, Inc., Palo Alto, California
2007 *******************************************************************************/
2011 static void icvFindPolynomialRoots(const double *a, double *u, int n, int maxiter, int fig)
2015 double h[MAXN + 3], b[MAXN + 3], c[MAXN + 3], d[MAXN + 3], e[MAXN + 3];
2017 double K, ps, qs, pt, qt, s, rev, r = 0;
2019 double p = 0, q = 0, qq;
2021 // Zero elements with negative indices
2022 b[2 + -1] = b[2 + -2] =
2023 c[2 + -1] = c[2 + -2] =
2024 d[2 + -1] = d[2 + -2] =
2025 e[2 + -1] = e[2 + -2] =
2026 h[2 + -1] = h[2 + -2] = 0.0;
2028 // Copy polynomial coefficients to working storage
2029 for (j = n; j >= 0; j--)
2030 h[2 + j] = *a++; // Note reversal of coefficients
2033 K = pow(10.0, (double)(fig)); // Relative accuracy
2035 for (; h[2 + n] == 0.0; n--) { // Look for zero high-order coeff.
2044 ps = qs = pt = qt = s = 0.0;
2046 K = pow(10.0, (double)(fig));
2049 r = -h[2 + 1] / h[2 + 0];
2053 for (j = n; j >= 0; j--) // Find geometric mean of coeff's
2054 if (h[2 + j] != 0.0)
2055 s += log(fabs(h[2 + j]));
2056 s = exp(s / (n + 1));
2058 for (j = n; j >= 0; j--) // Normalize coeff's by mean
2061 if (fabs(h[2 + 1] / h[2 + 0]) < fabs(h[2 + n - 1] / h[2 + n])) {
2064 for (j = (n - 1) / 2; j >= 0; j--) {
2066 h[2 + j] = h[2 + n - j];
2074 if (h[2 + n - 2] == 0.0) {
2078 q = h[2 + n] / h[2 + n - 2];
2079 p = (h[2 + n - 1] - q * h[2 + n - 3]) / h[2 + n - 2];
2086 for (i = maxiter; i > 0; i--) {
2088 for (j = 0; j <= n; j++) { // BAIRSTOW
2089 b[2 + j] = h[2 + j] - p * b[2 + j - 1] - q * b[2 + j - 2];
2090 c[2 + j] = b[2 + j] - p * c[2 + j - 1] - q * c[2 + j - 2];
2092 if ((h[2 + n - 1] != 0.0) && (b[2 + n - 1] != 0.0)) {
2093 if (fabs(h[2 + n - 1] / b[2 + n - 1]) >= K) {
2094 b[2 + n] = h[2 + n] - q * b[2 + n - 2];
2096 if (b[2 + n] == 0.0)
2098 if (K < fabs(h[2 + n] / b[2 + n]))
2102 for (j = 0; j <= n; j++) { // NEWTON
2103 d[2 + j] = h[2 + j] + r * d[2 + j - 1]; // Calculate polynomial at r
2104 e[2 + j] = d[2 + j] + r * e[2 + j - 1]; // Calculate derivative at r
2106 if (d[2 + n] == 0.0)
2108 if (K < fabs(h[2 + n] / d[2 + n]))
2111 c[2 + n - 1] = -p * c[2 + n - 2] - q * c[2 + n - 3];
2112 s = c[2 + n - 2] * c[2 + n - 2] - c[2 + n - 1] * c[2 + n - 3];
2117 p += (b[2 + n - 1] * c[2 + n - 2] - b[2 + n] * c[2 + n - 3]) / s;
2118 q += (-b[2 + n - 1] * c[2 + n - 1] + b[2 + n] * c[2 + n - 2]) / s;
2120 if (e[2 + n - 1] == 0.0)
2121 r -= 1.0; // Minimum step
2123 r -= d[2 + n] / e[2 + n - 1]; // Newton's iteration
2141 for (j = n; j >= 0; j--) { // Polynomial deflation by lin-nomial
2142 if ((d[2 + j] != 0.0) && (fabs(h[2 + j] / d[2 + j]) < K))
2143 h[2 + j] = d[2 + j];
2159 if (0.0 < (q - (p * p / 4.0))) { // Two complex roots
2160 s = sqrt(q - (p * p / 4.0));
2165 } else { // Two real roots
2166 s = sqrt(((p * p / 4.0)) - q);
2168 *u++ = qq = -p / 2.0 + s;
2170 *u++ = qq = -p / 2.0 - s;
2176 for (j = n; j >= 0; j--) { // Polynomial deflation by quadratic
2177 if ((b[2 + j] != 0.0) && (fabs(h[2 + j] / b[2 + j]) < K))
2178 h[2 + j] = b[2 + j];
2187 void cvSolvePoly(const CvMat* a, CvMat *r, int maxiter, int fig)
2192 double *ad = 0, *rd = 0;
2194 CV_FUNCNAME("cvSolvePoly");
2196 CV_ASSERT(maxiter > 0);
2197 if (CV_MAT_TYPE(a->type) != CV_32FC1 &&
2198 CV_MAT_TYPE(a->type) != CV_64FC1)
2199 CV_Error(CV_StsUnsupportedFormat, "coeffs must be either CV_32FC1 or CV_64FC1");
2200 if (CV_MAT_TYPE(r->type) != CV_32FC2 &&
2201 CV_MAT_TYPE(r->type) != CV_64FC2)
2202 CV_Error(CV_StsUnsupportedFormat, "roots must be either CV_32FC2 or CV_64FC2");
2203 m = a->rows * a->cols;
2204 n = r->rows * r->cols;
2207 CV_Error(CV_StsUnmatchedFormats, "must have n + 1 coefficients");
2209 if( CV_MAT_DEPTH(a->type) == CV_32F || !CV_IS_MAT_CONT(a->type))
2211 ad = (double*)cvStackAlloc(m*sizeof(ad[0]));
2212 CvMat _a = cvMat( a->rows, a->cols, CV_64F, ad );
2213 cvConvert( a, &_a );
2218 if( CV_MAT_DEPTH(r->type) == CV_32F || !CV_IS_MAT_CONT(r->type))
2219 rd = (double*)cvStackAlloc(n*sizeof(ad[0]));
2223 icvFindPolynomialRoots( ad, rd, n, maxiter, fig);
2224 if( rd != r->data.db )
2226 CvMat _r = cvMat( r->rows, r->cols, CV_64FC2, rd );
2227 cvConvert( &_r, r );