MOAB: Mesh Oriented datABase  (version 5.4.1)
SymMatrix3D.hpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2007 Sandia National Laboratories.  Developed at the
00005     University of Wisconsin--Madison under SNL contract number
00006     624796.  The U.S. Government and the University of Wisconsin
00007     retain certain rights to this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023     (2008) [email protected]
00024 
00025   ***************************************************************** */
00026 
00027 /** \file SymMatrix3D.hpp
00028  *  \brief Symetric 3x3 Matrix
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #ifndef MSQ_SYM_MATRIX_3D_HPP
00033 #define MSQ_SYM_MATRIX_3D_HPP
00034 
00035 #include "Mesquite.hpp"
00036 #include "Vector3D.hpp"
00037 
00038 namespace MBMesquite
00039 {
00040 
00041 class MESQUITE_EXPORT SymMatrix3D
00042 {
00043   private:
00044     double d_[6];
00045 
00046   public:
00047     enum Term
00048     {
00049         T00 = 0,
00050         T01 = 1,
00051         T02 = 2,
00052         T10 = T01,
00053         T11 = 3,
00054         T12 = 4,
00055         T20 = T02,
00056         T21 = T12,
00057         T22 = 5
00058     };
00059 
00060     inline static Term term( unsigned r, unsigned c )
00061     {
00062         return (Term)( r <= c ? 3 * r - r * ( r + 1 ) / 2 + c : 3 * c - c * ( c + 1 ) / 2 + r );
00063     }
00064 
00065     SymMatrix3D() {}
00066 
00067     SymMatrix3D( double diagonal_value )
00068     {
00069         d_[T00] = d_[T11] = d_[T22] = diagonal_value;
00070         d_[T01] = d_[T02] = d_[T12] = 0.0;
00071     }
00072 
00073     SymMatrix3D( double t00, double t01, double t02, double t11, double t12, double t22 )
00074     {
00075         d_[T00] = t00;
00076         d_[T01] = t01;
00077         d_[T02] = t02;
00078         d_[T11] = t11;
00079         d_[T12] = t12;
00080         d_[T22] = t22;
00081     }
00082 
00083     /**\brief Outer product */
00084     SymMatrix3D( const Vector3D& u )
00085     {
00086         d_[T00] = u[0] * u[0];
00087         d_[T01] = u[0] * u[1];
00088         d_[T02] = u[0] * u[2];
00089         d_[T11] = u[1] * u[1];
00090         d_[T12] = u[1] * u[2];
00091         d_[T22] = u[2] * u[2];
00092     }
00093 
00094     double& operator[]( unsigned t )
00095     {
00096         return d_[t];
00097     }
00098     double operator[]( unsigned t ) const
00099     {
00100         return d_[t];
00101     }
00102 
00103     double& operator()( unsigned short r, unsigned short c )
00104     {
00105         return d_[term( r, c )];
00106     }
00107     double operator()( unsigned short r, unsigned short c ) const
00108     {
00109         return d_[term( r, c )];
00110     }
00111 
00112     inline SymMatrix3D& operator+=( const SymMatrix3D& other );
00113     inline SymMatrix3D& operator-=( const SymMatrix3D& other );
00114     inline SymMatrix3D& operator*=( double scalar );
00115     inline SymMatrix3D& operator/=( double scalar );
00116 };
00117 
00118 inline SymMatrix3D operator-( const SymMatrix3D& m )
00119 {
00120     return SymMatrix3D( -m[SymMatrix3D::T00], -m[SymMatrix3D::T01], -m[SymMatrix3D::T02], -m[SymMatrix3D::T11],
00121                         -m[SymMatrix3D::T12], -m[SymMatrix3D::T22] );
00122 }
00123 
00124 inline SymMatrix3D& SymMatrix3D::operator+=( const SymMatrix3D& other )
00125 {
00126     d_[0] += other.d_[0];
00127     d_[1] += other.d_[1];
00128     d_[2] += other.d_[2];
00129     d_[3] += other.d_[3];
00130     d_[4] += other.d_[4];
00131     d_[5] += other.d_[5];
00132     return *this;
00133 }
00134 
00135 inline SymMatrix3D& SymMatrix3D::operator-=( const SymMatrix3D& other )
00136 {
00137     d_[0] -= other.d_[0];
00138     d_[1] -= other.d_[1];
00139     d_[2] -= other.d_[2];
00140     d_[3] -= other.d_[3];
00141     d_[4] -= other.d_[4];
00142     d_[5] -= other.d_[5];
00143     return *this;
00144 }
00145 
00146 inline SymMatrix3D& SymMatrix3D::operator*=( double s )
00147 {
00148     d_[0] *= s;
00149     d_[1] *= s;
00150     d_[2] *= s;
00151     d_[3] *= s;
00152     d_[4] *= s;
00153     d_[5] *= s;
00154     return *this;
00155 }
00156 
00157 inline SymMatrix3D& SymMatrix3D::operator/=( double s )
00158 {
00159     d_[0] /= s;
00160     d_[1] /= s;
00161     d_[2] /= s;
00162     d_[3] /= s;
00163     d_[4] /= s;
00164     d_[5] /= s;
00165     return *this;
00166 }
00167 
00168 inline SymMatrix3D operator+( const SymMatrix3D& a, const SymMatrix3D& b )
00169 {
00170     SymMatrix3D r( a );
00171     r += b;
00172     return r;
00173 }
00174 inline SymMatrix3D operator-( const SymMatrix3D& a, const SymMatrix3D& b )
00175 {
00176     SymMatrix3D r( a );
00177     r -= b;
00178     return r;
00179 }
00180 inline SymMatrix3D operator*( const SymMatrix3D& a, double s )
00181 {
00182     SymMatrix3D r( a );
00183     r *= s;
00184     return r;
00185 }
00186 inline SymMatrix3D operator*( double s, const SymMatrix3D& a )
00187 {
00188     SymMatrix3D r( a );
00189     r *= s;
00190     return r;
00191 }
00192 inline SymMatrix3D operator/( const SymMatrix3D& a, double s )
00193 {
00194     SymMatrix3D r( a );
00195     r /= s;
00196     return r;
00197 }
00198 inline SymMatrix3D operator/( double s, const SymMatrix3D& a )
00199 {
00200     SymMatrix3D r( a );
00201     r /= s;
00202     return r;
00203 }
00204 
00205 inline Vector3D operator*( const Vector3D& v, const SymMatrix3D& m )
00206 {
00207     return Vector3D( v[0] * m[0] + v[1] * m[1] + v[2] * m[2], v[0] * m[1] + v[1] * m[3] + v[2] * m[4],
00208                      v[0] * m[2] + v[1] * m[4] + v[2] * m[5] );
00209 }
00210 inline Vector3D operator*( const SymMatrix3D& m, const Vector3D& v )
00211 {
00212     return v * m;
00213 }
00214 
00215 /** Calculate the outer product of a vector with itself */
00216 inline SymMatrix3D outer( const Vector3D& v )
00217 {
00218     return SymMatrix3D( v[0] * v[0], v[0] * v[1], v[0] * v[2], v[1] * v[1], v[1] * v[2], v[2] * v[2] );
00219 }
00220 
00221 /** Given to vectors u and v, calculate the symmetric matrix
00222  *  equal to outer(u,v) + transpose(outer(u,v))
00223  *  equal to outer(v,u) + transpose(outer(v,u))
00224  */
00225 inline SymMatrix3D outer_plus_transpose( const Vector3D& u, const Vector3D& v )
00226 {
00227     return SymMatrix3D( 2 * u[0] * v[0], u[0] * v[1] + u[1] * v[0], u[0] * v[2] + u[2] * v[0], 2 * u[1] * v[1],
00228                         u[1] * v[2] + u[2] * v[1], 2 * u[2] * v[2] );
00229 }
00230 
00231 inline const SymMatrix3D& transpose( const SymMatrix3D& a )
00232 {
00233     return a;
00234 }
00235 
00236 inline double det( const SymMatrix3D& a )
00237 {
00238     return a[0] * a[3] * a[5] + 2.0 * a[1] * a[2] * a[4] - a[0] * a[4] * a[4] - a[3] * a[2] * a[2] - a[5] * a[1] * a[1];
00239 }
00240 
00241 inline SymMatrix3D inverse( const SymMatrix3D& a )
00242 {
00243     SymMatrix3D result( a[3] * a[5] - a[4] * a[4], a[2] * a[4] - a[1] * a[5], a[1] * a[4] - a[2] * a[3],
00244                         a[0] * a[5] - a[2] * a[2], a[1] * a[2] - a[0] * a[4], a[0] * a[3] - a[1] * a[1] );
00245     result /= det( a );
00246     return result;
00247 }
00248 
00249 inline double Frobenius_2( const SymMatrix3D& a )
00250 {
00251     return a[0] * a[0] + 2 * a[1] * a[1] + 2 * a[2] * a[2] + a[3] * a[3] + 2 * a[4] * a[5] + a[5] * a[5];
00252 }
00253 
00254 inline double Frobenius( const SymMatrix3D& a )
00255 {
00256     return std::sqrt( Frobenius_2( a ) );
00257 }
00258 
00259 }  // namespace MBMesquite
00260 
00261 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines