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