MC_matrix.cpp

Go to the documentation of this file.
00001 
00002 #include <MC_matrix.hpp>
00003 
00004 #include <cmath>
00005 #include <MC_int_vector.hpp>
00006 #include <MC_v3d.hpp>
00007 #include <MC_v4d.hpp>
00008 #include <MC_v3d_vector.hpp>
00009 #include <MC_string_helper.hpp>
00010 
00011 
00012 
00013 namespace mesh_conv
00014 {
00015 
00016 
00017 
00018 MC_matrix::MC_matrix(){current_size[0]=0;current_size[1]=0;resize(0);}
00019 
00020 MC_matrix::MC_matrix(const int& n,const int& m)
00021 {current_size[0]=0;current_size[1]=0;resize(n,m);}
00022 MC_matrix::MC_matrix(const int& n)
00023 {current_size[0]=0;current_size[1]=0;resize(n);}
00024 MC_matrix::MC_matrix(const MC_v3d& v)
00025 {
00026     current_size[0]=0;current_size[1]=0;
00027     resize(3,1);
00028     for(int k=0;k<3;k++)
00029         (*this)(k,0)=v[k];
00030 }
00031 MC_matrix::MC_matrix(const MC_v3d_vector& v)
00032 {
00033     current_size[0]=0;current_size[1]=0;
00034     int N=v.size();
00035     resize(3,N);
00036     for(int k=0;k<N;k++)
00037         for(int k_dim=0;k_dim<3;k_dim++)
00038             (*this)(k_dim,k)=v[k][k_dim];
00039 }
00040 MC_matrix::MC_matrix(const MC_v3d& v1,const MC_v3d& v2)
00041 {
00042     current_size[0]=0;current_size[1]=0;
00043     resize(3,2);
00044     for(int k_dim=0;k_dim<3;k_dim++)
00045         (*this)(k_dim,0)=v1[k_dim];
00046     for(int k_dim=0;k_dim<3;k_dim++)
00047         (*this)(k_dim,1)=v2[k_dim];
00048 }
00049 MC_matrix::MC_matrix(const MC_v3d& v1,const MC_v3d& v2,const MC_v3d& v3)
00050 {
00051     current_size[0]=0;current_size[1]=0;
00052     resize(3,3);
00053     for(int k_dim=0;k_dim<3;k_dim++)
00054         (*this)(k_dim,0)=v1[k_dim];
00055     for(int k_dim=0;k_dim<3;k_dim++)
00056         (*this)(k_dim,1)=v2[k_dim];
00057     for(int k_dim=0;k_dim<3;k_dim++)
00058         (*this)(k_dim,2)=v3[k_dim];
00059 }
00060 
00061 MC_matrix::MC_matrix(const MC_matrix& _M)
00062 {M=_M.M;for(int k_dim=0;k_dim<2;k_dim++){current_size[k_dim]=_M.current_size[k_dim];}}
00063 
00064 MC_matrix::~MC_matrix()
00065 {clear();}
00066 
00067 MC_matrix& MC_matrix::clear()
00068 {
00069   M.resize(0);
00070   current_size[0]=0;
00071   current_size[1]=0;
00072   return *this;
00073 }
00074 
00075 
00076 void MC_matrix::check_integrity() const
00077 {
00078   if(int(M.size())!=current_size[0]*current_size[1])
00079     {std::cout<<"Error in check_integrity in MC_matrix::check_integrity(), size of M is "<<M.size()<<", and size recorded is ("<<current_size[0]<<","<<current_size[1]<<")"<<std::endl;exit(-1);}
00080 }
00081 
00082 
00083 int MC_matrix::size_1() const {return current_size[0];}
00084 int MC_matrix::size_2() const {return current_size[1];}
00085 MC_int_vector MC_matrix::size() const
00086 {return MC_int_vector(current_size[0],current_size[1]);}
00087 int MC_matrix::size_vec() const
00088 {
00090   if(current_size[1]==1)
00091     return current_size[0];
00092   else if(current_size[0]==1)
00093     return current_size[1];
00094 
00095   std::cout<<"Error in MC_matrix::size_vec(), matrix is not a vector (size=("<<size()<<"))"<<std::endl;
00096   exit(-1);
00097 }
00098 
00099 double& MC_matrix::operator()(const int& k1,const int& k2)
00100 {
00101   if(k1<0 || k2<0)
00102     {std::cout<<"Error in MC_matrix::operator("<<k1<<","<<k2<<"), size=("<<size()<<")"<<std::endl;exit(-1);}
00103 
00104   // resize if needed
00105   if(k1>=current_size[0] || k2>=current_size[1])
00106     resize(std::max(k1+1,current_size[0]),std::max(k2+1,current_size[1]));
00107 
00108   int index=k1+current_size[0]*k2;
00109   if(index>=M.size()){std::cout<<"Error in MC_matrix::operator("<<k1<<","<<k2<<"), index="<<index<<" and size of M is "<<M.size()<<std::endl;exit(-1);}
00110 
00111   return M[index];
00112 }
00113 
00114 const double& MC_matrix::operator()(const int& k1,const int& k2) const
00115 {
00116   if(k1<0 || k1>=current_size[0] || k2<0 || k2>=current_size[1])
00117     {std::cout<<"Error in MC_matrix::operator("<<k1<<","<<k2<<"), size=("<<size()<<")"<<std::endl;exit(-1);}
00118 
00119   int index=k1+current_size[0]*k2;
00120   if(index>=M.size()){std::cout<<"Error in MC_matrix::operator("<<k1<<","<<k2<<"), index="<<index<<" and size of M is "<<M.size()<<std::endl;exit(-1);}
00121 
00122   return M[index];
00123 }
00124 
00125 
00126 double& MC_matrix::operator()(const int& k_index)
00127 {
00128   
00129   if(k_index<0)
00130     {std::cout<<"Error in MC_matrix::operator("<<k_index<<"), size=("<<M.size()<<")"<<std::endl;exit(-1);}
00131 
00132   if(k_index>=M.size())
00133     {
00134       if(size_2()==1)
00135         resize(k_index+1,1);
00136       else if(size_1()==1 || size_1()==0 || size_2()==0)
00137         resize(1,k_index+1);
00138       else
00139         {std::cout<<"Error in MC_matrix::operator("<<k_index<<"), size=("<<M.size()<<")"<<std::endl;exit(-1);}
00140     }
00141   return M[k_index];
00142 }
00143 
00144 const double& MC_matrix::operator()(const int& k_index) const
00145 {
00146   if(k_index<0 || k_index>=M.size())
00147     {std::cout<<"Error in MC_matrix::operator("<<k_index<<"), size=("<<M.size()<<")"<<std::endl;exit(-1);}
00148   return M[k_index];
00149 }
00150 
00151 MC_matrix& MC_matrix::resize(const MC_int_vector& new_size)
00152 {
00153 
00154     // do not change anything
00155     if( (new_size[0]==current_size[0]) && ((new_size[1]==current_size[1]) || (new_size[1]==-1&&new_size[0]==current_size[1])))
00156         return *this;
00157 
00158     MC_int_vector temp_new_size=new_size;
00159     if(new_size[1]==-1)
00160             temp_new_size[1]=temp_new_size[0];
00161 
00162     // copy
00163     MC_double_vector new_matrix=MC_double_vector::zeros(std::max(temp_new_size[0],current_size[0])*std::max(temp_new_size[1],current_size[1]));
00164 
00165     int L1=std::min(temp_new_size[0],current_size[0]);
00166     int L2=std::min(temp_new_size[1],current_size[1]);
00167     for(int k_1=0;k_1<L1;k_1++)
00168         for(int k_2=0;k_2<L2;k_2++)
00169             new_matrix[k_1+k_2*temp_new_size[0]] = M[k_1+k_2*current_size[0]];
00170 
00171 
00172     // record it
00173     M=new_matrix;
00174     current_size[0]=temp_new_size[0];
00175     current_size[1]=temp_new_size[1];
00176 
00177 
00178     return *this;
00179 
00180 }
00181 MC_matrix& MC_matrix::resize(const int& new_size_1,const int& new_size_2)
00182 {resize(MC_int_vector(new_size_1,new_size_2));return *this;}
00183 
00184 MC_matrix& MC_matrix::resize_1(const int& new_size_1)
00185 {resize(new_size_1,size_2());return *this;}
00186 MC_matrix& MC_matrix::resize_2(const int& new_size_2)
00187 {resize(size_1(),new_size_2);return *this;}
00188 
00189 std::ostream& operator<<(std::ostream& stream, const MC_matrix& _M)
00190 {
00191   int k_1=0,k_2=0;
00192   int N_1=_M.size_1(),N_2=_M.size_2();
00193   for(k_1=0;k_1<N_1;k_1++)
00194     {
00195       for(k_2=0;k_2<N_2;k_2++)
00196         stream<<_M(k_1,k_2)<<" ";
00197       stream<<std::endl;
00198     }
00199   return stream;
00200 }
00201 
00202 
00203 
00204 
00205 
00206 //
00207 //MC_matrix MC_matrix::submatrix(const char* string_index_x,const char* string_index_y) const
00208 //{return submatrix(std::string(string_index_x),std::string(string_index_y));}
00209 //
00210 //MC_matrix MC_matrix::submatrix(const std::string& string_index_x,const std::string& string_index_y) const
00211 //{
00212 //
00213 //  int start=0,end=0;
00214 //  double increment=0.0;
00215 //
00216 //  analyse_string(string_index_x,0,&start,&increment,&end);
00217 //  int_vector index_x = int_vector::linspace(start,increment,end);
00218 //
00219 //  analyse_string(string_index_y,1,&start,&increment,&end);
00220 //  int_vector index_y = int_vector::linspace(start,increment,end);
00221 //
00222 //  return submatrix(index_x,index_y);
00223 //}
00224 
00225 
00226 MC_matrix MC_matrix::operator()(const MC_int_vector& index_1,const MC_int_vector& index_2) const
00227 {
00228     MC_matrix temp_matrix;
00229 
00230     int k_index_1=0,N_index_1=index_1.size();
00231     int k_index_2=0,N_index_2=index_2.size();
00232     int current_x=0,current_y=0;
00233     for(k_index_1=0;k_index_1<N_index_1;k_index_1++)
00234     {
00235         current_x = index_1[k_index_1];
00236         for(k_index_2=0;k_index_2<N_index_2;k_index_2++)
00237         {
00238             current_y = index_2[k_index_2];
00239             temp_matrix(k_index_1,k_index_2) = (*this)(current_x,current_y);
00240         }
00241     }
00242 
00243     return temp_matrix;
00244 }
00245 
00246 
00247 // analyse "a:b:c"
00248 void MC_matrix::analyse_string(const std::string& to_analyse,int dim,int *start,double *increment,int *end) const
00249 {
00250   
00251   if(dim!=-1 && dim!=0 && dim!=1)
00252     {std::cout<<"Error in MC_matrix::analyse_string("<<to_analyse<<","<<dim<<", ...) dim="<<dim<<"should be 0 or 1"<<std::endl;exit(-1);}
00253   
00254   std::vector <std::string> token = mesh_conv::MC_string_tokenizer::tokenize(to_analyse,":");
00255   if(token.size()<1 || token.size()>3)
00256     {std::cout<<"Error in MC_matrix::analyse_string("<<to_analyse<<","<<dim<<", ...), cannot analyse string "<<to_analyse<<std::endl;exit(-1);}
00257 
00258   std::vector <std::string> token_start = mesh_conv::MC_string_tokenizer::tokenize(token[0],"-");
00259   std::vector <std::string> token_end = mesh_conv::MC_string_tokenizer::tokenize(token[token.size()-1],"-");
00260   int current_value=0;
00261   int temp_value=0;
00262 
00263   // special case of ":"
00264   if(to_analyse==":")
00265     {
00266       *start=0;
00267       if(dim==-1)
00268         *end=size_1()*size_2()-1;
00269       else if(dim==0)
00270         *end=size_1()-1;
00271       else
00272         *end=size_2()-1;
00273       *increment=1;
00274       return ;
00275     }
00276   // special case, only one number
00277   int number=0;
00278   if(token.size()==1)
00279   {
00280       bool is_converted=false;
00281       number = MC_string_converter::value_of<int>(to_analyse,&is_converted);
00282       if(is_converted==true)
00283       {
00284           *start=number;*end=number;*increment=1;
00285           return;
00286       }
00287   }
00288 
00289   for(unsigned int k=0;k<token_start.size();k++)
00290     {
00291       if(token_start[k]=="start")
00292         temp_value=0;
00293       else if(token_start[k]=="end")
00294           if(dim==-1)
00295               temp_value=size_1()*size_2()-1;
00296       else if(dim==0)
00297           temp_value=size_1()-1;
00298       else
00299           temp_value=size_2()-1;
00300       else
00301       {
00302           bool is_converted=false;
00303           temp_value=MC_string_converter::value_of<int>(token_start[k],&is_converted);
00304           if(is_converted==false)
00305           {std::cout<<"Error in MC_matrix::analyse_string("<<to_analyse<<","<<dim<<", ...), cannot interpret string"<<std::endl;exit(-1);}
00306       }
00307       
00308       if(k>0)
00309         current_value -= temp_value;
00310       else
00311         current_value = temp_value;
00312 
00313       *start = current_value;
00314     }
00315 
00316   current_value=0;
00317   for(unsigned int k=0;k<token_end.size();k++)
00318     {
00319       if(token_end[k]=="start")
00320         temp_value=0;
00321       else if(token_end[k]=="end")
00322         if(dim==-1)
00323           temp_value=size_1()*size_2()-1;
00324         else if(dim==0)
00325           temp_value=size_1()-1;
00326         else
00327           temp_value=size_2()-1;
00328         else
00329         {
00330             bool is_converted=false;
00331             temp_value=MC_string_converter::value_of<int>(token_end[k],&is_converted);
00332             if(is_converted==false)
00333             {std::cout<<"Error in MC_matrix::analyse_string("<<to_analyse<<","<<dim<<", ...), cannot interpret string"<<token_end[k]<<std::endl;exit(-1);}
00334         }
00335         if(k>0)
00336             current_value -= temp_value;
00337         else
00338             current_value = temp_value;
00339 
00340         *end = current_value;
00341     }
00342 
00343   if(token.size()==3)//there is an increment
00344     {
00345       bool is_converted=false;
00346       *increment = MC_string_converter::value_of <double>(token[1],&is_converted);
00347 
00348       if(is_converted==false)
00349       {std::cout<<"Error in MC_matrix::analyse_string("<<to_analyse<<","<<dim<<", ...), cannot interpret increment "<<token[1]<<std::endl;exit(-1);}
00350       return;
00351     }
00352   
00353   
00354   *increment=1;//default value
00355 
00356 }  
00357 
00358 void MC_matrix::analyse_string(const char* to_analyse,int dim,int *start,double *increment,int *end) const
00359 {analyse_string(std::string(to_analyse),dim,start,increment,end);}
00360 
00361 MC_matrix MC_matrix::reshaped_1(const int& new_size_1) const
00362 {
00363   int N=M.size();
00364   if(N%new_size_1 != 0)
00365     {std::cout<<"Error in MC_matrix::reshape_1("<<new_size_1<<") in MC_matrix, total size "<<M.size()<<" are not compatible"<<std::endl;exit(-1);}
00366   return reshaped(new_size_1,N/new_size_1);
00367 }
00368 
00369 MC_matrix MC_matrix::reshaped_2(const int& new_size_2) const
00370 {
00371   int N=M.size();
00372   if(N%new_size_2 != 0)
00373   {std::cout<<"Error in MC_matrix::reshape_2("<<new_size_2<<") in MC_matrix, total size "<<M.size()<<" are not compatible"<<std::endl;exit(-1);}
00374   return reshaped(N/new_size_2,new_size_2);
00375 }
00376 MC_matrix MC_matrix::reshaped(const MC_int_vector& new_size) const
00377 {
00378     // if do nothing
00379     if(new_size[0]==current_size[0] && new_size[1]==current_size[1])
00380         return *this;
00381 
00382   if(new_size[0]*new_size[1] != M.size())
00383     {std::cout<<"Error in MC_matrix::reshape("<<new_size<<"), total size should be "<<M.size()<<std::endl;exit(-1);}
00384 
00385   MC_matrix temp_matrix(new_size[0],new_size[1]);
00386 
00387   int k1=0,k2=0;
00388   int count=0;
00389   for(k2=0;k2<new_size[1];k2++)
00390     for(k1=0;k1<new_size[2];k1++)
00391       temp_matrix(k1,k2) = M[count++];
00392 
00393   return temp_matrix;
00394 }
00395 MC_matrix MC_matrix::reshaped(const int& new_size_1,const int& new_size_2) const
00396 {return reshaped(MC_int_vector(new_size_1,new_size_2));}
00397 
00398 MC_matrix MC_matrix::transposed() const
00399 {
00400   MC_matrix new_matrix(size_2(),size_1());
00401   int k1=0,N1=size_1();
00402   int k2=0,N2=size_2();
00403   for(k1=0;k1<N1;k1++)
00404     for(k2=0;k2<N2;k2++)
00405       new_matrix(k2,k1)=(*this)(k1,k2);
00406   return new_matrix;
00407 }
00408 
00409 
00410 MC_matrix MC_matrix::zeros(const int& new_size_1,const int& new_size_2)
00411 {return MC_matrix(new_size_1,new_size_2);}
00412 MC_matrix MC_matrix::zeros(const int& new_size)
00413 {return MC_matrix(new_size);}
00414 
00415 MC_matrix MC_matrix::identity(const int& new_size)
00416 {
00417   MC_matrix temp(new_size);
00418   for(int k=0;k<new_size;k++)
00419     temp(k,k)=1;
00420   return temp;
00421 }
00422 
00423 MC_matrix& MC_matrix::set_block(const MC_int_vector& index_1,const MC_int_vector& index_2,const MC_matrix& block)
00424 {
00425   int k1=0,N1=index_1.size();
00426   int k2=0,N2=index_2.size();
00427 
00428   if(N1!=block.size_1() || N2!=block.size_2())
00429     {std::cout<<"Error in MC_matrix::set_block(MC_int_vector,MC_int_vector,MC_matrix), size are not compatible ("<<N1<<","<<N2<<") - ("<<block.size_1()<<","<<block.size_2()<<")"<<std::endl;exit(-1);}
00430 
00431   for(k1=0;k1<N1;k1++)
00432     for(k2=0;k2<N2;k2++)
00433       (*this)(index_1[k1],index_2[k2])=block(k1,k2);
00434 
00435   return *this;
00436 }
00437 
00438 MC_matrix& MC_matrix::set_block(const int& start_x,const int& end_x,const int& start_y,const int& end_y,const MC_matrix& block)
00439 {return set_block(MC_int_vector::linspace(start_x,end_x),MC_int_vector::linspace(start_y,end_y),block);}
00440 
00441 MC_matrix MC_matrix::repmat(const int& k_repeat) const
00442 {return repmat(k_repeat,k_repeat);}
00443 MC_matrix MC_matrix::repmat(const MC_int_vector& k_repeat) const
00444 {
00445     if(k_repeat.size()!=2)
00446     {std::cout<<"Error in MC_matrix::repmat("<<k_repeat<<"), size must be 2"<<std::endl;exit(-1);}
00447     return repmat(k_repeat[0],k_repeat[1]);
00448 }
00449 MC_matrix MC_matrix::repmat(const int& k_repeat_1,const int& k_repeat_2) const
00450 {
00451     MC_matrix new_matrix(k_repeat_1*size_1(),k_repeat_2*size_2());
00452 
00453     MC_int_vector L1,L2;
00454     int k1=0,k2=0;
00455     for(k1=0;k1<k_repeat_1;k1++)
00456     {
00457         L1 = MC_int_vector::linspace(k1*size_1(),(k1+1)*size_1()-1);
00458         for(k2=0;k2<k_repeat_2;k2++)
00459         {
00460             L2 = MC_int_vector::linspace(k2*size_2(),(k2+1)*size_2()-1);
00461             new_matrix.set_block(L1,L2,(*this));
00462         }
00463     }
00464     return new_matrix;
00465 }
00466 
00467 MC_matrix MC_matrix::repmat_1(const int& k_repeat_1) const {return repmat(k_repeat_1,1);}
00468 MC_matrix MC_matrix::repmat_2(const int& k_repeat_2) const {return repmat(1,k_repeat_2);}
00469 
00470 
00471 MC_matrix operator+(const MC_matrix& M1,const double& alpha)
00472 {
00473   MC_matrix temp=M1;
00474   int k1=0,k2=0;
00475   int N1=M1.size_1(),N2=M1.size_2();
00476   for(k1=0;k1<N1;k1++)
00477     for(k2=0;k2<N2;k2++)
00478       temp(k1,k2)+=alpha;
00479   return temp;
00480 }
00481 MC_matrix operator+(const double& alpha,const MC_matrix& M1)
00482 {return M1+alpha;}
00483 
00484 MC_matrix operator-(const MC_matrix& M1,const double& alpha)
00485 {
00486   MC_matrix temp=M1;
00487   int k1=0,k2=0;
00488   int N1=M1.size_1(),N2=M1.size_2();
00489   for(k1=0;k1<N1;k1++)
00490     for(k2=0;k2<N2;k2++)
00491       temp(k1,k2)-=alpha;
00492   return temp;
00493 }
00494 MC_matrix operator-(const double& alpha,const MC_matrix& M1)
00495 {
00496   MC_matrix temp=M1;
00497   int k1=0,k2=0;
00498   int N1=M1.size_1(),N2=M1.size_2();
00499   for(k1=0;k1<N1;k1++)
00500     for(k2=0;k2<N2;k2++)
00501       temp(k1,k2)=alpha-M1(k1,k2);
00502   return temp;
00503 }
00504 
00505 MC_matrix operator*(const MC_matrix& M1,const double& alpha)
00506 {
00507   MC_matrix temp=M1;
00508   int k1=0,k2=0;
00509   int N1=M1.size_1(),N2=M1.size_2();
00510   for(k1=0;k1<N1;k1++)
00511     for(k2=0;k2<N2;k2++)
00512       temp(k1,k2)*=alpha;
00513   return temp;
00514 }
00515 MC_matrix operator*(const double& alpha,const MC_matrix& M1)
00516 {return M1*alpha;}
00517 MC_matrix operator/(const MC_matrix& M1,const double& alpha)
00518 {
00519 
00520     double epsilon=0.000001;
00521     if(abs(alpha)<epsilon)
00522     {std::cout<<"Error in MC_matrix::operator/("<<alpha<<"), value too small"<<std::endl;exit(-1);}
00523 
00524     MC_matrix temp=M1;
00525     int k1=0,k2=0;
00526     int N1=M1.size_1(),N2=M1.size_2();
00527     for(k1=0;k1<N1;k1++)
00528         for(k2=0;k2<N2;k2++)
00529             temp(k1,k2)/=alpha;
00530     return temp;
00531 }
00532 MC_matrix operator/(const double& alpha,const MC_matrix& M1)
00533 {
00534   double epsilon=0.000001;
00535   
00536   double current=0.0;
00537   MC_matrix temp=M1;
00538   int k1=0,k2=0;
00539   int N1=M1.size_1(),N2=M1.size_2();
00540   for(k1=0;k1<N1;k1++)
00541     for(k2=0;k2<N2;k2++)
00542       {
00543         current = M1(k1,k2);
00544         if(abs(current)<epsilon)
00545           {std::cout<<"Error in MC_matrix::operator/("<<alpha<<"), value too small at ("<<k1<<","<<k2<<")"<<std::endl;exit(-1);}
00546 
00547         temp(k1,k2)=alpha/current;
00548       }
00549   return temp;
00550 }
00551 
00552 MC_matrix operator+(const MC_matrix& M1,const MC_matrix& M2)
00553 {
00554   if(M1.size_1()!=M2.size_1() || M1.size_2()!=M2.size_2())
00555     {std::cout<<"Error in MC_matrix::operator+(matrix,matrix), size are not compatible ("<<M1.size_1()<<","<<M1.size_2()<<")!=("<<M2.size_1()<<","<<M2.size_2()<<std::endl;exit(-1);}
00556   
00557   MC_matrix temp(M1.size_1(),M1.size_2());
00558   int k=0,N=M1.M.size();
00559   for(k=0;k<N;k++)
00560     temp.M[k] = M1.M[k]+M2.M[k];
00561   return temp;
00562 }
00563 
00564 MC_matrix operator-(const MC_matrix& M1,const MC_matrix& M2)
00565 {
00566   if(M1.size_1()!=M2.size_1() || M1.size_2()!=M2.size_2())
00567     {std::cout<<"Error in MC_matrix::operator-(matrix,matrix), size are not compatible ("<<M1.size_1()<<","<<M1.size_2()<<")!=("<<M2.size_1()<<","<<M2.size_2()<<std::endl;exit(-1);}
00568   
00569   MC_matrix temp(M1.size_1(),M1.size_2());
00570   int k=0,N=M1.M.size();
00571   for(k=0;k<N;k++)
00572     temp.M[k] = M1.M[k]-M2.M[k];
00573   return temp;
00574 }
00575 
00576 MC_matrix operator*(const MC_matrix& M1,const MC_matrix& M2)
00577 {
00578   if(M1.size_2()!=M2.size_1())
00579     {std::cout<<"Error in MC_matrix::operator*(matrix,matrix), size are not compatible ("<<M1.size_1()<<","<<M1.size_2()<<") x ("<<M2.size_1()<<","<<M2.size_2()<<")"<<std::endl;exit(-1);}
00580   
00581   MC_matrix temp(M1.size_1(),M2.size_2());
00582   int k=0,N=M1.size_2();
00583   int k1=0,k2=0;
00584   int N1=M1.size_1(),N2=M2.size_2();
00585   for(k1=0;k1<N1;k1++)
00586     for(k2=0;k2<N2;k2++)
00587       for(k=0;k<N;k++)
00588         temp(k1,k2) += M1(k1,k)*M2(k,k2);
00589 
00590   return temp;
00591 }
00592 
00593 
00594 
00595 
00596 MC_matrix MC_matrix::inverted() const
00597 {
00598     if(size_1()!=size_2())
00599     {std::cout<<"Error in MC_matrix::invertd(), matrix is not square ! ("<<size_1()<<","<<size_2()<<")"<<std::endl;exit(-1);}
00600 
00601 
00603     double epsilon=0.0000001;
00604     if(size_1()==2 && size_2()==2)
00605     {
00606         double det=(*this)(0,0)*(*this)(1,1)-(*this)(1,0)*(*this)(0,1);
00607         if(std::abs(det)<epsilon)
00608         {std::cout<<"Error in MC_matrix::inverted() (2x2), matrix has null determinant"<<std::endl;}
00609         MC_matrix res(2);
00610         res(0,0)= (*this)(1,1);
00611         res(1,0)=-(*this)(1,0);
00612         res(0,1)=-(*this)(0,1);
00613         res(1,1)= (*this)(0,0);
00614         res/=det;
00615         return res;
00616     }
00617     else if(size_1()==3 && size_2()==3)
00618     {
00619         double v00=(*this)(0,0),v01=(*this)(0,1),v02=(*this)(0,2);
00620         double v10=(*this)(1,0),v11=(*this)(1,1),v12=(*this)(1,2);
00621         double v20=(*this)(2,0),v21=(*this)(2,1),v22=(*this)(2,2);
00622 
00623         double det=
00624                 +v00*(v11*v22-v12*v21)
00625                 -v01*(v10*v22-v12*v20)
00626                 +v02*(v10*v21-v11*v20);
00627 
00628 
00629 
00630         if(std::abs(det)<epsilon)
00631         {std::cout<<"Warning in MC_matrix::inverted() (3x3), matrix has null determinant"<<std::endl;return MC_matrix::identity(3);}
00632 
00633         MC_matrix res(3);
00634         res(0,0) = v11*v22-v12*v21;
00635         res(0,1) = v02*v21-v01*v22;
00636         res(0,2) = v01*v12-v02*v11;
00637 
00638         res(1,0) = v12*v20-v10*v22;
00639         res(1,1) = v00*v22-v02*v20;
00640         res(1,2) = v02*v10-v00*v12;
00641 
00642         res(2,0) = v10*v21-v11*v20;
00643         res(2,1) = v01*v20-v00*v21;
00644         res(2,2) = v00*v11-v01*v10;
00645 
00646 
00647         res/=det;
00648         return res;
00649     }
00650     else
00651     {
00652         exit(-1);
00653 
00654     }
00655     exit(-1);
00656 
00657 }
00658 
00659 
00660 
00661 
00662 
00663 
00664 
00665 MC_matrix MC_matrix::lsqr_invert() const
00666 {return ( ((*this).transposed()) * (*this) ).inverted() * (*this).transposed();}
00667 
00668 
00669 MC_matrix operator*(const MC_matrix& M1,const MC_v3d& V)
00670 {
00671   MC_matrix vec(V);
00672 
00673   
00674   if(M1.size_2()==4)
00675     vec(3,0)=1; //automatic add the 1 value
00676 
00677 
00678   if(M1.size_2()==3 || M1.size_2()==4) 
00679     {return M1*vec;}
00680   else {std::cout<<"Error in MC_matrix::operator*(MC_matrix,MC_v3d), size of Matrix ("<<M1.size_1()<<","<<M1.size_2()<<") are not compatible"<<std::endl;exit(-1);}
00681   
00682 }
00683 
00684 
00685 MC_matrix MC_matrix::rotation_axis_to_axis(const MC_v3d& a1,const MC_v3d& a2)
00686 {
00687 
00688   MC_v3d v0,v1;
00689   v0 = a1.normalized();
00690   v1 = a2.normalized();
00691 
00692   MC_v3d n = (v0.cross(v1));
00693   if(n.norm()<0.00001)
00694   {
00695       return MC_matrix::identity(3);
00696       //std::cout<<"Warning in MC_matrix::rotation_axis_to_axis("<<a1<<","<<a2<<"), parralel vector or norm is null, axis of rotation has norm="<<n.norm()<<std::endl;
00697   }
00698   n=n.normalized();
00699 
00700   double cos_t = v0.dot(v1);
00701   double sin_t = pow(fabs(1.0-cos_t*cos_t),0.5);
00702 
00703   MC_matrix R(3,3);
00704   R(0,0) = cos_t+n[0]*n[0]*(1-cos_t);
00705   R(1,0) = n[2]*sin_t+n[0]*n[1]*(1-cos_t);
00706   R(2,0) =-n[1]*sin_t+n[0]*n[2]*(1-cos_t);
00707 
00708   R(0,1) = n[0]*n[1]*(1-cos_t)-n[2]*sin_t;
00709   R(1,1) = cos_t+n[1]*n[1]*(1.0-cos_t);
00710   R(2,1) = n[0]*sin_t+n[1]*n[2]*(1-cos_t);
00711 
00712   R(0,2) = n[1]*sin_t+n[0]*n[2]*(1-cos_t);
00713   R(1,2) =-n[0]*sin_t+n[1]*n[2]*(1-cos_t);
00714   R(2,2) = cos_t+n[2]*n[2]*(1-cos_t);
00715 
00716   return R;
00717 
00718 }
00719 
00720 
00721 
00722 
00723 
00724 MC_matrix MC_matrix::operator()(const std::string& string_index)
00725 {
00726     int start=0;
00727     double increment=0;
00728     int end=0;
00729 
00730     analyse_string(string_index,-1,&start,&increment,&end);
00731     return (*this)(MC_int_vector::linspace(start,end,increment));
00732 }
00733 MC_matrix MC_matrix::operator()(const MC_int_vector& index)
00734 {
00735     MC_matrix new_matrix(index.size(),1);
00736     int N=index.size();
00737     for(int k=0;k<N;k++)
00738         new_matrix(k)=(*this)(index[k]);
00739     return new_matrix;
00740 
00741 }
00742 
00743 MC_matrix MC_matrix::operator()(const std::string& string_index_1,const std::string& string_index_2)
00744 {
00745     int start=0,end=0;
00746     double increment=0.0;
00747 
00748     analyse_string(string_index_1,0,&start,&increment,&end);
00749     MC_int_vector index_x = MC_int_vector::linspace(start,end,increment);
00750 
00751     analyse_string(string_index_2,1,&start,&increment,&end);
00752     MC_int_vector index_y = MC_int_vector::linspace(start,end,increment);
00753 
00754     return (*this)(index_x,index_y);
00755 }
00756 
00757 MC_matrix MC_matrix::rotation(const MC_v3d& _n,const double& angle)
00758 {
00759   MC_v3d n=_n.normalized();
00760 
00761 
00762 
00763   double cos_t = cos(angle);
00764   double sin_t = sin(angle);
00765 
00766   MC_matrix R(3,3);
00767 
00768   R(0,0) = cos_t+n[0]*n[0]*(1-cos_t);
00769   R(1,0) = n[2]*sin_t+n[0]*n[1]*(1-cos_t);
00770   R(2,0) =-n[1]*sin_t+n[0]*n[2]*(1-cos_t);
00771 
00772   R(0,1) = n[0]*n[1]*(1-cos_t)-n[2]*sin_t;
00773   R(1,1) = cos_t+n[1]*n[1]*(1.0-cos_t);
00774   R(2,1) = n[0]*sin_t+n[1]*n[2]*(1-cos_t);
00775 
00776   R(0,2) = n[1]*sin_t+n[0]*n[2]*(1-cos_t);
00777   R(1,2) =-n[0]*sin_t+n[1]*n[2]*(1-cos_t);
00778   R(2,2) = cos_t+n[2]*n[2]*(1-cos_t);
00779   
00780   return R;
00781 }
00782 
00783 
00784 
00785 
00786 const double& MC_matrix::to_double() const
00787 {
00788   if(size_1()==1 && size_2()==1)
00789     return M[0];
00790   else
00791     {std::cout<<"Error in MC_matrix::to_double(), size are not compatible (1,1) => ("<<size_1()<<","<<size_2()<<")"<<std::endl; exit(-1);}
00792 
00793 }
00794 
00795 double MC_matrix::norm_2() const
00796 {
00797   int k_1=0,k_2=0;
00798   double n=0.0;
00799   for(k_1=0;k_1<current_size[0];k_1++)
00800     for(k_2=0;k_2<current_size[1];k_2++)
00801       n += (*this)(k_1,k_2)*(*this)(k_1,k_2);
00802   n = pow(n,0.5);
00803 
00804   return n;
00805 }
00806 
00807 
00808 MC_matrix& MC_matrix::operator+=(const double& a)
00809 {
00810   int N=M.size();
00811   for(int k=0;k<N;k++)
00812     M[k]+=a;
00813   return *this;
00814 }
00815 
00816 MC_matrix& MC_matrix::operator+=(const MC_matrix& _m)
00817 {
00818   if(_m.size_1()!=size_1() || _m.size_2()!=size_2())
00819     {std::cout<<"Error in MC_matrix::operator+=(MC_matrix), size are not compatible ("<<size_1()<<","<<size_2()<<") != ("<<_m.size_1()<<","<<_m.size_2()<<")"<<std::endl;exit(-1);}
00820   
00821   int N=M.size();
00822   for(int k=0;k<N;k++)
00823     M[k]+=_m(k);
00824 
00825   return *this;
00826 }
00827 
00828 MC_matrix& MC_matrix::operator*=(const double& a)
00829 {
00830   int N=M.size();
00831   for(int k=0;k<N;k++)
00832     M[k]*=a;
00833 
00834   return *this;
00835 }
00836 
00837 MC_matrix& MC_matrix::operator/=(const double& a)
00838 {
00839   double epsilon=0.00000001;
00840   if(std::abs(a)<epsilon)
00841     {std::cout<<"Error in MC_matrix::operator/=("<<a<<"), divide by zero"<<std::endl;exit(-1);}
00842 
00843   int N=M.size();
00844   for(int k=0;k<N;k++)
00845     M[k]/=a;
00846 
00847   return *this;
00848 }
00849 
00850 
00851 MC_matrix MC_matrix::exp_m() const
00852 {
00853 
00854   if(size_1()!=size_2())
00855     {std::cout<<"Error in MC_matrix::exp(), matrix is not square ("<<size_1()<<","<<size_2()<<")"<<std::endl;exit(-1);}
00856   
00857 
00858   MC_matrix A=*this;
00859   double j=std::max(double(0.0),double(1.0+floor(logf(float(A.norm_2()))/logf(2.0))));
00860 
00861 
00862   A = A*pow(2.0,-j);
00863   MC_matrix D=MC_matrix::identity(size_1());
00864   MC_matrix N=D;
00865   MC_matrix X=D;
00866   double c=1.0;
00867 
00868   int q=6;
00869   for(int k=1;k<=q;k++)
00870     {
00871       c = c*(q-k+1)/(k*(2*q-k+1));
00872       X = A*X;
00873       N = N+c*X;
00874       D = D+pow(-1.0,k)*c*X;
00875     }
00876 
00877   X = D.inverted()*N;
00878   X = X.pow_m(int(pow(2.0,j)));
00879 
00880 
00881   return X;
00882 }
00883 
00884 MC_matrix MC_matrix::pow_m(const int& k_pow) const
00885 {
00886   if(size_1()!=size_2())
00887     {std::cout<<"Error in MC_matrix::pow(), matrix is not square ("<<size_1()<<","<<size_2()<<")"<<std::endl;exit(-1);}
00888 
00889   if(k_pow<0)
00890     {std::cout<<"Error in MC_matrix::pow("<<k_pow<<"), k_pow must be positiv"<<std::endl;exit(-1);}
00891 
00892   MC_matrix Res = MC_matrix::identity(size_1());
00893   for(int k=0;k<k_pow;k++)
00894     Res = Res*(*this);
00895   return Res;
00896 }
00897 
00898 
00899 MC_matrix& MC_matrix::add_row(const MC_v3d& x0)
00900 {
00901   if(size_2()!=3)
00902     {std::cout<<"Error in MC_matrix::add_row, size_2="<<size_2()<<" and must be 3"<<std::endl;exit(-1);}
00903   
00904   int Nx = size_1();
00905   resize(Nx+1,3);
00906   set_block(Nx+1,Nx+1,0,2,MC_matrix(x0));
00907 
00908   return *this;
00909 }
00910 MC_matrix& MC_matrix::add_row(const MC_v3d& x0,const MC_v3d& x1)
00911 {add_row(x0); add_row(x1); return *this;}
00912 MC_matrix& MC_matrix::add_row(const MC_v3d& x0,const MC_v3d& x1,const MC_v3d& x2)
00913 {add_row(x0,x1); add_row(x2); return *this;}
00914 
00915 MC_matrix& MC_matrix::add_col(const MC_v3d& x0)
00916 {
00917   if(size_1()!=3)
00918     {std::cout<<"Error in MC_matrix::add_col, size_1="<<size_1()<<" and must be 3"<<std::endl;exit(-1);}
00919   
00920   int Ny = size_2();
00921   resize(2,Ny+1);
00922   set_block(0,2,Ny+1,Ny+1,MC_matrix(x0));
00923 
00924   return *this;
00925 }
00926 MC_matrix& MC_matrix::add_col(const MC_v3d& x0,const MC_v3d& x1)
00927 {add_col(x0); add_col(x1); return *this;}
00928 MC_matrix& MC_matrix::add_col(const MC_v3d& x0,const MC_v3d& x1,const MC_v3d& x2)
00929 {add_col(x0,x1); add_col(x2); return *this;
00930 }
00931 
00932 std::pair <MC_matrix,MC_matrix> MC_matrix::polar_decomposition() const
00933 {
00934   int counter=0;
00935   int max_counter=2000;
00936   bool loop_finished=false;
00937 
00938   MC_matrix R0=*this;
00939   MC_matrix R1;
00940   double epsilon=0.000001;
00941 
00942   while(loop_finished==false)
00943     {
00944 
00945       R1 = 0.5*(R0+R0.inverted().transposed());
00946 
00947       counter++;
00948       if(counter>=max_counter || (R1-R0).norm_2()<epsilon)
00949         loop_finished=true;
00950       else
00951         R0=R1;
00952     }
00953   
00954   if(counter>=max_counter)
00955     {std::cout<<"Error in MC_matrix::polar_decomposition(), no convergence"<<std::endl;exit(-1);}
00956 
00957   MC_matrix U = R1.inverted()*(*this);
00958 
00959   return std::pair<MC_matrix,MC_matrix>(R1,U);
00960 }
00961 
00962 double MC_matrix::trace() const
00963 {
00964   if(size_1()!=size_2())
00965     {std::cout<<"Error in MC_matrix::trace(), not a square matrix"<<std::endl;exit(-1);}
00966 
00967   double tr=0.0;
00968   for(int k=0;k<size_1();k++)
00969     tr += (*this)(k,k);
00970 
00971   return tr;
00972   
00973 }
00974 
00975 MC_matrix& MC_matrix::add_col(const MC_double_vector& col)
00976 {
00977   if(size_1()==0 && size_2()==0)
00978     {resize(col.size(),1);return set_col(0,col);}
00979   
00980   if(size_1()!=col.size())
00981     {std::cout<<"Error in MC_matrix::add_col(double_vector), size are not compatible: matrix is ("<<size_1()<<"x"<<size_2()<<"), and column vector has size "<<col.size()<<std::endl;exit(-1);}
00982   
00983   resize(size_1(),size_2()+1);
00984   return set_col(size_2()-1,col);
00985 }
00986 
00987 MC_matrix& MC_matrix::add_row(const MC_double_vector& row)
00988 {
00989   if(size_1()==0 && size_2()==0)
00990     {resize(1,row.size());return set_row(0,row);}
00991   
00992   if(size_2()!=row.size())
00993     {std::cout<<"Error in MC_matrix::add_row(double_vector), size are not compatible: matrix is ("<<size_1()<<"x"<<size_2()<<"), and row vector has size "<<row.size()<<std::endl;exit(-1);}
00994   
00995   resize(size_1()+1,size_2());
00996   return set_row(size_1()-1,row);
00997 }
00998 
00999 MC_matrix& MC_matrix::set_col(const int& id_col,const MC_double_vector& col)
01000 {
01001   int N=col.size();
01002   for(int k=0;k<N;k++)
01003     (*this)(k,id_col)=col(k);
01004   return *this;
01005 }
01006 MC_matrix& MC_matrix::set_row(const int& id_row,const MC_double_vector& row)
01007 {
01008   int N=row.size();
01009   for(int k=0;k<N;k++)
01010     (*this)(id_row,k)=row(k);
01011   return *this;
01012 }
01013 
01014 std::pair<std::vector <MC_matrix>,std::vector <MC_matrix> > MC_matrix::polar_decomposition(const std::vector <MC_matrix>& v_m)
01015 {
01016   std::pair <std::vector<MC_matrix>,std::vector<MC_matrix> > ret;
01017   int N=v_m.size();
01018   ret.first.resize(N);
01019   ret.second.resize(N);
01020 
01021   for(int k=0;k<N;k++)
01022     {
01023       std::pair <MC_matrix,MC_matrix> temp_polar=v_m[k].polar_decomposition();
01024       ret.first[k]=temp_polar.first;
01025       ret.second[k]=temp_polar.second;
01026     }
01027   return ret;
01028 }
01029 
01030 
01031 std::pair <MC_matrix,std::vector <MC_matrix> > MC_matrix::rotation_axis_to_axis_with_gradient(const MC_v3d& a0,const MC_v3d& a1)
01032 {
01033   double epsilon=0.00001;
01034   if(abs(a0.norm()-1.0)>epsilon || abs(a1.norm()-1.0)>epsilon)
01035     {std::cout<<"Error in rotation_axis_to_axis_with_gradient(), vector are not of norm 1"<<std::endl;exit(-1);}
01036 
01037 
01038   std::pair <MC_v3d,MC_v3d_vector> n_grad = (a0.cross(a1)).normalized_with_gradient();
01039   MC_v3d n =n_grad.first;
01040   MC_v3d_vector gradient_normal=n_grad.second;
01041 
01042   double cos_t=a0.dot(a1);
01043   double sin_t=pow(abs(1-cos_t*cos_t),0.5);
01044   
01045   MC_matrix R(3,3);
01046   R(0,0) = cos_t+n[0]*n[0]*(1-cos_t);
01047   R(1,0) = n[2]*sin_t+n[0]*n[1]*(1-cos_t);
01048   R(2,0) =-n[1]*sin_t+n[0]*n[2]*(1-cos_t);
01049 
01050   R(0,1) = n[0]*n[1]*(1-cos_t)-n[2]*sin_t;
01051   R(1,1) = cos_t+n[1]*n[1]*(1.0-cos_t);
01052   R(2,1) = n[0]*sin_t+n[1]*n[2]*(1-cos_t);
01053 
01054   R(0,2) = n[1]*sin_t+n[0]*n[2]*(1-cos_t);
01055   R(1,2) =-n[0]*sin_t+n[1]*n[2]*(1-cos_t);
01056   R(2,2) = cos_t+n[2]*n[2]*(1-cos_t);
01057 
01058 
01059   double x00=a0[0],x01=a0[1],x02=a0[2];
01060   double x10=a1[0],x11=a1[1],x12=a1[2];
01061 
01062 
01063   // nabla cos(t)
01064   MC_double_vector nabla_c=MC_double_vector(x10)<<x11<<x12<<x00<<x01<<x02;
01065   // nabla sin(t)
01066   MC_double_vector nabla_s=-cos_t/(sin_t+epsilon)*nabla_c;
01067 
01068 
01069   // nabla nx
01070   MC_double_vector nabla_nx=MC_double_vector(0.0)<<x12<<-x11<<0.0<<-x02<<x01;
01071   // nabla ny
01072   MC_double_vector nabla_ny=MC_double_vector(-x12)<<0.0<<x10<<x02<<0.0<<-x00;
01073   // nabla nz
01074   MC_double_vector nabla_nz=MC_double_vector(x11)<<-x10<<0.0<<-x01<<x00<<0.0;
01075 
01076 
01077 
01078   MC_v3d_vector gradient_normalized(6);
01079   for(int k=0;k<6;k++)
01080     for(int k_dim=0;k_dim<3;k_dim++)
01081       gradient_normalized[k][k_dim]=gradient_normal[k_dim].dot(MC_v3d(nabla_nx[k],nabla_ny[k],nabla_nz[k]));
01082 
01083 
01084   nabla_nx=gradient_normalized.component(0);
01085   nabla_ny=gradient_normalized.component(1);
01086   nabla_nz=gradient_normalized.component(2);
01087 
01088 
01089   //voir calculs
01090   std::vector <MC_matrix> nabla_R(6);
01091   for(int k=0;k<6;k++)
01092     {
01093       nabla_R[k].resize(3,3);
01094 
01095       
01096       nabla_R[k](0,0) = nabla_c[k]+2*n[0]*(1-cos_t)*nabla_nx[k]-n[0]*n[0]*nabla_c[k];
01097       nabla_R[k](1,0) = sin_t*nabla_nz[k]+n[2]*nabla_s[k]+n[1]*(1-cos_t)*nabla_nx[k]+n[0]*(1-cos_t)*nabla_ny[k]-n[0]*n[1]*nabla_c[k];
01098       nabla_R[k](2,0) = -sin_t*nabla_ny[k]-n[1]*nabla_s[k]+n[2]*(1-cos_t)*nabla_nx[k]+n[0]*(1-cos_t)*nabla_nz[k]-n[0]*n[2]*nabla_c[k];
01099 
01100 
01101       nabla_R[k](0,1) = nabla_nx[k]*n[1]*(1-cos_t)+n[0]*(1-cos_t)*nabla_ny[k]-n[0]*n[1]*nabla_c[k]-sin_t*nabla_nz[k]-n[2]*nabla_s[k];
01102       nabla_R[k](1,1) = nabla_c[k]+2*n[1]*(1-cos_t)*nabla_ny[k]-n[1]*n[1]*nabla_c[k];
01103       nabla_R[k](2,1) = sin_t*nabla_nx[k]+n[0]*nabla_s[k]+n[2]*(1-cos_t)*nabla_ny[k]+n[1]*(1-cos_t)*nabla_nz[k]-n[1]*n[2]*nabla_c[k];
01104 
01105       nabla_R[k](0,2) = sin_t*nabla_ny[k]+n[1]*nabla_s[k]+n[2]*(1-cos_t)*nabla_nx[k]+n[0]*(1-cos_t)*nabla_nz[k]-n[0]*n[2]*nabla_c[k];
01106       nabla_R[k](1,2) = -sin_t*nabla_nx[k]-n[0]*nabla_s[k]+n[2]*(1-cos_t)*nabla_ny[k]+n[1]*(1-cos_t)*nabla_nz[k]-n[1]*n[2]*nabla_c[k];
01107       nabla_R[k](2,2) = nabla_c[k]+2*n[2]*(1-cos_t)*nabla_nz[k]-n[2]*n[2]*nabla_c[k];
01108     
01109 
01110     }
01111 
01112   return std::pair <MC_matrix,std::vector <MC_matrix> > (R,nabla_R);
01113 }
01114 
01115 void MC_matrix::internal_product(MC_v3d* to_multiply) const
01116 {
01117     if(to_multiply)
01118     {
01119         double x0=(*to_multiply)[0];
01120         double x1=(*to_multiply)[1];
01121         double x2=(*to_multiply)[2];
01122 
01123         if(size_1()==3 && size_2()==3)
01124         {
01125 
01126             (*to_multiply)[0]= M[0]*x0+M[3]*x1+M[6]*x2;
01127             (*to_multiply)[1]= M[1]*x0+M[4]*x1+M[7]*x2;
01128             (*to_multiply)[2]= M[2]*x0+M[5]*x1+M[8]*x2;
01129             return ;
01130 
01131         }
01132         else if(size_1()==4 && size_2()==4) //add the 1 automatically
01133         {
01134             (*to_multiply)[0]= M[0]*x0+M[4]*x1+M[8]*x2+M[12];
01135             (*to_multiply)[1]= M[1]*x0+M[5]*x1+M[9]*x2+M[13];
01136             (*to_multiply)[2]= M[2]*x0+M[6]*x1+M[10]*x2+M[14];
01137         }
01138         else
01139         {std::cout<<"Error in MC_matrix::internal_product(MC_v3d* "<<*to_multiply<<"), size of the matrix is "<<size()<<std::endl;exit(-1);}
01140 
01141     }
01142     else
01143     {std::cout<<"Error in MC_matrix::internal_product(MC_v3d* ), the pointer is null"<<std::endl;exit(-1);}
01144 }
01145 
01146 void MC_matrix::internal_product(MC_v4d* to_multiply) const
01147 {
01148     if(to_multiply)
01149     {
01150         double x0=(*to_multiply)[0];
01151         double x1=(*to_multiply)[1];
01152         double x2=(*to_multiply)[2];
01153         double x3=(*to_multiply)[3];
01154 
01155         if(size_1()==4 && size_2()==4)
01156         {
01157             (*to_multiply)[0]= M[0]*x0+M[4]*x1+M[8]*x2+M[12]*x3;
01158             (*to_multiply)[1]= M[1]*x0+M[5]*x1+M[9]*x2+M[13]*x3;
01159             (*to_multiply)[2]= M[2]*x0+M[6]*x1+M[10]*x2+M[14]*x3;
01160             (*to_multiply)[3]= M[3]*x0+M[7]*x1+M[11]*x2+M[15]*x3;
01161         }
01162         else
01163         {std::cout<<"Error in MC_matrix::internal_product(MC_v4d* "<<*to_multiply<<"), size of the matrix is "<<size()<<std::endl;exit(-1);}
01164 
01165     }
01166     else
01167     {std::cout<<"Error in MC_matrix::internal_product(MC_v4d* ), the pointer is null"<<std::endl;exit(-1);}
01168 }
01169 
01170 
01171 MC_v3d MC_matrix::translation_part() const
01172 {
01173     if(size_1()!=4 || size_2()!=4)
01174     {std::cout<<"Error in MC_matrix::translation_part(), size of the matrix is not 4x4 but "<<size()<<std::endl;exit(-1);}
01175 
01176     return MC_v3d((*this)(0,3),(*this)(1,3),(*this)(2,3));
01177 }
01178 
01179 MC_matrix& MC_matrix::add_translation(const MC_v3d& tr)
01180 {
01181     if(size_1()!=4 || size_2()!=4)
01182     {std::cout<<"Error in MC_matrix::add_translation("<<tr<<"), size of the matrix should be 4x4 and not "<<size()<<std::endl;exit(-1);}
01183     M[12]+=tr[0];M[13]+=tr[1];M[14]+=tr[2];
01184     return *this;
01185 }
01186 
01187 
01188 MC_matrix MC_matrix::to_matrix4() const
01189 {
01190     if(size_1()==4 && size_2()==4)
01191         return *this;
01192     else if(size_1()==3 && size_2()==3)
01193     {
01194         MC_matrix m4=MC_matrix::identity(4);
01195         m4.set_block(0,2,0,2,*this);
01196         return m4;
01197     }
01198     else
01199     {std::cout<<"Error in MC_matrix::to_matrix4(), size must be 3x3 and not "<<size()<<std::endl;exit(-1);}
01200 
01201 }
01202 std::pair <MC_matrix,MC_v3d> MC_matrix::to_matrix3() const
01203 {
01204     if(size_1()==3 && size_2()==3)
01205         return std::pair <MC_matrix,MC_v3d> (*this,MC_v3d(0,0,0));
01206     else if(size_1()==4 && size_2()==4)
01207         return std::pair <MC_matrix,MC_v3d> ((*this)(MC_int_vector(0,1,2),MC_int_vector(0,1,2)),(*this)(MC_int_vector(0,1,2),3));
01208     else
01209     {std::cout<<"Error in MC_matrix::to_matrix3(), size must be 4x4 and not "<<size()<<std::endl;exit(-1);}
01210 }
01211 const double* MC_matrix::pointer() const
01212 {return M.pointer();}
01213 
01214 MC_matrix& MC_matrix::operator*=(const MC_matrix& M1)
01215 {
01216     *this=(*this)*M1;
01217     return *this;
01218 }
01219 
01220 MC_matrix& MC_matrix::set_translation(const MC_v3d& tr)
01221 {
01222     if(size_1()!=4 || size_2()!=4)
01223     {std::cout<<"Error in MC_matrix::set_translation("<<tr<<"), size of the matrix should be 4x4 and not "<<size()<<std::endl;exit(-1);}
01224     M[12]=tr[0];M[13]=tr[1];M[14]=tr[2];
01225     return *this;
01226 }
01227 MC_matrix& MC_matrix::set_rotation(const MC_matrix& m)
01228 {
01229     if( !((size_1()==4 && size_2()==4) || (size_1()==3 && size_2()==3)) )
01230     {std::cout<<"Error in MC_matrix::set_rotation("<<m<<"), size of the matrix should be 4x4 or 3x3 and not "<<size()<<std::endl;exit(-1);}
01231     for(int k1=0;k1<3;++k1)
01232         for(int k2=0;k2<3;++k2)
01233             M[k1+4*k2]=m(k1,k2);
01234     return *this;
01235 }
01236 
01237 MC_double_vector operator*(const MC_matrix& M1,const MC_double_vector& v)
01238 {
01239     if(M1.size_2()!=v.size())
01240     {std::cout<<"Error in MC_matrix::operator*(const MC_matrix& M1,const MC_double_vector& v), size are not compatible : ["<<M1.size()<<"]x"<<v.size()<<std::endl;exit(-1);}
01241 
01242     MC_matrix m;m.add_col(v);
01243     return (M1*m).to_vec();
01244 }
01245 const MC_double_vector& MC_matrix::to_vec () const
01246 {return M;}
01247 
01248 MC_double_vector MC_matrix::get_col(const int& k_index) const
01249 {
01250     if(k_index<0 || k_index>=size_2())
01251     {std::cout<<"Error in MC_matrix::get_col("<<k_index<<"), size_2="<<size_2()<<std::endl;exit(-1);}
01252 
01253     return (*this)(MC_int_vector::linspace(0,size_1()-1),k_index).to_vec();
01254 }
01255 MC_double_vector MC_matrix::get_row(const int& k_index) const
01256 {
01257     if(k_index<0 || k_index>=size_1())
01258     {std::cout<<"Error in MC_matrix::get_row("<<k_index<<"), size_1="<<size_1()<<std::endl;exit(-1);}
01259 
01260     return (*this)(k_index,MC_int_vector::linspace(0,size_2()-1)).to_vec();
01261 }
01262 
01263 
01264 
01265 
01266 
01267 MC_matrix MC_matrix::transformation(const std::string& input)
01268 {
01269     std::vector<std::string> v_input=MC_string_converter::delete_empty(MC_string_tokenizer::tokenize(input,"<>,;: "));
01270     int counter=0;
01271     int N=v_input.size();
01272     //for(int k=0;k<N;++k)
01273     //    std::cout<<" -- "<<v_input[k]<<std::endl;
01274 
01275     while(counter<N)
01276     {
01277         if(v_input[counter]=="rotation")
01278         {
01279             if(counter+4<N)
01280             {
01281                 //read axis and angle
01282                 double x=MC_string_converter::value_of<double>(v_input[counter+1]);
01283                 double y=MC_string_converter::value_of<double>(v_input[counter+2]);
01284                 double z=MC_string_converter::value_of<double>(v_input[counter+3]);
01285                 double theta=MC_string_converter::value_of<double>(v_input[counter+4]);
01286 
01287                 return MC_matrix::rotation(MC_v3d(x,y,z),theta);
01288             }
01289         }
01290         if(v_input[counter]=="translation")
01291         {
01292             if(counter+3<N)
01293             {
01294                 double x=MC_string_converter::value_of<double>(v_input[counter+1]);
01295                 double y=MC_string_converter::value_of<double>(v_input[counter+2]);
01296                 double z=MC_string_converter::value_of<double>(v_input[counter+3]);
01297 
01298 
01299                 return MC_matrix::translation(MC_v3d(x,y,z));
01300             }
01301         }
01302         if(v_input[counter]=="scaling")
01303         {
01304             if(counter+3<N)
01305             {
01306                 bool is_ok_1=false,is_ok_2=false,is_ok_3=false;
01307                 double x=MC_string_converter::value_of<double>(v_input[counter+1],&is_ok_1);
01308                 double y=MC_string_converter::value_of<double>(v_input[counter+2],&is_ok_2);
01309                 double z=MC_string_converter::value_of<double>(v_input[counter+3],&is_ok_3);
01310 
01311                 if(is_ok_1==true && is_ok_2==true && is_ok_3==true)
01312                     return MC_matrix::scaling(x,y,z);
01313                 else if(is_ok_1==true && (is_ok_2==false || is_ok_3==false) )
01314                 {
01315                     return MC_matrix::scaling(x);
01316                 }
01317 
01318             }
01319             else if (counter+1<N)
01320             {
01321                 double s=MC_string_converter::value_of<double>(v_input[counter+1]);
01322 
01323                 return MC_matrix::scaling(s);
01324             }
01325         }
01326 
01327         ++counter;
01328     }
01329     return MC_matrix::identity(4);
01330 }
01331 
01332 MC_matrix MC_matrix::translation(const MC_v3d& tr)
01333 {
01334     MC_matrix M=MC_matrix::identity(4);
01335     M.set_translation(tr);
01336     return M;
01337 }
01338 
01339 MC_matrix MC_matrix::scaling(const double& s)
01340 {
01341     return MC_matrix::scaling(s,s,s);
01342 }
01343 
01344 MC_matrix MC_matrix::scaling(const double& sx,const double& sy,const double& sz)
01345 {
01346     MC_matrix M(3);
01347     M(0,0)=sx;M(1,1)=sy;M(2,2)=sz;
01348     return M;
01349 }
01350 
01351 std::string MC_matrix::to_string() const
01352 {
01353     std::stringstream stream;stream<<*this;
01354     return stream.str();
01355 }
01356 
01357 MC_matrix MC_matrix::kronecker(const MC_double_vector& v1,const MC_double_vector& v2)
01358 {
01359     int N=v1.size();
01360     if(v2.size()!=N)
01361     {std::cout<<"Error in MC_matrix::kronecker(v1,v2), size are not consistent"<<std::endl;exit(-1);}
01362 
01363     MC_matrix K=MC_matrix::zeros(N);
01364     for(int k1=0;k1<N;++k1)
01365         for(int k2=0;k2<N;++k2)
01366             K(k1,k2) = v1[k1]*v2[k2];
01367     return K;
01368 
01369 }
01370 
01371 MC_matrix::MC_matrix(const MC_double_vector& column)
01372 {
01373     *this=MC_matrix(column.size(),1);
01374     set_col(0,column);
01375 }
01376 
01377 
01378 }

Generated on Sun Apr 18 20:24:47 2010 by  doxygen 1.6.1