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
00033 #include <boost/numeric/ublas/matrix.hpp>
00034 #include <boost/numeric/ublas/vector.hpp>
00035
00036 #include <boost/numeric/ublas/matrix_proxy.hpp>
00037 #include <boost/numeric/ublas/io.hpp>
00038 #include <boost/numeric/ublas/matrix_expression.hpp>
00039
00040 #include "petscblaslapack.h"
00041
00042 #if (PETSC_VERSION_MINOR == 2) //Old API
00043 #define LAPACKgeev_ LAgeev_
00044 #endif
00045
00046
00047
00048
00049
00050 #include <cfloat>
00051 #define TINY DBL_EPSILON
00052
00053 #include "Exception.hpp"
00054
00055 using namespace boost::numeric::ublas;
00063 template<class T>
00064 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00065 {
00066 using namespace boost::numeric::ublas;
00067
00068 return rM(0,0);
00069 }
00073 template<class T>
00074 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM, const unsigned missrow, const unsigned misscol)
00075 {
00076 using namespace boost::numeric::ublas;
00077
00078 assert(missrow==0);
00079 assert(misscol==0);
00080 return 1.0;
00081 }
00082
00083 template<class T>
00084 T Determinant(const boost::numeric::ublas::c_matrix<T,2,2>& rM)
00085 {
00086 using namespace boost::numeric::ublas;
00087
00088 return rM(0,0)*rM(1,1) - rM(1,0)*rM(0,1);
00089 }
00090
00094 template<class T>
00095 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM, const unsigned missrow, const unsigned misscol)
00096 {
00097 using namespace boost::numeric::ublas;
00098
00099 assert(missrow < 2);
00100 assert(misscol < 2);
00101
00102 unsigned row = (missrow==1) ? 0 : 1;
00103 unsigned col = (misscol==1) ? 0 : 1;
00104 return rM(row,col);
00105 }
00106
00107 template<class T>
00108 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM, const unsigned missrow, const unsigned misscol)
00109 {
00110 using namespace boost::numeric::ublas;
00111
00112 assert(missrow < 2);
00113 assert(misscol < 1);
00114
00115 unsigned row = (missrow==1) ? 0 : 1;
00116 unsigned col = (misscol==1) ? 0 : 1;
00117 return rM(row,col);
00118 }
00119
00120 template<class T>
00121 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00122 {
00123 using namespace boost::numeric::ublas;
00124
00125 return rM(0,0) * (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))
00126 - rM(0,1) * (rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))
00127 + rM(0,2) * (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0));
00128 }
00129
00135 template<class T>
00136 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00137 {
00138 using namespace boost::numeric::ublas;
00139
00140 return std::sqrt(rM(0,0) * rM(0,0) + rM(1,0) * rM(1,0));
00141 }
00142
00148 template<class T>
00149 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00150 {
00151 using namespace boost::numeric::ublas;
00152
00153 return std::sqrt(rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0));
00154 }
00155
00161 template<class T>
00162 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00163 {
00164 using namespace boost::numeric::ublas;
00165
00166 c_matrix<T,2,2> product = prod(trans(rM), rM);
00167
00168 return std::sqrt(Determinant(product));
00169 }
00170
00178 template<class T>
00179 T Determinant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM)
00180 {
00181 NEVER_REACHED;
00182 }
00183
00191 template<class T>
00192 T Determinant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM)
00193 {
00194 NEVER_REACHED;
00195 }
00196
00204 template<class T>
00205 T Determinant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM)
00206 {
00207 NEVER_REACHED;
00208 }
00209
00213 template<class T>
00214 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 0>& rM, const unsigned missrow, const unsigned misscol)
00215 {
00216 NEVER_REACHED;
00217 }
00218
00222 template<class T>
00223 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 2, 0>& rM, const unsigned missrow, const unsigned misscol)
00224 {
00225 NEVER_REACHED;
00226 }
00227
00231 template<class T>
00232 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 1, 0>& rM, const unsigned missrow, const unsigned misscol)
00233 {
00234 NEVER_REACHED;
00235 }
00236
00240 template<class T>
00241 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM, const unsigned missrow, const unsigned misscol)
00242 {
00243 using namespace boost::numeric::ublas;
00244
00245 assert(missrow < 3);
00246
00247
00248 unsigned lorow = (missrow==0) ? 1 : 0;
00249 unsigned hirow = (missrow==2) ? 1 : 2;
00250 unsigned locol = (misscol==0) ? 1 : 0;
00251 unsigned hicol = (misscol==2) ? 1 : 2;
00252 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00253 }
00254
00258 template<class T>
00259 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM, const unsigned missrow, const unsigned misscol)
00260 {
00261 using namespace boost::numeric::ublas;
00262
00263 assert(missrow < 3);
00264 assert(misscol < 1);
00265
00266 unsigned lorow = (missrow==0) ? 1 : 0;
00267 unsigned hirow = (missrow==2) ? 1 : 2;
00268 unsigned locol = (misscol==0) ? 1 : 0;
00269 unsigned hicol = (misscol==2) ? 1 : 2;
00270 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00271 }
00272
00276 template<class T>
00277 T SubDeterminant(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM, const unsigned missrow, const unsigned misscol)
00278 {
00279 using namespace boost::numeric::ublas;
00280
00281 assert(missrow < 3);
00282 assert(misscol < 3);
00283
00284 unsigned lorow = (missrow==0) ? 1 : 0;
00285 unsigned hirow = (missrow==2) ? 1 : 2;
00286 unsigned locol = (misscol==0) ? 1 : 0;
00287 unsigned hicol = (misscol==2) ? 1 : 2;
00288 return rM(lorow,locol)*rM(hirow,hicol) - rM(lorow,hicol)*rM(hirow,locol);
00289 }
00290
00297 template<class T>
00298 boost::numeric::ublas::c_matrix<T, 1, 1> Inverse(const boost::numeric::ublas::c_matrix<T, 1, 1>& rM)
00299 {
00300 using namespace boost::numeric::ublas;
00301
00302 c_matrix<T,1,1> inverse;
00303 T det = Determinant(rM);
00304 assert( fabs(det) > TINY );
00305 inverse(0,0) = 1.0/det;
00306 return inverse;
00307 }
00308
00309 template<class T>
00310 boost::numeric::ublas::c_matrix<T, 2, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 2>& rM)
00311 {
00312 using namespace boost::numeric::ublas;
00313
00314 c_matrix<T, 2, 3> inverse;
00315
00316
00317
00318
00319
00320 T a = rM(0,0)*rM(0,0) + rM(1,0)*rM(1,0) + rM(2,0)*rM(2,0);
00321 T b = rM(0,0)*rM(0,1) + rM(1,0)*rM(1,1) + rM(2,0)*rM(2,1);
00322 T c = b;
00323 T d = rM(0,1)*rM(0,1) + rM(1,1)*rM(1,1) + rM(2,1)*rM(2,1);
00324
00325 T det = a*d - b*c;
00326
00327 T a_inv = d/det;
00328 T b_inv = -b/det;
00329 T c_inv = -c/det;
00330 T d_inv = a/det;
00331
00332 inverse(0,0) = a_inv*rM(0,0) + b_inv*rM(0,1);
00333 inverse(1,0) = c_inv*rM(0,0) + d_inv*rM(0,1);
00334 inverse(0,1) = a_inv*rM(1,0) + b_inv*rM(1,1);
00335 inverse(1,1) = c_inv*rM(1,0) + d_inv*rM(1,1);
00336 inverse(0,2) = a_inv*rM(2,0) + b_inv*rM(2,1);
00337 inverse(1,2) = c_inv*rM(2,0) + d_inv*rM(2,1);
00338
00339 return inverse;
00340 }
00341
00342 template<class T>
00343 boost::numeric::ublas::c_matrix<T, 2, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 2>& rM)
00344 {
00345 using namespace boost::numeric::ublas;
00346
00347 c_matrix<T, 2, 2> inverse;
00348 T det = Determinant(rM);
00349
00350 assert( fabs(det) > TINY );
00351 inverse(0,0) = rM(1,1)/det;
00352 inverse(0,1) = -rM(0,1)/det;
00353 inverse(1,0) = -rM(1,0)/det;
00354 inverse(1,1) = rM(0,0)/det;
00355 return inverse;
00356 }
00357
00358 template<class T>
00359 boost::numeric::ublas::c_matrix<T, 3, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 3>& rM)
00360 {
00361 using namespace boost::numeric::ublas;
00362
00363 c_matrix<T, 3, 3> inverse;
00364 T det = Determinant(rM);
00365 assert( fabs(det) > TINY );
00366
00367 inverse(0,0) = (rM(1,1)*rM(2,2) - rM(1,2)*rM(2,1))/det;
00368 inverse(1,0) = -(rM(1,0)*rM(2,2) - rM(1,2)*rM(2,0))/det;
00369 inverse(2,0) = (rM(1,0)*rM(2,1) - rM(1,1)*rM(2,0))/det;
00370 inverse(0,1) = -(rM(0,1)*rM(2,2) - rM(0,2)*rM(2,1))/det;
00371 inverse(1,1) = (rM(0,0)*rM(2,2) - rM(0,2)*rM(2,0))/det;
00372 inverse(2,1) = -(rM(0,0)*rM(2,1) - rM(0,1)*rM(2,0))/det;
00373 inverse(0,2) = (rM(0,1)*rM(1,2) - rM(0,2)*rM(1,1))/det;
00374 inverse(1,2) = -(rM(0,0)*rM(1,2) - rM(0,2)*rM(1,0))/det;
00375 inverse(2,2) = (rM(0,0)*rM(1,1) - rM(0,1)*rM(1,0))/det;
00376
00377 return inverse;
00378 }
00379
00385 template<class T>
00386 boost::numeric::ublas::c_matrix<T, 1, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 1>& rM)
00387 {
00388 using namespace boost::numeric::ublas;
00389
00390 c_matrix<T, 1, 2> inverse;
00391 T det = Determinant(rM);
00392
00393 inverse(0,0) = rM(0,0)/det/det;
00394 inverse(0,1) = rM(1,0)/det/det;
00395
00396 return inverse;
00397 }
00398
00404 template<class T>
00405 boost::numeric::ublas::c_matrix<T, 1, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 1>& rM)
00406 {
00407 using namespace boost::numeric::ublas;
00408
00409 c_matrix<T, 1, 3> inverse;
00410 T det = Determinant(rM);
00411
00412 inverse(0,0) = rM(0,0)/det/det;
00413 inverse(0,1) = rM(1,0)/det/det;
00414 inverse(0,2) = rM(2,0)/det/det;
00415
00416 return inverse;
00417 }
00418
00419 template<class T>
00420 c_vector<T, 3> VectorProduct(const c_vector<T, 3>& rA, const c_vector<T, 3>& rB)
00421 {
00425
00426 c_vector<T, 3> result;
00427
00428 double x1 = rA(0);
00429 double y1 = rA(1);
00430 double z1 = rA(2);
00431 double x2 = rB(0);
00432 double y2 = rB(1);
00433 double z2 = rB(2);
00434
00435 result(0) = y1*z2 - z1*y2;
00436 result(1) = z1*x2 - x1*z2;
00437 result(2) = x1*y2 - y1*x2;
00438
00439 return result;
00440 }
00441
00442 template<class T>
00443 T Trace(const c_matrix<T, 1, 1>& rM)
00444 {
00445 return rM(0,0);
00446 }
00447
00448 template<class T>
00449 T Trace(const c_matrix<T, 2, 2>& rM)
00450 {
00451 return rM(0,0) + rM(1,1);
00452 }
00453
00454 template<class T>
00455 T Trace(const c_matrix<T, 3, 3>& rM)
00456 {
00457 return rM(0,0) + rM(1,1) + rM(2,2);
00458 }
00459
00460 template<class T>
00461 T Trace(const c_matrix<T, 4, 4>& rM)
00462 {
00463 return rM(0,0) + rM(1,1) + rM(2,2) + rM(3,3);
00464 }
00465
00471 template<class T>
00472 T SecondInvariant(const c_matrix<T, 3, 3>& rM)
00473 {
00474 return rM(0,0)*rM(1,1) + rM(1,1)*rM(2,2) + rM(2,2)*rM(0,0)
00475 - rM(1,0)*rM(1,0) - rM(2,1)*rM(2,1) - rM(2,0)*rM(2,0);
00476 }
00477
00482 template<class T>
00483 T SecondInvariant(const c_matrix<T, 2, 2>& rM)
00484 {
00485 return Determinant(rM);
00486 }
00487
00491 c_vector<double, 1> Create_c_vector(double x);
00492
00493 c_vector<double, 2> Create_c_vector(double x, double y);
00494
00495 c_vector<double, 3> Create_c_vector(double x, double y, double z);
00496
00505 c_vector<double,3> CalculateEigenvectorForSmallestNonzeroEigenvalue(c_matrix<double, 3, 3>& rA);
00506
00507 #endif
00508