UblasCustomFunctions.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
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 //Promote universal LAPACK name if it's an old version of PETSc
00042 #if (PETSC_VERSION_MINOR == 2) //Old API
00043 #define LAPACKgeev_ LAgeev_
00044 #endif
00045 
00046 //#include <iostream>
00047 //#include <fstream>
00048 //#include <vector>
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> &m)
00065 {
00066     using namespace boost::numeric::ublas;
00067 
00068     return m(0,0);
00069 };
00073 template<class T>
00074 T SubDeterminant(const boost::numeric::ublas::c_matrix<T,1,1> &m, 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> &m)
00085 {
00086     using namespace boost::numeric::ublas;
00087 
00088     return m(0,0)*m(1,1)
00089            - m(1,0)*m(0,1);
00090 };
00091 
00095 template<class T>
00096 T SubDeterminant(const boost::numeric::ublas::c_matrix<T,2,2> &m, 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 m(row,col);
00106 };
00107 
00108 template<class T>
00109 T Determinant(const boost::numeric::ublas::c_matrix<T,3,3> &m)
00110 {
00111     using namespace boost::numeric::ublas;
00112 
00113     return   m(0,0) *
00114              (m(1,1)*m(2,2) - m(1,2)*m(2,1))
00115              - m(0,1) *
00116              (m(1,0)*m(2,2) - m(1,2)*m(2,0))
00117              + m(0,2) *
00118              (m(1,0)*m(2,1) - m(1,1)*m(2,0));
00119 };
00120 
00121 
00125 template<class T>
00126 T SubDeterminant(const boost::numeric::ublas::c_matrix<T,3,3> &m, const unsigned missrow, const unsigned misscol)
00127 {
00128     using namespace boost::numeric::ublas;
00129 
00130     assert(missrow<3);
00131     assert(misscol<3);
00132 
00133     unsigned lorow=(missrow==0)?1:0;
00134     unsigned hirow=(missrow==2)?1:2;
00135     unsigned locol=(misscol==0)?1:0;
00136     unsigned hicol=(misscol==2)?1:2;
00137     return (m(lorow,locol)*m(hirow,hicol) - m(lorow,hicol)*m(hirow,locol));
00138 };
00139 
00146 template<class T>
00147 boost::numeric::ublas::c_matrix<T, 1, 1> Inverse(const boost::numeric::ublas::c_matrix<T, 1, 1> &m)
00148 {
00149     using namespace boost::numeric::ublas;
00150 
00151     c_matrix<T, 1, 1> inverse;
00152     T det = Determinant(m);
00153     assert( fabs(det) > TINY ); //Else it is a singular matrix
00154     inverse(0,0) =  1.0/det;
00155     return inverse;
00156 };
00157 
00158 template<class T>
00159 boost::numeric::ublas::c_matrix<T, 2, 2> Inverse(const boost::numeric::ublas::c_matrix<T, 2, 2> &m)
00160 {
00161     using namespace boost::numeric::ublas;
00162 
00163     c_matrix<T, 2, 2> inverse;
00164     T det = Determinant(m);
00165 
00166     assert( fabs(det) > TINY ); //Else it is a singular matrix
00167     inverse(0,0)  =  m(1,1)/det;
00168     inverse(0,1)  = -m(0,1)/det;
00169     inverse(1,0)  = -m(1,0)/det;
00170     inverse(1,1)  =  m(0,0)/det;
00171     return inverse;
00172 };
00173 
00174 template<class T>
00175 boost::numeric::ublas::c_matrix<T, 3, 3> Inverse(const boost::numeric::ublas::c_matrix<T, 3, 3> &m)
00176 {
00177     using namespace boost::numeric::ublas;
00178 
00179     c_matrix<T, 3, 3> inverse;
00180     T det = Determinant(m);
00181     assert( fabs(det) > TINY ); //Else it is a singular matrix
00182     inverse(0,0)  =  (m(1,1)*m(2,2)-m(1,2)*m(2,1))/det;
00183     inverse(1,0)  =  -(m(1,0)*m(2,2)-m(1,2)*m(2,0))/det;
00184     inverse(2,0)  =  (m(1,0)*m(2,1)-m(1,1)*m(2,0))/det;
00185     inverse(0,1)  =  -(m(0,1)*m(2,2)-m(0,2)*m(2,1))/det;
00186     inverse(1,1)  =  (m(0,0)*m(2,2)-m(0,2)*m(2,0))/det;
00187     inverse(2,1)  =  -(m(0,0)*m(2,1)-m(0,1)*m(2,0))/det;
00188     inverse(0,2)  =  (m(0,1)*m(1,2)-m(0,2)*m(1,1))/det;
00189     inverse(1,2)  = - (m(0,0)*m(1,2)-m(0,2)*m(1,0))/det;
00190     inverse(2,2)  =  (m(0,0)*m(1,1)-m(0,1)*m(1,0))/det;
00191     return inverse;
00192 };
00193 
00194 template<class T>
00195 c_vector<T, 3> VectorProduct(const c_vector<T, 3> &a, const c_vector<T, 3> &b)
00196 {
00197     //This is a cross-product
00198     // What do you get when you cross an elephant with a banana?
00199     //only implemented for 3-vectors
00200 
00201     c_vector<T, 3>  result;
00202 
00203     double x1=a(0);
00204     double y1=a(1);
00205     double z1=a(2);
00206     double x2=b(0);
00207     double y2=b(1);
00208     double z2=b(2);
00209 
00210     result(0)=y1*z2-z1*y2;
00211     result(1)=z1*x2-x1*z2;
00212     result(2)=x1*y2-y1*x2;
00213 
00214     return result;
00215 }
00216 
00217 template<class T>
00218 T Trace(const c_matrix<T,1,1> &m)
00219 {
00220     return m(0,0);
00221 }
00222 
00223 template<class T>
00224 T Trace(const c_matrix<T,2,2> &m)
00225 {
00226     return m(0,0)+m(1,1);
00227 }
00228 
00229 template<class T>
00230 T Trace(const c_matrix<T,3,3> &m)
00231 {
00232     return m(0,0)+m(1,1)+m(2,2);
00233 }
00234 
00235 template<class T>
00236 T Trace(const c_matrix<T,4,4> &m)
00237 {
00238     return m(0,0)+m(1,1)+m(2,2)+m(3,3);
00239 }
00240 
00246 template<class T>
00247 T SecondInvariant(const c_matrix<T,3,3> &m)
00248 {
00249     return    m(0,0)*m(1,1) + m(1,1)*m(2,2) + m(2,2)*m(0,0)
00250             - m(1,0)*m(1,0) - m(2,1)*m(2,1) - m(2,0)*m(2,0);
00251 }
00252 
00257 template<class T>
00258 T SecondInvariant(const c_matrix<T,2,2> &m)
00259 {
00260     return Determinant(m);
00261 }
00262 
00263 
00267 c_vector<double, 1> Create_c_vector(double x);
00268 
00269 c_vector<double, 2> Create_c_vector(double x, double y);
00270 
00271 c_vector<double, 3> Create_c_vector(double x, double y, double z);
00272 
00281 c_vector<double,3> CalculateEigenvectorForSmallestNonzeroEigenvalue(c_matrix<double,3,3> &A);
00282 
00283 #endif /*UBLASCUSTOMFUNCTIONS_HPP_*/
00284 

Generated on Wed Mar 18 12:51:52 2009 for Chaste by  doxygen 1.5.5