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 #ifndef UBLASCUSTOMFUNCTIONS_HPP_
00031 #define UBLASCUSTOMFUNCTIONS_HPP_
00032
00039 #include <boost/numeric/ublas/matrix.hpp>
00040 #include <boost/numeric/ublas/vector.hpp>
00041
00042 #include <boost/numeric/ublas/matrix_proxy.hpp>
00043 #include <boost/numeric/ublas/io.hpp>
00044 #include <boost/numeric/ublas/matrix_expression.hpp>
00045
00046 #include <cfloat>
00047 #include "petsc.h"
00048 #include "petscblaslapack.h"
00049
00050 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00051 #define LAPACKgeev_ LAgeev_
00052 #endif
00053
00054 #include "Exception.hpp"
00055 #include "PetscTools.hpp"
00056
00057 using namespace boost::numeric::ublas;
00058
00059
00060
00061
00068 template<class T>
00069 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00070 {
00071 using namespace boost::numeric::ublas;
00072
00073 return rM(0,0);
00074 }
00081 template<class T>
00082 T Determinant(const boost::numeric::ublas::c_matrix<T,2,2>& rM)
00083 {
00084 using namespace boost::numeric::ublas;
00085
00086 return rM(0,0)*rM(1,1) - rM(1,0)*rM(0,1);
00087 }
00094 template<class T>
00095 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00096 {
00097 using namespace boost::numeric::ublas;
00098
00099 return rM(0,0) * (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))
00100 - rM(0,1) * (rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))
00101 + rM(0,2) * (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0));
00102 }
00103
00104
00105
00106
00107
00114 template<class T>
00115 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00116 {
00117 using namespace boost::numeric::ublas;
00118 c_matrix<T,2,2> product = prod(trans(rM), rM);
00119 return std::sqrt(Determinant(product));
00120 }
00121
00128 template<class T>
00129 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00130 {
00131 using namespace boost::numeric::ublas;
00132 return std::sqrt(rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0));
00133 }
00134
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
00148
00149
00154 template<class T>
00155 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM)
00156 {
00157 NEVER_REACHED;
00158 }
00159
00164 template<class T>
00165 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM)
00166 {
00167 NEVER_REACHED;
00168 }
00169
00174 template<class T>
00175 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM)
00176 {
00177 NEVER_REACHED;
00178 }
00179
00180
00181
00182
00183
00184
00195 template<class T>
00196 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM, const unsigned missrow, const unsigned misscol)
00197 {
00198 using namespace boost::numeric::ublas;
00199
00200 assert(missrow==0);
00201 assert(misscol==0);
00202 return 1.0;
00203 }
00204
00205
00215 template<class T>
00216 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM, const unsigned missrow, const unsigned misscol)
00217 {
00218 using namespace boost::numeric::ublas;
00219
00220 assert(missrow < 2);
00221 assert(misscol < 2);
00222
00223 unsigned row = (missrow==1) ? 0 : 1;
00224 unsigned col = (misscol==1) ? 0 : 1;
00225 return rM(row,col);
00226 }
00227
00235 template<class T>
00236 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM, const unsigned missrow, const unsigned misscol)
00237 {
00238 using namespace boost::numeric::ublas;
00239
00240 assert(missrow < 3);
00241 assert(misscol < 3);
00242
00243 unsigned lorow = (missrow==0) ? 1 : 0;
00244 unsigned hirow = (missrow==2) ? 1 : 2;
00245 unsigned locol = (misscol==0) ? 1 : 0;
00246 unsigned hicol = (misscol==2) ? 1 : 2;
00247 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00248 }
00249
00250
00251
00252
00260 template<class T>
00261 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM, const unsigned missrow, const unsigned misscol)
00262 {
00263 using namespace boost::numeric::ublas;
00264
00265 assert(missrow < 3);
00266
00267
00268 unsigned lorow = (missrow==0) ? 1 : 0;
00269 unsigned hirow = (missrow==2) ? 1 : 2;
00270 unsigned locol = (misscol==0) ? 1 : 0;
00271 unsigned hicol = (misscol==2) ? 1 : 2;
00272 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00273 }
00274
00282 template<class T>
00283 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM, const unsigned missrow, const unsigned misscol)
00284 {
00285 using namespace boost::numeric::ublas;
00286
00287 assert(missrow < 3);
00288 assert(misscol < 1);
00289
00290 unsigned lorow = (missrow==0) ? 1 : 0;
00291 unsigned hirow = (missrow==2) ? 1 : 2;
00292 unsigned locol = (misscol==0) ? 1 : 0;
00293 unsigned hicol = (misscol==2) ? 1 : 2;
00294 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00295 }
00296
00304 template<class T>
00305 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM, const unsigned missrow, const unsigned misscol)
00306 {
00307 using namespace boost::numeric::ublas;
00308
00309 assert(missrow < 2);
00310 assert(misscol < 1);
00311
00312 unsigned row = (missrow==1) ? 0 : 1;
00313 unsigned col = (misscol==1) ? 0 : 1;
00314 return rM(row,col);
00315 }
00316
00317
00318 #if defined(__xlC__)
00319
00320 #else //#if defined(__xlC__)
00321
00328 template<class T>
00329 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM, const unsigned missrow, const unsigned misscol)
00330 {
00331 NEVER_REACHED;
00332 }
00333
00341 template<class T>
00342 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM, const unsigned missrow, const unsigned misscol)
00343 {
00344 NEVER_REACHED;
00345 }
00346
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
00363
00364
00372 template<class T>
00373 boost::numeric::ublas::c_matrix<T, 1, 1> Inverse(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00374 {
00375 using namespace boost::numeric::ublas;
00376
00377 c_matrix<T,1,1> inverse;
00378 T det = Determinant(rM);
00379 assert( fabs(det) > DBL_EPSILON );
00380 inverse(0,0) = 1.0/det;
00381 return inverse;
00382 }
00383
00391 template<class T>
00392 boost::numeric::ublas::c_matrix<T, 2, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM)
00393 {
00394 using namespace boost::numeric::ublas;
00395
00396 c_matrix<T, 2, 2> inverse;
00397 T det = Determinant(rM);
00398
00399 assert( fabs(det) > DBL_EPSILON );
00400 inverse(0,0) = rM(1,1)/det;
00401 inverse(0,1) = -rM(0,1)/det;
00402 inverse(1,0) = -rM(1,0)/det;
00403 inverse(1,1) = rM(0,0)/det;
00404 return inverse;
00405 }
00406
00414 template<class T>
00415 boost::numeric::ublas::c_matrix<T, 3, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00416 {
00417 using namespace boost::numeric::ublas;
00418
00419 c_matrix<T, 3, 3> inverse;
00420 T det = Determinant(rM);
00421 assert( fabs(det) > DBL_EPSILON );
00422
00423 inverse(0,0) = (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))/det;
00424 inverse(1,0) = -(rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))/det;
00425 inverse(2,0) = (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0))/det;
00426 inverse(0,1) = -(rM(0,1)*rM(2,2) - rM(0,2)*rM(2,1))/det;
00427 inverse(1,1) = (rM(0,0)*rM(2,2) - rM(0,2)*rM(2,0))/det;
00428 inverse(2,1) = -(rM(0,0)*rM(2,1) - rM(0,1)*rM(2,0))/det;
00429 inverse(0,2) = (rM(0,1)*rM(1,2) - rM(0,2)*rM(1,1))/det;
00430 inverse(1,2) = -(rM(0,0)*rM(1,2) - rM(0,2)*rM(1,0))/det;
00431 inverse(2,2) = (rM(0,0)*rM(1,1) - rM(0,1)*rM(1,0))/det;
00432
00433 return inverse;
00434 }
00435
00436
00437
00445 template<class T>
00446 boost::numeric::ublas::c_matrix<T, 2, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00447 {
00448 using namespace boost::numeric::ublas;
00449
00450 c_matrix<T, 2, 3> inverse;
00451
00452
00453
00454
00455
00456 T a = rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0);
00457 T b = rM(0,0)*rM(0,1) + rM(1,0)*rM(1,1) + rM(2,0)*rM(2,1);
00458 T c = b;
00459 T d = rM(0,1)*rM(0,1) + rM(1,1)*rM(1,1) + rM(2,1)*rM(2,1);
00460
00461 T det = a*d - b*c;
00462
00463 T a_inv = d/det;
00464 T b_inv = -b/det;
00465 T c_inv = -c/det;
00466 T d_inv = a/det;
00467
00468 inverse(0,0) = a_inv*rM(0,0) + b_inv*rM(0,1);
00469 inverse(1,0) = c_inv*rM(0,0) + d_inv*rM(0,1);
00470 inverse(0,1) = a_inv*rM(1,0) + b_inv*rM(1,1);
00471 inverse(1,1) = c_inv*rM(1,0) + d_inv*rM(1,1);
00472 inverse(0,2) = a_inv*rM(2,0) + b_inv*rM(2,1);
00473 inverse(1,2) = c_inv*rM(2,0) + d_inv*rM(2,1);
00474
00475 return inverse;
00476 }
00477
00478
00486 template<class T>
00487 boost::numeric::ublas::c_matrix<T, 1, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00488 {
00489 using namespace boost::numeric::ublas;
00490
00491 c_matrix<T, 1, 2> inverse;
00492 T det = Determinant(rM);
00493
00494 inverse(0,0) = rM(0,0)/det/det;
00495 inverse(0,1) = rM(1,0)/det/det;
00496
00497 return inverse;
00498 }
00499
00507 template<class T>
00508 boost::numeric::ublas::c_matrix<T, 1, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00509 {
00510 using namespace boost::numeric::ublas;
00511
00512 c_matrix<T, 1, 3> inverse;
00513 T det = Determinant(rM);
00514
00515 inverse(0,0) = rM(0,0)/det/det;
00516 inverse(0,1) = rM(1,0)/det/det;
00517 inverse(0,2) = rM(2,0)/det/det;
00518
00519 return inverse;
00520 }
00521
00522
00523
00524
00531 template<class T>
00532 T Trace(const c_matrix<T, 1, 1>& rM)
00533 {
00534 return rM(0,0);
00535 }
00536
00543 template<class T>
00544 T Trace(const c_matrix<T, 2, 2>& rM)
00545 {
00546 return rM(0,0) + rM(1,1);
00547 }
00548
00555 template<class T>
00556 T Trace(const c_matrix<T, 3, 3>& rM)
00557 {
00558 return rM(0,0) + rM(1,1) + rM(2,2);
00559 }
00560
00567 template<class T>
00568 T Trace(const c_matrix<T, 4, 4>& rM)
00569 {
00570 return rM(0,0) + rM(1,1) + rM(2,2) + rM(3,3);
00571 }
00572
00573
00582 template<class T>
00583 T SecondInvariant(const c_matrix<T, 3, 3>& rM)
00584 {
00585 return rM(0,0)*rM(1,1) + rM(1,1)*rM(2,2) + rM(2,2)*rM(0,0)
00586 - rM(1,0)*rM(1,0) - rM(2,1)*rM(2,1) - rM(2,0)*rM(2,0);
00587 }
00588
00596 template<class T>
00597 T SecondInvariant(const c_matrix<T, 2, 2>& rM)
00598 {
00599 return Determinant(rM);
00600 }
00601
00602
00611 c_vector<double,3> CalculateEigenvectorForSmallestNonzeroEigenvalue(c_matrix<double, 3, 3>& rA);
00612
00613
00614
00615
00622 template<class T>
00623 c_vector<T, 3> VectorProduct(const c_vector<T, 3>& rA, const c_vector<T, 3>& rB)
00624 {
00625
00626 c_vector<T, 3> result;
00627
00628 double x1 = rA(0);
00629 double y1 = rA(1);
00630 double z1 = rA(2);
00631 double x2 = rB(0);
00632 double y2 = rB(1);
00633 double z2 = rB(2);
00634
00635 result(0) = y1*z2 - z1*y2;
00636 result(1) = z1*x2 - x1*z2;
00637 result(2) = x1*y2 - y1*x2;
00638
00639 return result;
00640 }
00641
00642
00649 c_vector<double, 1> Create_c_vector(double x);
00650
00658 c_vector<double, 2> Create_c_vector(double x, double y);
00659
00668 c_vector<double, 3> Create_c_vector(double x, double y, double z);
00669
00670
00677 double SmallPow(double x, unsigned exponent);
00678
00686 bool Divides(double smallerNumber, double largerNumber);
00687
00688 #endif
00689