Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_MATH_POLAR_DECOMPOSITION_H
00002 #define OPENTISSUE_CORE_MATH_MATH_POLAR_DECOMPOSITION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_vector3.h>
00013 #include <OpenTissue/core/math/math_matrix3x3.h>
00014 #include <OpenTissue/core/math/math_eigen_system_decomposition.h>
00015
00016 #include <cmath>
00017
00018
00019 namespace OpenTissue
00020 {
00021
00022 namespace math
00023 {
00024
00025
00026
00027 namespace polar_decomposition
00028 {
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 template<typename matrix3x3_type>
00050 inline bool eigen(matrix3x3_type const & A,matrix3x3_type & R,matrix3x3_type & S)
00051 {
00052 using std::sqrt;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 typedef typename matrix3x3_type::vector3_type vector3_type;
00075 typedef typename matrix3x3_type::value_traits value_traits;
00076 matrix3x3_type V;
00077 vector3_type d;
00078 matrix3x3_type S2 = trans(A)*A;
00079 eigen(S2,V,d);
00080
00081
00082 if( d(0) <= value_traits::zero() || d(1) <= value_traits::zero() || d(2) <= value_traits::zero() )
00083 return false;
00084
00085 vector3_type v0 = vector3_type( V(0,0), V(1,0), V(2,0) );
00086 vector3_type v1 = vector3_type( V(0,1), V(1,1), V(2,1) );
00087 vector3_type v2 = vector3_type( V(0,2), V(1,2), V(2,2) );
00088 S = outer_prod(v0,v0)* sqrt(d(0)) + outer_prod(v1,v1)* sqrt(d(1)) + outer_prod(v2,v2)* sqrt(d(2));
00089 R = A * inverse(S);
00090 return true;
00091 }
00092
00110 template<typename matrix3x3_type>
00111 inline bool newton(matrix3x3_type const & A, matrix3x3_type & R,unsigned int max_iterations, typename matrix3x3_type::value_type const & threshold)
00112 {
00113 typedef typename matrix3x3_type::value_traits value_traits;
00114 typedef typename matrix3x3_type::value_type real_type;
00115
00116 assert(max_iterations>0 || !"polar_decompostion::newton() max_iterations must be positive");
00117 assert(threshold>value_traits::zero() || !"polar_decomposition::newton(): theshold must be positive");
00118
00119 matrix3x3_type Q[2];
00120 int cur = 0, next = 1;
00121 Q[cur] = A;
00122
00123 bool within_threshold = false;
00124
00125 for(unsigned int iteration=0;iteration< max_iterations;++iteration)
00126 {
00127 Q[next] = ( Q[cur] + trans(inverse(Q[cur])) )*.5;
00128 real_type test = max_value ( Q[next] - Q[cur] );
00129 if( test < threshold )
00130 {
00131 within_threshold = true;
00132 break;
00133 }
00134 cur = (cur + 1)%2;
00135 next = (next + 1)%2;
00136 }
00137 R = Q[next];
00138 return within_threshold;
00139 }
00140
00141 }
00142
00143 }
00144
00145 }
00146
00147
00148 #endif
00149