UblasCustomFunctions.hpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (c) 2005-2015, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 // COMMON DETERMINANTS - SQUARE
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 // COMMON GENERALIZED DETERMINANTS - NOT SQUARE
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 // COMMON SUBDETERMINANTS - SQUARE
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 // COMMON SUBDETERMINANTS - NOT SQUARE
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     //assert(misscol < 2); //Don't assert this since it is used
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 /* IBM compiler doesn't support zero-sized arrays*/
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 // COMMON INVERSES - SQUARE
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); // else it is a singular matrix
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 ); // else it is a singular matrix
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); // else it is a singular matrix
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 // COMMON PSEUDO-INVERSES - NOT SQUARE
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     // calculate (T'T)^-1, where T'T = (a b)
00448     //                                 (c d)
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 // COMMON MATRIX TRACES
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 // OTHER MATRIX FUNCTIONS (INVARIANTS, EIGENVECTORS)
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                              //COMMON VECTOR FUNCTIONS
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 /*UBLASCUSTOMFUNCTIONS_HPP_*/

Generated by  doxygen 1.6.2