svd_eigen_Macie.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SVD_BOOST_MACIE
00026 #define SVD_BOOST_MACIE
00027
00028 #include <Eigen/Core>
00029 USING_PART_OF_NAMESPACE_EIGEN
00030
00031 namespace KDL
00032 {
00033 int svd_eigen_Macie(const MatrixXd& A,MatrixXd& U,VectorXd& S, MatrixXd& V,
00034 MatrixXd& B, VectorXd& tempi,
00035 double treshold,bool toggle)
00036 {
00037 bool rotate = true;
00038 unsigned int sweeps=0;
00039 unsigned int rotations=0;
00040 if(toggle){
00041
00042 B=(A*V).lazy();
00043 while(rotate){
00044 rotate=false;
00045 rotations=0;
00046
00047 for(unsigned int i=0;i<B.cols();i++){
00048 for(unsigned int j=i+1;j<B.cols();j++){
00049
00050 double p = B.col(i).dot(B.col(j));
00051 double qi =B.col(i).dot(B.col(i));
00052 double qj = B.col(j).dot(B.col(j));
00053 double q=qi-qj;
00054 double alpha = pow(p,2.0)/(qi*qj);
00055
00056
00057 if(alpha<treshold)
00058 continue;
00059 rotations++;
00060 double c = sqrt(4*pow(p,2.0)+pow(q,2.0));
00061 double cos,sin;
00062 if(q>=0){
00063 cos=sqrt((c+q)/(2*c));
00064 sin=p/(c*cos);
00065 }else{
00066 if(p<0)
00067 sin=-sqrt((c-q)/(2*c));
00068 else
00069 sin=sqrt((c-q)/(2*c));
00070 cos=p/(c*sin);
00071 }
00072
00073
00074 tempi = cos*B.col(i) + sin*B.col(j);
00075 B.col(j) = - sin*B.col(i) + cos*B.col(j);
00076 B.col(i) = tempi;
00077
00078
00079 tempi.start(V.rows()) = cos*V.col(i) + sin*V.col(j);
00080 V.col(j) = - sin*V.col(i) + cos*V.col(j);
00081 V.col(i) = tempi.start(V.rows());
00082
00083 rotate=true;
00084 }
00085 }
00086
00087 if(rotations!=0){
00088 for(unsigned int i=0;i<U.rows();i++) {
00089 if(i<B.cols()){
00090 double si=sqrt(B.col(i).dot(B.col(i)));
00091 if(si==0)
00092 U.col(i) = B.col(i);
00093 else
00094 U.col(i) = B.col(i)/si;
00095 S(i)=si;
00096 }
00097 else
00098 U.col(i) = 0*tempi;
00099 }
00100 sweeps++;
00101 }
00102 }
00103 return sweeps;
00104 }else{
00105
00106 B =(U.transpose() * A).lazy();
00107 while(rotate){
00108 rotate=false;
00109 rotations=0;
00110
00111 for(unsigned int i=0;i<B.cols();i++){
00112 for(unsigned int j=i+1;j<B.cols();j++){
00113
00114 double p = B.row(i).dot(B.row(j));
00115 double qi = B.row(i).dot(B.row(i));
00116 double qj = B.row(j).dot(B.row(j));
00117
00118 double q=qi-qj;
00119 double alpha = pow(p,2.0)/(qi*qj);
00120
00121
00122
00123 if(alpha<treshold)
00124 continue;
00125 rotations++;
00126 double c = sqrt(4*pow(p,2.0)+pow(q,2.0));
00127 double cos,sin;
00128 if(q>=0){
00129 cos=sqrt((c+q)/(2*c));
00130 sin=p/(c*cos);
00131 }else{
00132 if(p<0)
00133 sin=-sqrt((c-q)/(2*c));
00134 else
00135 sin=sqrt((c-q)/(2*c));
00136 cos=p/(c*sin);
00137 }
00138
00139
00140 tempi.start(B.cols()) = cos*B.row(i) + sin*B.row(j);
00141 B.row(j) = - sin*B.row(i) + cos*B.row(j);
00142 B.row(i) = tempi.start(B.cols());
00143
00144
00145
00146 tempi.start(U.rows()) = cos*U.col(i) + sin*U.col(j);
00147 U.col(j) = - sin*U.col(i) + cos*U.col(j);
00148 U.col(i) = tempi.start(U.rows());
00149
00150 rotate=true;
00151 }
00152 }
00153
00154
00155 if(rotations!=0){
00156 for(unsigned int i=0;i<V.rows();i++) {
00157 double si=sqrt(B.row(i).dot(B.row(i)));
00158 if(si==0)
00159 V.col(i) = B.row(i);
00160 else
00161 V.col(i) = B.row(i)/si;
00162 S(i)=si;
00163 }
00164 sweeps++;
00165 }
00166 }
00167 return sweeps;
00168 }
00169 }
00170
00171
00172 }
00173 #endif