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 #ifndef UBLASCUSTOMFUNCTIONS_HPP_
00030 #define UBLASCUSTOMFUNCTIONS_HPP_
00031
00038 #include <boost/numeric/ublas/matrix.hpp>
00039 #include <boost/numeric/ublas/vector.hpp>
00040
00041 #include <boost/numeric/ublas/matrix_proxy.hpp>
00042 #include <boost/numeric/ublas/io.hpp>
00043 #include <boost/numeric/ublas/matrix_expression.hpp>
00044
00045 #include "petsc.h"
00046 #include "petscblaslapack.h"
00047
00048 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00049 #define LAPACKgeev_ LAgeev_
00050 #endif
00051
00052 #include "Exception.hpp"
00053 #include "MathsCustomFunctions.hpp"
00054
00055 using namespace boost::numeric::ublas;
00056
00057
00058
00065 template<class T>
00066 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00067 {
00068 using namespace boost::numeric::ublas;
00069
00070 return rM(0,0);
00071 }
00072
00079 template<class T>
00080 T Determinant(const boost::numeric::ublas::c_matrix<T,2,2>& rM)
00081 {
00082 using namespace boost::numeric::ublas;
00083
00084 return rM(0,0)*rM(1,1) - rM(1,0)*rM(0,1);
00085 }
00086
00093 template<class T>
00094 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00095 {
00096 using namespace boost::numeric::ublas;
00097
00098 return rM(0,0) * (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))
00099 - rM(0,1) * (rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))
00100 + rM(0,2) * (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0));
00101 }
00102
00103
00104
00112 template<class T>
00113 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00114 {
00115 using namespace boost::numeric::ublas;
00116 c_matrix<T,2,2> product = prod(trans(rM), rM);
00117 return std::sqrt(Determinant(product));
00118 }
00119
00127 template<class T>
00128 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00129 {
00130 using namespace boost::numeric::ublas;
00131 return std::sqrt(rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0));
00132 }
00133
00141 template<class T>
00142 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00143 {
00144 using namespace boost::numeric::ublas;
00145 return std::sqrt(rM(0,0) * rM(0,0) + rM(1,0) * rM(1,0));
00146 }
00147
00153 template<class T>
00154 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM)
00155 {
00156 NEVER_REACHED;
00157 }
00158
00164 template<class T>
00165 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM)
00166 {
00167 NEVER_REACHED;
00168 }
00169
00175 template<class T>
00176 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM)
00177 {
00178 NEVER_REACHED;
00179 }
00180
00181
00182
00192 template<class T>
00193 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM, const unsigned missrow, const unsigned misscol)
00194 {
00195 using namespace boost::numeric::ublas;
00196
00197 assert(missrow == 0);
00198 assert(misscol == 0);
00199 return 1.0;
00200 }
00201
00210 template<class T>
00211 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM, const unsigned missrow, const unsigned misscol)
00212 {
00213 using namespace boost::numeric::ublas;
00214
00215 assert(missrow < 2);
00216 assert(misscol < 2);
00217
00218 unsigned row = (missrow==1) ? 0 : 1;
00219 unsigned col = (misscol==1) ? 0 : 1;
00220 return rM(row,col);
00221 }
00222
00231 template<class T>
00232 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM, const unsigned missrow, const unsigned misscol)
00233 {
00234 using namespace boost::numeric::ublas;
00235
00236 assert(missrow < 3);
00237 assert(misscol < 3);
00238
00239 unsigned lorow = (missrow==0) ? 1 : 0;
00240 unsigned hirow = (missrow==2) ? 1 : 2;
00241 unsigned locol = (misscol==0) ? 1 : 0;
00242 unsigned hicol = (misscol==2) ? 1 : 2;
00243 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00244 }
00245
00246
00247
00256 template<class T>
00257 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM, const unsigned missrow, const unsigned misscol)
00258 {
00259 using namespace boost::numeric::ublas;
00260
00261 assert(missrow < 3);
00262
00263
00264 unsigned lorow = (missrow==0) ? 1 : 0;
00265 unsigned hirow = (missrow==2) ? 1 : 2;
00266 unsigned locol = (misscol==0) ? 1 : 0;
00267 unsigned hicol = (misscol==2) ? 1 : 2;
00268 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00269 }
00270
00279 template<class T>
00280 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM, const unsigned missrow, const unsigned misscol)
00281 {
00282 using namespace boost::numeric::ublas;
00283
00284 assert(missrow < 3);
00285 assert(misscol < 1);
00286
00287 unsigned lorow = (missrow==0) ? 1 : 0;
00288 unsigned hirow = (missrow==2) ? 1 : 2;
00289 unsigned locol = (misscol==0) ? 1 : 0;
00290 unsigned hicol = (misscol==2) ? 1 : 2;
00291 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00292 }
00293
00302 template<class T>
00303 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM, const unsigned missrow, const unsigned misscol)
00304 {
00305 using namespace boost::numeric::ublas;
00306
00307 assert(missrow < 2);
00308 assert(misscol < 1);
00309
00310 unsigned row = (missrow==1) ? 0 : 1;
00311 unsigned col = (misscol==1) ? 0 : 1;
00312 return rM(row,col);
00313 }
00314
00315 #if defined(__xlC__)
00316
00317 #else //#if defined(__xlC__)
00318
00326 template<class T>
00327 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM, const unsigned missrow, const unsigned misscol)
00328 {
00329 NEVER_REACHED;
00330 }
00331
00340 template<class T>
00341 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM, const unsigned missrow, const unsigned misscol)
00342 {
00343 NEVER_REACHED;
00344 }
00345
00354 template<class T>
00355 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM, const unsigned missrow, const unsigned misscol)
00356 {
00357 NEVER_REACHED;
00358 }
00359 #endif //#if defined(__xlC__)
00360
00361
00362
00370 template<class T>
00371 boost::numeric::ublas::c_matrix<T, 1, 1> Inverse(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00372 {
00373 using namespace boost::numeric::ublas;
00374
00375 c_matrix<T,1,1> inverse;
00376 T det = Determinant(rM);
00377 assert(fabs(det) > DBL_EPSILON);
00378 inverse(0,0) = 1.0/det;
00379 return inverse;
00380 }
00381
00389 template<class T>
00390 boost::numeric::ublas::c_matrix<T, 2, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM)
00391 {
00392 using namespace boost::numeric::ublas;
00393
00394 c_matrix<T, 2, 2> inverse;
00395 T det = Determinant(rM);
00396
00397 assert( fabs(det) > DBL_EPSILON );
00398 inverse(0,0) = rM(1,1)/det;
00399 inverse(0,1) = -rM(0,1)/det;
00400 inverse(1,0) = -rM(1,0)/det;
00401 inverse(1,1) = rM(0,0)/det;
00402 return inverse;
00403 }
00404
00412 template<class T>
00413 boost::numeric::ublas::c_matrix<T, 3, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00414 {
00415 using namespace boost::numeric::ublas;
00416
00417 c_matrix<T, 3, 3> inverse;
00418 T det = Determinant(rM);
00419 assert(fabs(det) > DBL_EPSILON);
00420
00421 inverse(0,0) = (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))/det;
00422 inverse(1,0) = -(rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))/det;
00423 inverse(2,0) = (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0))/det;
00424 inverse(0,1) = -(rM(0,1)*rM(2,2) - rM(0,2)*rM(2,1))/det;
00425 inverse(1,1) = (rM(0,0)*rM(2,2) - rM(0,2)*rM(2,0))/det;
00426 inverse(2,1) = -(rM(0,0)*rM(2,1) - rM(0,1)*rM(2,0))/det;
00427 inverse(0,2) = (rM(0,1)*rM(1,2) - rM(0,2)*rM(1,1))/det;
00428 inverse(1,2) = -(rM(0,0)*rM(1,2) - rM(0,2)*rM(1,0))/det;
00429 inverse(2,2) = (rM(0,0)*rM(1,1) - rM(0,1)*rM(1,0))/det;
00430
00431 return inverse;
00432 }
00433
00434
00435
00443 template<class T>
00444 boost::numeric::ublas::c_matrix<T, 2, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00445 {
00446 using namespace boost::numeric::ublas;
00447
00448 c_matrix<T, 2, 3> inverse;
00449
00450
00451
00452
00453
00454 T a = rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0);
00455 T b = rM(0,0)*rM(0,1) + rM(1,0)*rM(1,1) + rM(2,0)*rM(2,1);
00456 T c = b;
00457 T d = rM(0,1)*rM(0,1) + rM(1,1)*rM(1,1) + rM(2,1)*rM(2,1);
00458
00459 T det = a*d - b*c;
00460
00461 T a_inv = d/det;
00462 T b_inv = -b/det;
00463 T c_inv = -c/det;
00464 T d_inv = a/det;
00465
00466 inverse(0,0) = a_inv*rM(0,0) + b_inv*rM(0,1);
00467 inverse(1,0) = c_inv*rM(0,0) + d_inv*rM(0,1);
00468 inverse(0,1) = a_inv*rM(1,0) + b_inv*rM(1,1);
00469 inverse(1,1) = c_inv*rM(1,0) + d_inv*rM(1,1);
00470 inverse(0,2) = a_inv*rM(2,0) + b_inv*rM(2,1);
00471 inverse(1,2) = c_inv*rM(2,0) + d_inv*rM(2,1);
00472
00473 return inverse;
00474 }
00475
00483 template<class T>
00484 boost::numeric::ublas::c_matrix<T, 1, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00485 {
00486 using namespace boost::numeric::ublas;
00487
00488 c_matrix<T, 1, 2> inverse;
00489 T det = Determinant(rM);
00490
00491 inverse(0,0) = rM(0,0)/det/det;
00492 inverse(0,1) = rM(1,0)/det/det;
00493
00494 return inverse;
00495 }
00496
00504 template<class T>
00505 boost::numeric::ublas::c_matrix<T, 1, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00506 {
00507 using namespace boost::numeric::ublas;
00508
00509 c_matrix<T, 1, 3> inverse;
00510 T det = Determinant(rM);
00511
00512 inverse(0,0) = rM(0,0)/det/det;
00513 inverse(0,1) = rM(1,0)/det/det;
00514 inverse(0,2) = rM(2,0)/det/det;
00515
00516 return inverse;
00517 }
00518
00519
00520
00527 template<class T>
00528 T Trace(const c_matrix<T, 1, 1>& rM)
00529 {
00530 return rM(0,0);
00531 }
00532
00539 template<class T>
00540 T Trace(const c_matrix<T, 2, 2>& rM)
00541 {
00542 return rM(0,0) + rM(1,1);
00543 }
00544
00551 template<class T>
00552 T Trace(const c_matrix<T, 3, 3>& rM)
00553 {
00554 return rM(0,0) + rM(1,1) + rM(2,2);
00555 }
00556
00563 template<class T>
00564 T Trace(const c_matrix<T, 4, 4>& rM)
00565 {
00566 return rM(0,0) + rM(1,1) + rM(2,2) + rM(3,3);
00567 }
00568
00569
00570
00579 template<class T>
00580 T SecondInvariant(const c_matrix<T, 3, 3>& rM)
00581 {
00582 return rM(0,0)*rM(1,1) + rM(1,1)*rM(2,2) + rM(2,2)*rM(0,0)
00583 - rM(1,0)*rM(1,0) - rM(2,1)*rM(2,1) - rM(2,0)*rM(2,0);
00584 }
00585
00593 template<class T>
00594 T SecondInvariant(const c_matrix<T, 2, 2>& rM)
00595 {
00596 return Determinant(rM);
00597 }
00598
00608 c_vector<double,3> CalculateEigenvectorForSmallestNonzeroEigenvalue(c_matrix<double, 3, 3>& rA);
00609
00610
00611
00619 template<class T>
00620 c_vector<T, 3> VectorProduct(const c_vector<T, 3>& rA, const c_vector<T, 3>& rB)
00621 {
00622
00623 c_vector<T, 3> result;
00624
00625 double x1 = rA(0);
00626 double y1 = rA(1);
00627 double z1 = rA(2);
00628 double x2 = rB(0);
00629 double y2 = rB(1);
00630 double z2 = rB(2);
00631
00632 result(0) = y1*z2 - z1*y2;
00633 result(1) = z1*x2 - x1*z2;
00634 result(2) = x1*y2 - y1*x2;
00635
00636 return result;
00637 }
00638
00645 c_vector<double, 1> Create_c_vector(double x);
00646
00654 c_vector<double, 2> Create_c_vector(double x, double y);
00655
00664 c_vector<double, 3> Create_c_vector(double x, double y, double z);
00665
00666 #endif