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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef UBLASCUSTOMFUNCTIONS_HPP_
00037 #define UBLASCUSTOMFUNCTIONS_HPP_
00038
00045 #include "UblasIncludes.hpp"
00046
00047 #include "Exception.hpp"
00048 #include "MathsCustomFunctions.hpp"
00049
00050
00051
00058 template<class T>
00059 inline T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00060 {
00061 using namespace boost::numeric::ublas;
00062
00063 return rM(0,0);
00064 }
00065
00072 template<class T>
00073 T Determinant(const boost::numeric::ublas::c_matrix<T,2,2>& rM)
00074 {
00075 using namespace boost::numeric::ublas;
00076
00077 return rM(0,0)*rM(1,1) - rM(1,0)*rM(0,1);
00078 }
00079
00086 template<class T>
00087 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00088 {
00089 using namespace boost::numeric::ublas;
00090
00091 return rM(0,0) * (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))
00092 - rM(0,1) * (rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))
00093 + rM(0,2) * (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0));
00094 }
00095
00096
00097
00105 template<class T>
00106 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00107 {
00108 using namespace boost::numeric::ublas;
00109 c_matrix<T,2,2> product = prod(trans(rM), rM);
00110 return std::sqrt(Determinant(product));
00111 }
00112
00120 template<class T>
00121 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00122 {
00123 using namespace boost::numeric::ublas;
00124 return std::sqrt(rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0));
00125 }
00126
00134 template<class T>
00135 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00136 {
00137 using namespace boost::numeric::ublas;
00138 return std::sqrt(rM(0,0) * rM(0,0) + rM(1,0) * rM(1,0));
00139 }
00140
00147 template<class T>
00148 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM)
00149 {
00150 NEVER_REACHED;
00151 }
00152
00159 template<class T>
00160 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM)
00161 {
00162 NEVER_REACHED;
00163 }
00164
00171 template<class T>
00172 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM)
00173 {
00174 NEVER_REACHED;
00175 }
00176
00177
00178
00188 template<class T>
00189 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM, const unsigned missrow, const unsigned misscol)
00190 {
00191 using namespace boost::numeric::ublas;
00192
00193 assert(missrow == 0);
00194 assert(misscol == 0);
00195 return 1.0;
00196 }
00197
00206 template<class T>
00207 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM, const unsigned missrow, const unsigned misscol)
00208 {
00209 using namespace boost::numeric::ublas;
00210
00211 assert(missrow < 2);
00212 assert(misscol < 2);
00213
00214 unsigned row = (missrow==1) ? 0 : 1;
00215 unsigned col = (misscol==1) ? 0 : 1;
00216 return rM(row,col);
00217 }
00218
00227 template<class T>
00228 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM, const unsigned missrow, const unsigned misscol)
00229 {
00230 using namespace boost::numeric::ublas;
00231
00232 assert(missrow < 3);
00233 assert(misscol < 3);
00234
00235 unsigned lorow = (missrow==0) ? 1 : 0;
00236 unsigned hirow = (missrow==2) ? 1 : 2;
00237 unsigned locol = (misscol==0) ? 1 : 0;
00238 unsigned hicol = (misscol==2) ? 1 : 2;
00239 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00240 }
00241
00242
00243
00252 template<class T>
00253 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM, const unsigned missrow, const unsigned misscol)
00254 {
00255 using namespace boost::numeric::ublas;
00256
00257 assert(missrow < 3);
00258
00259
00260 unsigned lorow = (missrow==0) ? 1 : 0;
00261 unsigned hirow = (missrow==2) ? 1 : 2;
00262 unsigned locol = (misscol==0) ? 1 : 0;
00263 unsigned hicol = (misscol==2) ? 1 : 2;
00264 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00265 }
00266
00275 template<class T>
00276 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM, const unsigned missrow, const unsigned misscol)
00277 {
00278 using namespace boost::numeric::ublas;
00279
00280 assert(missrow < 3);
00281 assert(misscol < 1);
00282
00283 unsigned lorow = (missrow==0) ? 1 : 0;
00284 unsigned hirow = (missrow==2) ? 1 : 2;
00285 unsigned locol = (misscol==0) ? 1 : 0;
00286 unsigned hicol = (misscol==2) ? 1 : 2;
00287 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00288 }
00289
00298 template<class T>
00299 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM, const unsigned missrow, const unsigned misscol)
00300 {
00301 using namespace boost::numeric::ublas;
00302
00303 assert(missrow < 2);
00304 assert(misscol < 1);
00305
00306 unsigned row = (missrow==1) ? 0 : 1;
00307 unsigned col = (misscol==1) ? 0 : 1;
00308 return rM(row,col);
00309 }
00310
00311 #if defined(__xlC__)
00312
00313 #else //#if defined(__xlC__)
00314
00322 template<class T>
00323 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM, const unsigned missrow, const unsigned misscol)
00324 {
00325 NEVER_REACHED;
00326 }
00327
00336 template<class T>
00337 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM, const unsigned missrow, const unsigned misscol)
00338 {
00339 NEVER_REACHED;
00340 }
00341
00350 template<class T>
00351 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM, const unsigned missrow, const unsigned misscol)
00352 {
00353 NEVER_REACHED;
00354 }
00355 #endif //#if defined(__xlC__)
00356
00357
00358
00366 template<class T>
00367 boost::numeric::ublas::c_matrix<T, 1, 1> Inverse(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00368 {
00369 using namespace boost::numeric::ublas;
00370
00371 c_matrix<T,1,1> inverse;
00372 T det = Determinant(rM);
00373 assert(fabs(det) > DBL_EPSILON);
00374 inverse(0,0) = 1.0/det;
00375 return inverse;
00376 }
00377
00385 template<class T>
00386 boost::numeric::ublas::c_matrix<T, 2, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM)
00387 {
00388 using namespace boost::numeric::ublas;
00389
00390 c_matrix<T, 2, 2> inverse;
00391 T det = Determinant(rM);
00392
00393 assert( fabs(det) > DBL_EPSILON );
00394 inverse(0,0) = rM(1,1)/det;
00395 inverse(0,1) = -rM(0,1)/det;
00396 inverse(1,0) = -rM(1,0)/det;
00397 inverse(1,1) = rM(0,0)/det;
00398 return inverse;
00399 }
00400
00408 template<class T>
00409 boost::numeric::ublas::c_matrix<T, 3, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00410 {
00411 using namespace boost::numeric::ublas;
00412
00413 c_matrix<T, 3, 3> inverse;
00414 T det = Determinant(rM);
00415 assert(fabs(det) > DBL_EPSILON);
00416
00417 inverse(0,0) = (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))/det;
00418 inverse(1,0) = -(rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))/det;
00419 inverse(2,0) = (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0))/det;
00420 inverse(0,1) = -(rM(0,1)*rM(2,2) - rM(0,2)*rM(2,1))/det;
00421 inverse(1,1) = (rM(0,0)*rM(2,2) - rM(0,2)*rM(2,0))/det;
00422 inverse(2,1) = -(rM(0,0)*rM(2,1) - rM(0,1)*rM(2,0))/det;
00423 inverse(0,2) = (rM(0,1)*rM(1,2) - rM(0,2)*rM(1,1))/det;
00424 inverse(1,2) = -(rM(0,0)*rM(1,2) - rM(0,2)*rM(1,0))/det;
00425 inverse(2,2) = (rM(0,0)*rM(1,1) - rM(0,1)*rM(1,0))/det;
00426
00427 return inverse;
00428 }
00429
00430
00431
00439 template<class T>
00440 boost::numeric::ublas::c_matrix<T, 2, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00441 {
00442 using namespace boost::numeric::ublas;
00443
00444 c_matrix<T, 2, 3> inverse;
00445
00446
00447
00448
00449
00450 T a = rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0);
00451 T b = rM(0,0)*rM(0,1) + rM(1,0)*rM(1,1) + rM(2,0)*rM(2,1);
00452 T c = b;
00453 T d = rM(0,1)*rM(0,1) + rM(1,1)*rM(1,1) + rM(2,1)*rM(2,1);
00454
00455 T det = a*d - b*c;
00456
00457 T a_inv = d/det;
00458 T b_inv = -b/det;
00459 T c_inv = -c/det;
00460 T d_inv = a/det;
00461
00462 inverse(0,0) = a_inv*rM(0,0) + b_inv*rM(0,1);
00463 inverse(1,0) = c_inv*rM(0,0) + d_inv*rM(0,1);
00464 inverse(0,1) = a_inv*rM(1,0) + b_inv*rM(1,1);
00465 inverse(1,1) = c_inv*rM(1,0) + d_inv*rM(1,1);
00466 inverse(0,2) = a_inv*rM(2,0) + b_inv*rM(2,1);
00467 inverse(1,2) = c_inv*rM(2,0) + d_inv*rM(2,1);
00468
00469 return inverse;
00470 }
00471
00479 template<class T>
00480 boost::numeric::ublas::c_matrix<T, 1, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00481 {
00482 using namespace boost::numeric::ublas;
00483
00484 c_matrix<T, 1, 2> inverse;
00485 T det = Determinant(rM);
00486
00487 inverse(0,0) = rM(0,0)/det/det;
00488 inverse(0,1) = rM(1,0)/det/det;
00489
00490 return inverse;
00491 }
00492
00500 template<class T>
00501 boost::numeric::ublas::c_matrix<T, 1, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00502 {
00503 using namespace boost::numeric::ublas;
00504
00505 c_matrix<T, 1, 3> inverse;
00506 T det = Determinant(rM);
00507
00508 inverse(0,0) = rM(0,0)/det/det;
00509 inverse(0,1) = rM(1,0)/det/det;
00510 inverse(0,2) = rM(2,0)/det/det;
00511
00512 return inverse;
00513 }
00514
00515
00516
00523 template<class T>
00524 inline T Trace(const c_matrix<T, 1, 1>& rM)
00525 {
00526 return rM(0,0);
00527 }
00528
00535 template<class T>
00536 inline T Trace(const c_matrix<T, 2, 2>& rM)
00537 {
00538 return rM(0,0) + rM(1,1);
00539 }
00540
00547 template<class T>
00548 inline T Trace(const c_matrix<T, 3, 3>& rM)
00549 {
00550 return rM(0,0) + rM(1,1) + rM(2,2);
00551 }
00552
00559 template<class T>
00560 inline T Trace(const c_matrix<T, 4, 4>& rM)
00561 {
00562 return rM(0,0) + rM(1,1) + rM(2,2) + rM(3,3);
00563 }
00564
00565
00566
00575 template<class T>
00576 T SecondInvariant(const c_matrix<T, 3, 3>& rM)
00577 {
00578 return rM(0,0)*rM(1,1) + rM(1,1)*rM(2,2) + rM(2,2)*rM(0,0)
00579 - rM(1,0)*rM(1,0) - rM(2,1)*rM(2,1) - rM(2,0)*rM(2,0);
00580 }
00581
00589 template<class T>
00590 T SecondInvariant(const c_matrix<T, 2, 2>& rM)
00591 {
00592 return Determinant(rM);
00593 }
00594
00604 c_vector<double,3> CalculateEigenvectorForSmallestNonzeroEigenvalue(c_matrix<double, 3, 3>& rA);
00605
00612 double CalculateMaxEigenpair(c_matrix<double, 3, 3>& rA, c_vector<double, 3>& rEigenvector);
00613
00614
00615
00616
00625 template<class T>
00626 c_vector<T, 1> VectorProduct(const c_vector<T, 1>& rA, const c_vector<T, 1>& rB)
00627 {
00628 NEVER_REACHED;
00629 }
00638 template<class T>
00639 c_vector<T, 2> VectorProduct(const c_vector<T, 2>& rA, const c_vector<T, 2>& rB)
00640 {
00641 NEVER_REACHED;
00642 }
00643
00651 template<class T>
00652 c_vector<T, 3> VectorProduct(const c_vector<T, 3>& rA, const c_vector<T, 3>& rB)
00653 {
00654
00655 c_vector<T, 3> result;
00656
00657 result(0) = rA(1)*rB(2) - rA(2)*rB(1);
00658 result(1) = rA(2)*rB(0) - rA(0)*rB(2);
00659 result(2) = rA(0)*rB(1) - rA(1)*rB(0);
00660
00661 return result;
00662 }
00663
00670 c_vector<double, 1> Create_c_vector(double x);
00671
00679 c_vector<double, 2> Create_c_vector(double x, double y);
00680
00689 c_vector<double, 3> Create_c_vector(double x, double y, double z);
00690
00691 #endif