1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3 Header: FGMatrix33.h
4 Author: Tony Peden, Jon Berndt, Mathias Frolich
5 Date started: Unknown
6 
7  ------------- Copyright (C) 2001  Jon S. Berndt (jon@jsbsim.org) -------------
8 
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17  details.
18 
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25 
26 HISTORY
27 --------------------------------------------------------------------------------
28 ??/??/??   TP   Created
29 03/16/2000 JSB  Added exception throwing
30 03/06/2004 MF   Rework of the code to make it a bit compiler friendlier
31 
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 SENTRY
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
35 
36 #ifndef FGMATRIX33_H
37 #define FGMATRIX33_H
38 
39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 INCLUDES
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 
43 #include <string>
44 #include <iosfwd>
45 #include <stdexcept>
46 
47 #include "FGColumnVector3.h"
48 
49 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50 FORWARD DECLARATIONS
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
52 
53 namespace JSBSim {
54 
55 class FGColumnVector3;
56 class FGQuaternion;
57 
58 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 CLASS DOCUMENTATION
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61 
62 /** Exception convenience class.
63   */
64 
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 DECLARATION: MatrixException
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68 
69 // changed by James to inherit std::runtime_error, so that if this
70 // gets thrown, we can actually catch it.
71 class MatrixException : public std::runtime_error
72 {
73 public:
MatrixException(const std::string & msg)74     MatrixException(const std::string& msg) : std::runtime_error{msg} { }
75 };
76 
77 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 CLASS DOCUMENTATION
79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
80 
81   /** Handles matrix math operations.
82       @author Tony Peden, Jon Berndt, Mathias Froelich
83   */
84 
85 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 DECLARATION: FGMatrix33
87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
88 
89 class FGMatrix33
90 {
91 public:
92 
93   enum {
94     eRows = 3,
95     eColumns = 3
96   };
97 
98   /** Default initializer.
99 
100       Create a zero matrix.
101    */
102   FGMatrix33(void);
103 
104   /** Copy constructor.
105 
106       @param M Matrix which is used for initialization.
107 
108       Create copy of the matrix given in the argument.
109    */
FGMatrix33(const FGMatrix33 & M)110   FGMatrix33(const FGMatrix33& M)
111   {
112     data[0] = M.data[0];
113     data[1] = M.data[1];
114     data[2] = M.data[2];
115     data[3] = M.data[3];
116     data[4] = M.data[4];
117     data[5] = M.data[5];
118     data[6] = M.data[6];
119     data[7] = M.data[7];
120     data[8] = M.data[8];
121   }
122 
123   /** Initialization by given values.
124 
125       @param m11 value of the 1,1 Matrix element.
126       @param m12 value of the 1,2 Matrix element.
127       @param m13 value of the 1,3 Matrix element.
128       @param m21 value of the 2,1 Matrix element.
129       @param m22 value of the 2,2 Matrix element.
130       @param m23 value of the 2,3 Matrix element.
131       @param m31 value of the 3,1 Matrix element.
132       @param m32 value of the 3,2 Matrix element.
133       @param m33 value of the 3,3 Matrix element.
134 
135       Create a matrix from the doubles given in the arguments.
136    */
FGMatrix33(const double m11,const double m12,const double m13,const double m21,const double m22,const double m23,const double m31,const double m32,const double m33)137   FGMatrix33(const double m11, const double m12, const double m13,
138              const double m21, const double m22, const double m23,
139              const double m31, const double m32, const double m33)
140   {
141     data[0] = m11;
142     data[1] = m21;
143     data[2] = m31;
144     data[3] = m12;
145     data[4] = m22;
146     data[5] = m32;
147     data[6] = m13;
148     data[7] = m23;
149     data[8] = m33;
150   }
151 
152   /** Destructor.
153    */
~FGMatrix33(void)154   ~FGMatrix33(void) {}
155 
156   /** Prints the contents of the matrix.
157       @param delimeter the item separator (tab or comma)
158       @return a string with the delimeter-separated contents of the matrix  */
159   std::string Dump(const std::string& delimeter) const;
160 
161   /** Prints the contents of the matrix.
162       @param delimeter the item separator (tab or comma, etc.)
163       @param prefix an additional prefix that is used to indent the 3X3 matrix printout
164       @return a string with the delimeter-separated contents of the matrix  */
165   std::string Dump(const std::string& delimiter, const std::string& prefix) const;
166 
167   /** Read access the entries of the matrix.
168       @param row Row index.
169       @param col Column index.
170 
171       @return the value of the matrix entry at the given row and
172       column indices. Indices are counted starting with 1.
173    */
operator()174   double operator()(unsigned int row, unsigned int col) const {
175     return data[(col-1)*eRows+row-1];
176   }
177 
178   /** Write access the entries of the matrix.
179       Note that the indices given in the arguments are unchecked.
180 
181       @param row Row index.
182       @param col Column index.
183 
184       @return a reference to the matrix entry at the given row and
185       column indices. Indices are counted starting with 1.
186    */
operator()187   double& operator()(unsigned int row, unsigned int col) {
188     return data[(col-1)*eRows+row-1];
189   }
190 
191   /** Read access the entries of the matrix.
192       This function is just a shortcut for the <tt>double&
193       operator()(unsigned int row, unsigned int col)</tt> function. It is
194       used internally to access the elements in a more convenient way.
195 
196       Note that the indices given in the arguments are unchecked.
197 
198       @param row Row index.
199       @param col Column index.
200 
201       @return the value of the matrix entry at the given row and
202       column indices. Indices are counted starting with 1.
203    */
Entry(unsigned int row,unsigned int col)204   double Entry(unsigned int row, unsigned int col) const {
205     return data[(col-1)*eRows+row-1];
206   }
207 
208   /** Write access the entries of the matrix.
209       This function is just a shortcut for the <tt>double&
210       operator()(unsigned int row, unsigned int col)</tt> function. It is
211       used internally to access the elements in a more convenient way.
212 
213       Note that the indices given in the arguments are unchecked.
214 
215       @param row Row index.
216       @param col Column index.
217 
218       @return a reference to the matrix entry at the given row and
219       column indices. Indices are counted starting with 1.
220    */
Entry(unsigned int row,unsigned int col)221    double& Entry(unsigned int row, unsigned int col) {
222      return data[(col-1)*eRows+row-1];
223    }
224 
225   /** Number of rows in the matrix.
226       @return the number of rows in the matrix.
227    */
Rows(void)228    unsigned int Rows(void) const { return eRows; }
229 
230   /** Number of cloumns in the matrix.
231       @return the number of columns in the matrix.
232    */
Cols(void)233    unsigned int Cols(void) const { return eColumns; }
234 
235   /** Transposed matrix.
236       This function only returns the transpose of this matrix. This matrix itself
237       remains unchanged.
238       @return the transposed matrix.
239    */
Transposed(void)240   FGMatrix33 Transposed(void) const {
241     return FGMatrix33( data[0], data[1], data[2],
242                        data[3], data[4], data[5],
243                        data[6], data[7], data[8] );
244   }
245 
246   /** Transposes this matrix.
247       This function only transposes this matrix. Nothing is returned.
248    */
249   void T(void);
250 
251 /** Initialize the matrix.
252     This function initializes a matrix to all 0.0.
253  */
254   void InitMatrix(void);
255 
256 /** Initialize the matrix.
257     This function initializes a matrix to user specified values.
258  */
InitMatrix(const double m11,const double m12,const double m13,const double m21,const double m22,const double m23,const double m31,const double m32,const double m33)259   void InitMatrix(const double m11, const double m12, const double m13,
260                   const double m21, const double m22, const double m23,
261                   const double m31, const double m32, const double m33)
262   {
263     data[0] = m11;
264     data[1] = m21;
265     data[2] = m31;
266     data[3] = m12;
267     data[4] = m22;
268     data[5] = m32;
269     data[6] = m13;
270     data[7] = m23;
271     data[8] = m33;
272   }
273 
274   /** Returns the quaternion associated with this direction cosine (rotation) matrix.
275   */
276   FGQuaternion GetQuaternion(void) const;
277 
278   /** Returns the Euler angle column vector associated with this matrix.
279   */
280   FGColumnVector3 GetEuler() const;
281 
282   /** Determinant of the matrix.
283       @return the determinant of the matrix.
284    */
285   double Determinant(void) const;
286 
287   /** Return if the matrix is invertible.
288       Checks and returns if the matrix is nonsingular and thus
289       invertible. This is done by simply computing the determinant and
290       check if it is zero. Note that this test does not cover any
291       instabilities caused by nearly singular matirces using finite
292       arithmetics. It only checks exact singularity.
293    */
Invertible(void)294   bool Invertible(void) const { return 0.0 != Determinant(); }
295 
296   /** Return the inverse of the matrix.
297       Computes and returns if the inverse of the matrix. It is computed
298       by Cramers Rule. Also there are no checks performed if the matrix
299       is invertible. If you are not sure that it really is check this
300       with the @ref Invertible() call before.
301    */
302   FGMatrix33 Inverse(void) const;
303 
304   /** Assignment operator.
305 
306       @param A source matrix.
307 
308       Copy the content of the matrix given in the argument into *this.
309    */
310   FGMatrix33& operator=(const FGMatrix33& A)
311   {
312     data[0] = A.data[0];
313     data[1] = A.data[1];
314     data[2] = A.data[2];
315     data[3] = A.data[3];
316     data[4] = A.data[4];
317     data[5] = A.data[5];
318     data[6] = A.data[6];
319     data[7] = A.data[7];
320     data[8] = A.data[8];
321     return *this;
322   }
323 
324   /** Matrix vector multiplication.
325 
326       @param v vector to multiply with.
327       @return matric vector product.
328 
329       Compute and return the product of the current matrix with the
330       vector given in the argument.
331    */
332   FGColumnVector3 operator*(const FGColumnVector3& v) const;
333 
334   /** Matrix subtraction.
335 
336       @param B matrix to add to.
337       @return difference of the matrices.
338 
339       Compute and return the sum of the current matrix and the matrix
340       B given in the argument.
341   */
342   FGMatrix33 operator-(const FGMatrix33& B) const;
343 
344   /** Matrix addition.
345 
346       @param B matrix to add to.
347       @return sum of the matrices.
348 
349       Compute and return the sum of the current matrix and the matrix
350       B given in the argument.
351   */
352   FGMatrix33 operator+(const FGMatrix33& B) const;
353 
354   /** Matrix product.
355 
356       @param B matrix to add to.
357       @return product of the matrices.
358 
359       Compute and return the product of the current matrix and the matrix
360       B given in the argument.
361   */
362   FGMatrix33 operator*(const FGMatrix33& B) const;
363 
364   /** Multiply the matrix with a scalar.
365 
366       @param scalar scalar factor to multiply with.
367       @return scaled matrix.
368 
369       Compute and return the product of the current matrix with the
370       scalar value scalar given in the argument.
371   */
372   FGMatrix33 operator*(const double scalar) const;
373 
374   /** Multiply the matrix with 1.0/scalar.
375 
376       @param scalar scalar factor to divide through.
377       @return scaled matrix.
378 
379       Compute and return the product of the current matrix with the
380       scalar value 1.0/scalar, where scalar is given in the argument.
381   */
382   FGMatrix33 operator/(const double scalar) const;
383 
384   /** In place matrix subtraction.
385 
386       @param B matrix to subtract.
387       @return reference to the current matrix.
388 
389       Compute the diffence from the current matrix and the matrix B
390       given in the argument.
391   */
392   FGMatrix33& operator-=(const FGMatrix33 &B);
393 
394   /** In place matrix addition.
395 
396       @param B matrix to add.
397       @return reference to the current matrix.
398 
399       Compute the sum of the current matrix and the matrix B
400       given in the argument.
401   */
402   FGMatrix33& operator+=(const FGMatrix33 &B);
403 
404   /** In place matrix multiplication.
405 
406       @param B matrix to multiply with.
407       @return reference to the current matrix.
408 
409       Compute the product of the current matrix and the matrix B
410       given in the argument.
411   */
412   FGMatrix33& operator*=(const FGMatrix33 &B);
413 
414   /** In place matrix scale.
415 
416       @param scalar scalar value to multiply with.
417       @return reference to the current matrix.
418 
419       Compute the product of the current matrix and the scalar value scalar
420       given in the argument.
421   */
422   FGMatrix33& operator*=(const double scalar);
423 
424   /** In place matrix scale.
425 
426       @param scalar scalar value to divide through.
427       @return reference to the current matrix.
428 
429       Compute the product of the current matrix and the scalar value
430       1.0/scalar, where scalar is given in the argument.
431   */
432   FGMatrix33& operator/=(const double scalar);
433 
434 private:
435   double data[eRows*eColumns];
436 };
437 
438 /** Scalar multiplication.
439 
440     @param scalar scalar value to multiply with.
441     @param A Matrix to multiply.
442 
443     Multiply the Matrix with a scalar value.
444 */
445 inline FGMatrix33 operator*(double scalar, const FGMatrix33& A) {
446   // use already defined operation.
447   return A*scalar;
448 }
449 
450 /** Write matrix to a stream.
451 
452     @param os Stream to write to.
453     @param M Matrix to write.
454 
455     Write the matrix to a stream.
456 */
457 std::ostream& operator<<(std::ostream& os, const FGMatrix33& M);
458 
459 /** Read matrix from a stream.
460 
461     @param os Stream to read from.
462     @param M Matrix to initialize with the values from the stream.
463 
464     Read matrix from a stream.
465 */
466 std::istream& operator>>(std::istream& is, FGMatrix33& M);
467 
468 } // namespace JSBSim
469 #endif
470