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
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
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
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
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
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
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
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
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
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)
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;
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
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;
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
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
01064 MC_double_vector nabla_c=MC_double_vector(x10)<<x11<<x12<<x00<<x01<<x02;
01065
01066 MC_double_vector nabla_s=-cos_t/(sin_t+epsilon)*nabla_c;
01067
01068
01069
01070 MC_double_vector nabla_nx=MC_double_vector(0.0)<<x12<<-x11<<0.0<<-x02<<x01;
01071
01072 MC_double_vector nabla_ny=MC_double_vector(-x12)<<0.0<<x10<<x02<<0.0<<-x00;
01073
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
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)
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
01273
01274
01275 while(counter<N)
01276 {
01277 if(v_input[counter]=="rotation")
01278 {
01279 if(counter+4<N)
01280 {
01281
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 }