aimstil  5.0.5
eigen3D.h
Go to the documentation of this file.
1 #ifndef TIL_EIGEN3D_H
2 #define TIL_EIGEN3D_H
3 
4 // includes from STL
5 //#include <math.h>
6 #include <cmath>
7 #include <limits>
8 //#include <complex> // Warnings at compil time: can't use in DLL?
9 
10 // includes from TIL library
11 #include "til/til_common.h"
12 
13 
14 // Namespace
15 namespace til
16 {
17  template <class T>
18  void myComplexPow(T numReal, T numIm, T ex, T &resReal, T &resIm)
19  {
20  // Value under which no computation is done
21  const T EPSILON = 64 * (std::numeric_limits<T>::epsilon());
22 
23  T numNorm = (T) std::sqrt(double(numReal)*numReal + double(numIm)*numIm);
24 
25  if (numNorm <= EPSILON)
26  {
27  resReal = resIm = T(0);
28  return;
29  }
30 
31  //T numNorm = (T) std::sqrt(numNorm2);
32 
33  T resNorm = (T) std::pow(numNorm, ex);
34 
35  double angle;
36 
37  if (numReal < 0)
38  {
39  if (numIm < 0)
40  {
41  angle = (-M_PI - 2.0*std::atan(numIm / (numNorm - numReal)))*ex;
42  }
43  else
44  {
45  angle = (M_PI - 2.0*std::atan(numIm / (numNorm - numReal)))*ex;
46  }
47  }
48  else
49  {
50  angle = 2.0*std::atan(numIm / (numNorm + numReal))*ex;
51  }
52 
53  resReal = T(std::cos(angle)*resNorm);
54  resIm = T(std::sin(angle)*resNorm);
55  }
56 
57  template <class T>
58  void myComplexSqrt(T num, T &resReal, T &resIm)
59  {
60  if (num >= T(0))
61  {
62  resReal = (T) std::sqrt(num);
63  resIm = (T) 0;
64  }
65  else
66  {
67  resReal = (T) 0;
68  resIm = (T) std::sqrt(-num);
69  }
70  }
71 
72 
73  template <class T>
74  void eigen3D(T A11, T A12, T A13, T A22, T A23, T A33,
75  T &ev1, T &ev2, T &ev3)
76  {
77 
78  T A2 = -(A11+A22+A33);
79  T A1 = -(A12*A12+A13*A13+A23*A23-A11*A22-A11*A33-A22*A33);
80  T A0 = -(A11*A22*A33+2*A12*A13*A23-A12*A12*A33-A11*A23*A23-A13*A13*A22);
81 
82  T R = (9*A2*A1-27*A0-2*cube(A2))/T(54);
83  T D = (-square(A1*A2) + 27*square(A0)-18*A0*A1*A2 + 4*A0*cube(A2) + 4*cube(A1)) / 108;
84 
85 
86  T sqrtDReal;
87  T sqrtDIm;
88 
89  myComplexSqrt(D, sqrtDReal, sqrtDIm);
90 
91  if (std::abs(sqrtDIm) < 128 * (std::numeric_limits<T>::epsilon()) && R < sqrtDReal )
92  {
93  sqrtDIm = 128 * (std::numeric_limits<T>::epsilon());
94  }
95 
96  T SReal, SIm;
97  myComplexPow(R+sqrtDReal, sqrtDIm, T(1.0/3.0), SReal, SIm);
98 
99 
100  T TReal, TIm;
101  myComplexPow(R-sqrtDReal, -sqrtDIm, T(1.0/3.0), TReal, TIm);
102 
103  ev1 = T(-(1.0/3.0)*A2 + (SReal+TReal));
104  ev2 = T(-(1.0/3.0)*A2 - 0.5*(SReal+TReal) - 0.5*std::sqrt(3.0)*(SIm-TIm));
105  ev3 = T(-(1.0/3.0)*A2 - 0.5*(SReal+TReal) + 0.5*std::sqrt(3.0)*(SIm-TIm));
106  }
107 
108 } // namespace til
109 
110 #endif
111 
#define M_PI
Definition: til_common.h:48
void sqrt(const TImage &in, TImage &out)
Definition: imageArith.h:326
void myComplexSqrt(T num, T &resReal, T &resIm)
Definition: eigen3D.h:58
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
void myComplexPow(T numReal, T numIm, T ex, T &resReal, T &resIm)
Definition: eigen3D.h:18
General macros, definitions and functions.
INLINE const T cube(const T &a)
Max of two numbers.
numeric_array< T, D > abs(const numeric_array< T, D > &a)
Absolute value, element-wise.
T angle(T x, T y, T norm)
Returns the angle between (x,y) and the x-axis, with the norm of (x,y) provided.
void eigen3D(T A11, T A12, T A13, T A22, T A23, T A33, T &ev1, T &ev2, T &ev3)
Definition: eigen3D.h:74
void square(const TImage &in, TImage &out)
Definition: imageArith.h:310