gml_ElMat2.h

Go to the documentation of this file.
00001 /** @file gml_ElMat2.h
00002  * 
00003  *     Basic operations on row-major 2x2 matrices and 2x1 vectors.
00004  * 
00005  *  Copyright (c) 1997-2004 The CLIPS-IMAG Laboratory
00006  * 
00007  *  See the file "license.terms" for information on usage and redistribution
00008  *  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00009  * 
00010  *  Created in March, 1997 (FB).
00011  *  Updated to GML in February, 2004 (JL).
00012  */
00013 #ifndef __GML_ELMAT2__
00014 #define __GML_ELMAT2__
00015 
00016 // system includes
00017 #include <math.h>
00018 
00019 // project includes
00020 #include "gml/base/gml_Errors.h"
00021 
00022 
00023 /// gml_EM2_Invert --
00024 ///
00025 /// Invert the <source> matrix in <dest>.
00026 /// <source> and <dest> may be indentical.
00027 /// Return an error if <source> is not invertible.
00028 
00029 template <class T>
00030 inline static
00031 gml_TError gml_EM2_Invert (T* source, T* dest);
00032 
00033 
00034 /// gml_EM2_Det --
00035 ///
00036 /// Return the determinant of <source>
00037 
00038 template <class T>
00039 inline static
00040 T gml_EM2_Det (T* source);
00041 
00042 
00043 /// gml_EM2_AddMat --
00044 ///
00045 /// Add the two matrix <a> and <b> and put the result in <dest>
00046 /// <dest> may be <a> or <b>
00047 
00048 template <class T>
00049 inline static
00050 void gml_EM2_AddMat (T* a, T* b, T* dest);
00051 
00052 /// gml_EM2_AddVect --
00053 ///
00054 /// Add the two vectors <a> and <b> and put the result in <dest>
00055 /// <dest> may be <a> or <b>
00056 
00057 template <class T>
00058 inline static
00059 void gml_EM2_AddVect (T* a, T* b, T* dest);
00060 
00061 /// gml_EM2_MultVect --
00062 ///
00063 /// Multiply matrix <a> anv vector <b> and put the result in <dest>
00064 /// <dest> may be <a> or <b>.
00065 
00066 template <class T>
00067 inline static
00068 void gml_EM2_MultVect (T* a, T* b, T* dest);
00069 
00070 /// gml_EM2_EigenStuff --
00071 ///
00072 /// Return in <e> the eigenvalues of matrix <a>. Largest value goes in
00073 /// first position. The corresponding eigenvectors are returned in
00074 /// <v>. <v> contains 2 values: v[0] is the 2nd component of eigenvector
00075 /// corresponding to eigenvalue e[0] (its first component is choosen as 1)
00076 /// v[1] corresponds to e[1].
00077 
00078 template <class T>
00079 inline static
00080 gml_TError gml_EM2_EigenStuff (T* a, T* e, T* v);
00081 
00082 /// gml_EM2_EigenVal --
00083 ///
00084 /// Return in <e> the eigenvalues of matrix <a>. Largest value goes in
00085 /// first position.
00086 
00087 template <class T>
00088 inline static
00089 gml_TError gml_EM2_EigenVal (T* a, T* e);
00090 
00091 /// gml_EM2_EigenVect --
00092 ///
00093 /// Return in <v> the eigenvectors of matrix <a>. <v> contains 2 values:
00094 /// v[0] is the 2nd component of eigenvector corresponding to the largest
00095 /// eigenvalue (its first component is choosen as 1)
00096 /// v[1] corresponds to the smallest eigenvalue
00097 
00098 template <class T>
00099 inline static
00100 gml_TError gml_EM2_EigenVect (T* a, T* v);
00101 
00102 
00103 
00104 // Implementation follows.
00105 ////////////////////////////////////////////////////////////////////////////////
00106 
00107 //
00108 // gml_EM2_Invert
00109 //
00110 
00111 template <class T>
00112 inline static
00113 gml_TError gml_EM2_Invert (T* source, T* dest)
00114 {
00115 //  gml_EM2Init ();
00116 
00117   T a         = source[0];
00118   T b         = source[2];
00119   T c         = source[1];
00120   T d         = source[3];
00121 
00122   T det       = gml_EM2_Det (source);
00123   T invdet;
00124 
00125   if (det == 0) {
00126     return gml_gDivideByZero;
00127   }
00128 
00129   invdet  = 1/det;
00130 
00131   dest[0] =  d * invdet;
00132   dest[1] = -c * invdet;
00133   dest[2] = -b * invdet;
00134   dest[3] =  a * invdet;
00135 
00136   return gml_cNoError;
00137 }
00138 
00139 
00140 
00141 
00142 
00143 //
00144 // gml_EM2_Det
00145 //
00146 
00147 template <class T>
00148 inline static
00149 T gml_EM2_Det (T* source)
00150 {
00151   T a         = source[0];
00152   T b         = source[2];
00153   T c         = source[1];
00154   T d         = source[3];
00155 
00156   return a*d - b*c;
00157 }
00158 
00159 
00160 
00161 
00162 //
00163 // gml_EM2_AddMat
00164 //
00165 
00166 template <class T>
00167 inline static
00168 void gml_EM2_AddMat (T* a, T* b, T* dest)
00169 {
00170   dest[0] = a[0]+b[0];
00171   dest[1] = a[1]+b[1];
00172   dest[2] = a[2]+b[2];
00173   dest[3] = a[3]+b[3];
00174 }
00175 
00176 
00177 
00178 
00179 //
00180 // gml_EM2_AddVect
00181 //
00182 
00183 template <class T>
00184 inline static
00185 void gml_EM2_AddVect (T* a, T* b, T* dest)
00186 {
00187   dest[0] = a[0]+b[0];
00188   dest[1] = a[1]+b[1];
00189 }
00190 
00191 
00192 
00193 
00194 //
00195 // gml_EM2_MultVect
00196 //
00197 
00198 template <class T>
00199 inline static
00200 void gml_EM2_MultVect (T* a, T* b, T* dest)
00201 {
00202   T   tmp = b[0];
00203 
00204   dest[0] = a[0]*tmp + a[2]*b[1];
00205   dest[1] = a[1]*tmp + a[3]*b[1];
00206 }
00207 
00208 
00209 
00210 
00211 //
00212 // gml_EM2_EigenStuff
00213 //
00214 
00215 template <class T>
00216 inline static
00217 gml_TError gml_EM2_EigenStuff (T* a, T* e, T* v)
00218 {
00219   if (gml_EM2_EigenVal (a, e) != gml_cNoError)
00220     return gml_gDivideByZero;
00221 
00222   v[0] = - (a[0] - e[0]) / a[1];
00223   v[1] = - (a[0] - e[1]) / a[1];
00224 
00225   return gml_cNoError;
00226 }
00227 
00228 
00229 
00230 
00231 //
00232 // gml_EM2_EigenVal
00233 //
00234 
00235 template <class T>
00236 inline static
00237 gml_TError gml_EM2_EigenVal (T* a, T* e)
00238 {
00239   T ad, bc, apd, sq, del, l1, l2;
00240   
00241   assert (a[1] == a[2]);
00242   
00243   ad    = apd = a[0];
00244   bc    = a[1];
00245   bc   *= bc;
00246   ad   *= a[3];
00247   apd  += a[3];
00248   del   = apd*apd - 4*(ad - bc);
00249 
00250   if (del < 0)
00251     return gml_gDivideByZero;
00252   
00253   sq    = Sqrt (del);
00254   l1    = (apd + sq) / 2;
00255   l2    = (apd - sq) / 2;
00256 
00257   // l1 should be always greater (or equal) to l2
00258 
00259   e[0] = l1;
00260   e[1] = l2;
00261 
00262   return gml_cNoError;
00263 }
00264 
00265 
00266 
00267 
00268 //
00269 // gml_EM2_EigenVect
00270 //
00271 
00272 template <class T>
00273 inline static
00274 gml_TError gml_EM2_EigenVect (T* a, T* v)
00275 {
00276   T   e[2];
00277 
00278   return gml_EM2_EigenStuff (a, e, v);
00279 }
00280 
00281 #endif /* __GML_ELMAT2__ */
00282 
Generated on Tue Jun 12 14:03:27 2007 for gml by Doxygen 1.5.2.