1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 Author: Tony Peden, Jon Berndt, Mathias Frolich
6 Purpose: FGMatrix33 class
9 ------------- Copyright (C) 1998 by the authors above -------------
11 This program is free software; you can redistribute it and/or modify it under
12 the terms of the GNU Lesser General Public License as published by the Free Software
13 Foundation; either version 2 of the License, or (at your option) any later
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
21 You should have received a copy of the GNU Lesser General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place - Suite 330, Boston, MA 02111-1307, USA.
25 Further information about the GNU Lesser General Public License can also be found on
26 the world wide web at http://www.gnu.org.
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
32 --------------------------------------------------------------------------------
34 03/16/2000 JSB Added exception throwing
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40 #include "FGMatrix33.h"
41 #include "FGColumnVector3.h"
45 static const char *IdSrc = "$Id$";
46 static const char *IdHdr = ID_MATRIX33;
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
55 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 FGMatrix33::FGMatrix33(void)
59 data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
60 data[6] = data[7] = data[8] = 0.0;
65 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 std::ostream& operator<<(std::ostream& os, const FGMatrix33& M)
69 for (unsigned int i=1; i<=M.Rows(); i++) {
70 for (unsigned int j=1; j<=M.Cols(); j++) {
71 if (i == M.Rows() && j == M.Cols())
80 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 std::istream& operator>>(std::istream& is, FGMatrix33& M)
84 for (unsigned int i=1; i<=M.Rows(); i++) {
85 for (unsigned int j=1; j<=M.Cols(); j++) {
92 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94 double FGMatrix33::Determinant(void) const {
95 return Entry(1,1)*Entry(2,2)*Entry(3,3) + Entry(1,2)*Entry(2,3)*Entry(3,1)
96 + Entry(1,3)*Entry(2,1)*Entry(3,2) - Entry(1,3)*Entry(2,2)*Entry(3,1)
97 - Entry(1,2)*Entry(2,1)*Entry(3,3) - Entry(2,3)*Entry(3,2)*Entry(1,1);
100 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 FGMatrix33 FGMatrix33::Inverse(void) const {
103 // Compute the inverse of a general matrix using Cramers rule.
104 // I guess googling for cramers rule gives tons of references
106 double rdet = 1.0/Determinant();
108 double i11 = rdet*(Entry(2,2)*Entry(3,3)-Entry(2,3)*Entry(3,2));
109 double i21 = rdet*(Entry(2,3)*Entry(3,1)-Entry(2,1)*Entry(3,3));
110 double i31 = rdet*(Entry(2,1)*Entry(3,2)-Entry(2,2)*Entry(3,1));
111 double i12 = rdet*(Entry(1,3)*Entry(3,2)-Entry(1,2)*Entry(3,3));
112 double i22 = rdet*(Entry(1,1)*Entry(3,3)-Entry(1,3)*Entry(3,1));
113 double i32 = rdet*(Entry(1,2)*Entry(3,1)-Entry(1,1)*Entry(3,2));
114 double i13 = rdet*(Entry(1,2)*Entry(2,3)-Entry(1,3)*Entry(2,2));
115 double i23 = rdet*(Entry(1,3)*Entry(2,1)-Entry(1,1)*Entry(2,3));
116 double i33 = rdet*(Entry(1,1)*Entry(2,2)-Entry(1,2)*Entry(2,1));
118 return FGMatrix33( i11, i12, i13,
123 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125 void FGMatrix33::InitMatrix(void)
127 data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
128 data[6] = data[7] = data[8] = 0.0;
131 // *****************************************************************************
132 // binary operators ************************************************************
133 // *****************************************************************************
135 FGMatrix33 FGMatrix33::operator-(const FGMatrix33& M) const
137 return FGMatrix33( Entry(1,1) - M(1,1),
145 Entry(3,3) - M(3,3) );
148 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 FGMatrix33& FGMatrix33::operator-=(const FGMatrix33 &M)
152 data[0] -= M.data[0];
153 data[1] -= M.data[1];
154 data[2] -= M.data[2];
155 data[3] -= M.data[3];
156 data[4] -= M.data[4];
157 data[5] -= M.data[5];
158 data[6] -= M.data[6];
159 data[7] -= M.data[7];
160 data[8] -= M.data[8];
165 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 FGMatrix33 FGMatrix33::operator+(const FGMatrix33& M) const
169 return FGMatrix33( Entry(1,1) + M(1,1),
177 Entry(3,3) + M(3,3) );
180 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 FGMatrix33& FGMatrix33::operator+=(const FGMatrix33 &M)
184 Entry(1,1) += M(1,1);
185 Entry(1,2) += M(1,2);
186 Entry(1,3) += M(1,3);
187 Entry(2,1) += M(2,1);
188 Entry(2,2) += M(2,2);
189 Entry(2,3) += M(2,3);
190 Entry(3,1) += M(3,1);
191 Entry(3,2) += M(3,2);
192 Entry(3,3) += M(3,3);
197 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199 FGMatrix33 FGMatrix33::operator*(const double scalar) const
201 return FGMatrix33( scalar * Entry(1,1),
209 scalar * Entry(3,3) );
212 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 FGMatrix33 operator*(double scalar, FGMatrix33 &M)
216 return FGMatrix33( scalar * M(1,1),
227 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 FGMatrix33& FGMatrix33::operator*=(const double scalar)
231 Entry(1,1) *= scalar;
232 Entry(1,2) *= scalar;
233 Entry(1,3) *= scalar;
234 Entry(2,1) *= scalar;
235 Entry(2,2) *= scalar;
236 Entry(2,3) *= scalar;
237 Entry(3,1) *= scalar;
238 Entry(3,2) *= scalar;
239 Entry(3,3) *= scalar;
244 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246 FGMatrix33 FGMatrix33::operator*(const FGMatrix33& M) const
248 // FIXME: Make compiler friendlier
251 Product(1,1) = Entry(1,1)*M(1,1) + Entry(1,2)*M(2,1) + Entry(1,3)*M(3,1);
252 Product(1,2) = Entry(1,1)*M(1,2) + Entry(1,2)*M(2,2) + Entry(1,3)*M(3,2);
253 Product(1,3) = Entry(1,1)*M(1,3) + Entry(1,2)*M(2,3) + Entry(1,3)*M(3,3);
254 Product(2,1) = Entry(2,1)*M(1,1) + Entry(2,2)*M(2,1) + Entry(2,3)*M(3,1);
255 Product(2,2) = Entry(2,1)*M(1,2) + Entry(2,2)*M(2,2) + Entry(2,3)*M(3,2);
256 Product(2,3) = Entry(2,1)*M(1,3) + Entry(2,2)*M(2,3) + Entry(2,3)*M(3,3);
257 Product(3,1) = Entry(3,1)*M(1,1) + Entry(3,2)*M(2,1) + Entry(3,3)*M(3,1);
258 Product(3,2) = Entry(3,1)*M(1,2) + Entry(3,2)*M(2,2) + Entry(3,3)*M(3,2);
259 Product(3,3) = Entry(3,1)*M(1,3) + Entry(3,2)*M(2,3) + Entry(3,3)*M(3,3);
264 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 FGMatrix33& FGMatrix33::operator*=(const FGMatrix33& M)
268 // FIXME: Make compiler friendlier
271 a = Entry(1,1); b=Entry(1,2); c=Entry(1,3);
272 Entry(1,1) = a*M(1,1) + b*M(2,1) + c*M(3,1);
273 Entry(1,2) = a*M(1,2) + b*M(2,2) + c*M(3,2);
274 Entry(1,3) = a*M(1,3) + b*M(2,3) + c*M(3,3);
276 a = Entry(2,1); b=Entry(2,2); c=Entry(2,3);
277 Entry(2,1) = a*M(1,1) + b*M(2,1) + c*M(3,1);
278 Entry(2,2) = a*M(1,2) + b*M(2,2) + c*M(3,2);
279 Entry(2,3) = a*M(1,3) + b*M(2,3) + c*M(3,3);
281 a = Entry(3,1); b=Entry(3,2); c=Entry(3,3);
282 Entry(3,1) = a*M(1,1) + b*M(2,1) + c*M(3,1);
283 Entry(3,2) = a*M(1,2) + b*M(2,2) + c*M(3,2);
284 Entry(3,3) = a*M(1,3) + b*M(2,3) + c*M(3,3);
289 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 FGMatrix33 FGMatrix33::operator/(const double scalar) const
296 double tmp = 1.0/scalar;
297 Quot(1,1) = Entry(1,1) * tmp;
298 Quot(1,2) = Entry(1,2) * tmp;
299 Quot(1,3) = Entry(1,3) * tmp;
300 Quot(2,1) = Entry(2,1) * tmp;
301 Quot(2,2) = Entry(2,2) * tmp;
302 Quot(2,3) = Entry(2,3) * tmp;
303 Quot(3,1) = Entry(3,1) * tmp;
304 Quot(3,2) = Entry(3,2) * tmp;
305 Quot(3,3) = Entry(3,3) * tmp;
308 mE.Message = "Attempt to divide by zero in method FGMatrix33::operator/(const double scalar)";
314 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316 FGMatrix33& FGMatrix33::operator/=(const double scalar)
319 double tmp = 1.0/scalar;
331 mE.Message = "Attempt to divide by zero in method FGMatrix33::operator/=(const double scalar)";
337 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339 void FGMatrix33::T(void)
341 for (unsigned int i=1; i<=3; i++) {
342 for (unsigned int j=i+1; j<=3; j++) {
343 double tmp = Entry(i,j);
344 Entry(i,j) = Entry(j,i);
350 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352 FGColumnVector3 FGMatrix33::operator*(const FGColumnVector3& v) const {
353 double tmp1 = v(1)*Entry(1,1);
354 double tmp2 = v(1)*Entry(2,1);
355 double tmp3 = v(1)*Entry(3,1);
357 tmp1 += v(2)*Entry(1,2);
358 tmp2 += v(2)*Entry(2,2);
359 tmp3 += v(2)*Entry(3,2);
361 tmp1 += v(3)*Entry(1,3);
362 tmp2 += v(3)*Entry(2,3);
363 tmp3 += v(3)*Entry(3,3);
365 return FGColumnVector3( tmp1, tmp2, tmp3 );
368 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 // The bitmasked value choices are as follows:
370 // unset: In this case (the default) JSBSim would only print
371 // out the normally expected messages, essentially echoing
372 // the config files as they are read. If the environment
373 // variable is not set, debug_lvl is set to 1 internally
374 // 0: This requests JSBSim not to output any messages
376 // 1: This value explicity requests the normal JSBSim
378 // 2: This value asks for a message to be printed out when
379 // a class is instantiated
380 // 4: When this value is set, a message is displayed when a
381 // FGModel object executes its Run() method
382 // 8: When this value is set, various runtime state variables
383 // are printed out periodically
384 // 16: When set various parameters are sanity checked and
385 // a message is printed out when they go out of bounds
387 void FGMatrix33::Debug(int from)
389 if (debug_lvl <= 0) return;
391 if (debug_lvl & 1) { // Standard console startup message output
392 if (from == 0) { // Constructor
396 if (debug_lvl & 2 ) { // Instantiation/Destruction notification
397 if (from == 0) cout << "Instantiated: FGMatrix33" << endl;
398 if (from == 1) cout << "Destroyed: FGMatrix33" << endl;
400 if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
402 if (debug_lvl & 8 ) { // Runtime state variables
404 if (debug_lvl & 16) { // Sanity checking
406 if (debug_lvl & 64) {
407 if (from == 0) { // Constructor
408 cout << IdSrc << endl;
409 cout << IdHdr << endl;