1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 Author: Originally by Tony Peden [formatted here (and broken??) by JSB]
6 Purpose: FGMatrix class
10 --------------------------------------------------------------------------------
13 --------------------------------------------------------------------------------
15 03/16/2000 JSB Added exception throwing
17 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
23 static const char *IdSrc = "$Id$";
24 static const char *IdHdr = ID_MATRIX;
26 extern short debug_lvl;
28 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
32 double** FGalloc(int rows, int cols)
36 A = new double *[rows+1];
39 for (int i=0; i <= rows; i++){
40 A[i] = new double [cols+1];
41 if (!A[i]) return NULL;
46 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 void dealloc(double **A, int rows)
50 for (int i=0; i <= rows; i++) delete[] A[i];
54 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 FGMatrix::FGMatrix(const unsigned int r, const unsigned int c) : rows(r), cols(c)
58 data = FGalloc(rows,cols);
62 if (debug_lvl & 2) cout << "Instantiated: FGMatrix" << endl;
65 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 FGMatrix::FGMatrix(const FGMatrix& M)
73 if (debug_lvl & 2) cout << "Instantiated: FGMatrix" << endl;
76 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 FGMatrix::~FGMatrix(void)
84 if (debug_lvl & 2) cout << "Destroyed: FGMatrix" << endl;
87 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 ostream& operator<<(ostream& os, const FGMatrix& M)
91 for (unsigned int i=1; i<=M.Rows(); i++) {
92 for (unsigned int j=1; j<=M.Cols(); j++) {
93 if (i == M.Rows() && j == M.Cols())
96 os << M.data[i][j] << ", ";
102 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 FGMatrix& FGMatrix::operator<<(const float ff)
106 data[rowCtr][colCtr] = ff;
107 if (++colCtr > Cols()) {
109 if (++rowCtr > Rows())
115 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117 istream& operator>>(istream& is, FGMatrix& M)
119 for (unsigned int i=1; i<=M.Rows(); i++) {
120 for (unsigned int j=1; j<=M.Cols(); j++) {
127 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 FGMatrix& FGMatrix::operator=(const FGMatrix& M)
132 if (data != NULL) dealloc(data,rows);
141 data = FGalloc(rows,cols);
142 for (unsigned int i=0; i<=rows; i++) {
143 for (unsigned int j=0; j<=cols; j++) {
144 data[i][j] = M.data[i][j];
151 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153 unsigned int FGMatrix::Rows(void) const
158 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 unsigned int FGMatrix::Cols(void) const
165 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
169 FGMatrix::delim = delim;
170 FGMatrix::width = width;
171 FGMatrix::prec = prec;
172 FGMatrix::origin = origin;
175 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 void FGMatrix::InitMatrix(double value)
180 for (unsigned int i=0;i<=rows;i++) {
181 for (unsigned int j=0;j<=cols;j++) {
182 operator()(i,j) = value;
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190 void FGMatrix::InitMatrix(void)
195 // *****************************************************************************
196 // binary operators ************************************************************
197 // *****************************************************************************
199 FGMatrix FGMatrix::operator-(const FGMatrix& M)
201 FGMatrix Diff(Rows(), Cols());
203 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
205 mE.Message = "Invalid row/column match in Matrix operator -";
209 for (unsigned int i=1; i<=Rows(); i++) {
210 for (unsigned int j=1; j<=Cols(); j++) {
211 Diff(i,j) = data[i][j] - M(i,j);
217 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219 void FGMatrix::operator-=(const FGMatrix &M)
221 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
223 mE.Message = "Invalid row/column match in Matrix operator -=";
227 for (unsigned int i=1; i<=Rows(); i++) {
228 for (unsigned int j=1; j<=Cols(); j++) {
229 data[i][j] -= M(i,j);
234 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 FGMatrix FGMatrix::operator+(const FGMatrix& M)
238 FGMatrix Sum(Rows(), Cols());
240 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
242 mE.Message = "Invalid row/column match in Matrix operator +";
246 for (unsigned int i=1; i<=Rows(); i++) {
247 for (unsigned int j=1; j<=Cols(); j++) {
248 Sum(i,j) = data[i][j] + M(i,j);
254 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
256 void FGMatrix::operator+=(const FGMatrix &M)
258 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
260 mE.Message = "Invalid row/column match in Matrix operator +=";
264 for (unsigned int i=1; i<=Rows(); i++) {
265 for (unsigned int j=1; j<=Cols(); j++) {
271 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273 FGMatrix operator*(double scalar, FGMatrix &M)
275 FGMatrix Product(M.Rows(), M.Cols());
277 for (unsigned int i=1; i<=M.Rows(); i++) {
278 for (unsigned int j=1; j<=M.Cols(); j++) {
279 Product(i,j) = scalar*M(i,j);
285 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287 void FGMatrix::operator*=(const double scalar)
289 for (unsigned int i=1; i<=Rows(); i++) {
290 for (unsigned int j=1; j<=Cols(); j++) {
291 data[i][j] *= scalar;
296 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 FGMatrix FGMatrix::operator*(const FGMatrix& M)
300 FGMatrix Product(Rows(), M.Cols());
302 if (Cols() != M.Rows()) {
304 mE.Message = "Invalid row/column match in Matrix operator *";
308 for (unsigned int i=1; i<=Rows(); i++) {
309 for (unsigned int j=1; j<=M.Cols(); j++) {
311 for (unsigned int k=1; k<=Cols(); k++) {
312 Product(i,j) += data[i][k] * M(k,j);
319 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
321 void FGMatrix::operator*=(const FGMatrix& M)
323 if (Cols() != M.Rows()) {
325 mE.Message = "Invalid row/column match in Matrix operator *=";
331 prod = FGalloc(Rows(), M.Cols());
332 for (unsigned int i=1; i<=Rows(); i++) {
333 for (unsigned int j=1; j<=M.Cols(); j++) {
335 for (unsigned int k=1; k<=Cols(); k++) {
336 prod[i][j] += data[i][k] * M(k,j);
340 dealloc(data, Rows());
345 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 FGMatrix FGMatrix::operator/(const double scalar)
349 FGMatrix Quot(Rows(), Cols());
352 for (unsigned int i=1; i<=Rows(); i++) {
353 for (unsigned int j=1; j<=Cols(); j++) {
354 Quot(i,j) = data[i][j]/scalar;
359 cerr << "Attempt to divide by zero in method FGMatrix::operator/(const double scalar), object at " << this << endl;
364 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366 void FGMatrix::operator/=(const double scalar)
370 for (unsigned int i=1; i<=Rows(); i++) {
371 for (unsigned int j=1; j<=Cols(); j++) {
376 cerr << "Attempt to divide by zero in method FGMatrix::operator/=(const double scalar), object " << this << endl;
379 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 void FGMatrix::T(void)
386 TransposeNonSquare();
389 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391 FGColumnVector FGMatrix::operator*(const FGColumnVector& Col)
393 FGColumnVector Product(Col.Rows());
395 if (Cols() != Col.Rows()) {
397 mE.Message = "Invalid row/column match in Column Vector operator *";
401 for (unsigned int i=1;i<=Rows();i++) {
403 for (unsigned int j=1;j<=Cols();j++) {
404 Product(i) += Col(j)*data[i][j];
410 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 void FGMatrix::TransposeSquare(void)
414 for (unsigned int i=1; i<=rows; i++) {
415 for (unsigned int j=i+1; j<=cols; j++) {
416 double tmp = data[i][j];
417 data[i][j] = data[j][i];
423 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425 void FGMatrix::TransposeNonSquare(void)
429 tran = FGalloc(rows,cols);
431 for (unsigned int i=1; i<=rows; i++) {
432 for (unsigned int j=1; j<=cols; j++) {
433 tran[j][i] = data[i][j];
440 unsigned int m = rows;
445 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
447 void FGMatrix::Debug(void)
449 //TODO: Add your source code here
452 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
454 FGColumnVector::FGColumnVector(void):FGMatrix(3,1)
456 if (debug_lvl & 2) cout << "Instantiated: FGColumnVector" << endl;
459 FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
460 FGColumnVector::FGColumnVector(const FGColumnVector& b):FGMatrix(b) { }
462 FGColumnVector::~FGColumnVector(void)
464 // dealloc(data,rows);
465 if (debug_lvl & 2) cout << "Destroyed: FGColumnVector" << endl;
468 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 double& FGColumnVector::operator()(int m) const
472 return FGMatrix::operator()(m,1);
475 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477 FGColumnVector operator*(const FGMatrix& Mat, const FGColumnVector& Col)
479 FGColumnVector Product(Col.Rows());
481 if (Mat.Cols() != Col.Rows()) {
483 mE.Message = "Invalid row/column match in Column Vector operator *";
487 for (unsigned int i=1;i<=Mat.Rows();i++) {
489 for (unsigned int j=1;j<=Mat.Cols();j++) {
490 Product(i) += Col(j)*Mat(i,j);
497 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 FGColumnVector FGColumnVector::operator+(const FGColumnVector& C)
501 FGColumnVector Sum(C.Rows()); // This must be created dynamically
502 // because we don't know the size of "C",
503 // it could be 3 or 4 or ...
504 if (Rows() != C.Rows()) {
506 mE.Message = "Invalid row/column match in Column Vector operator *";
510 for (unsigned int i=1; i<=C.Rows(); i++) Sum(i) = C(i) + data[i][1];
515 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517 FGColumnVector FGColumnVector::operator*(const double scalar)
519 FGColumnVector Product(Rows());
521 for (unsigned int i=1; i<=Rows(); i++) Product(i) = scalar * data[i][1];
526 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
528 FGColumnVector FGColumnVector::operator-(const FGColumnVector& V)
530 FGColumnVector Diff(Rows());
532 if ((Rows() != V.Rows()) || (Cols() != V.Cols())) {
534 mE.Message = "Invalid row/column match in Column Vector operator -";
538 for (unsigned int i=1; i<=Rows(); i++) {
539 Diff(i) = data[i][1] - V(i);
545 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
547 FGColumnVector FGColumnVector::operator/(const double scalar)
549 FGColumnVector Quotient(Rows());
552 for (unsigned int i=1; i<=Rows(); i++) Quotient(i) = data[i][1] / scalar;
554 cerr << "Attempt to divide by zero in method FGColumnVector::operator/(const double scalar), object " << this << endl;
559 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561 FGColumnVector operator*(const double scalar, const FGColumnVector& C)
563 FGColumnVector Product(C.Rows());
565 for (unsigned int i=1; i<=C.Rows(); i++) {
566 Product(i) = scalar * C(i);
572 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 float FGColumnVector::Magnitude(void)
578 if ((data[1][1] == 0.00) &&
579 (data[2][1] == 0.00) &&
580 (data[3][1] == 0.00))
584 for (unsigned int i = 1; i<=Rows(); i++) num += data[i][1]*data[i][1];
589 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 FGColumnVector FGColumnVector::Normalize(void)
593 double Mag = Magnitude();
596 for (unsigned int i=1; i<=Rows(); i++)
597 for (unsigned int j=1; j<=Cols(); j++)
598 data[i][j] = data[i][j]/Mag;
604 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606 FGColumnVector& FGColumnVector::operator*(const FGColumnVector& V)
608 static FGColumnVector Product(3);
610 if (Rows() != 3 || V.Rows() != 3) {
612 mE.Message = "Invalid row count in vector cross product function";
616 Product(1) = data[2][1] * V(3) - data[3][1] * V(2);
617 Product(2) = data[3][1] * V(1) - data[1][1] * V(3);
618 Product(3) = data[1][1] * V(2) - data[2][1] * V(1);
623 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
625 FGColumnVector& FGColumnVector::multElementWise(const FGColumnVector& V)
627 static FGColumnVector Product(3);
629 if (Rows() != 3 || V.Rows() != 3) {
631 mE.Message = "Invalid row count in vector cross product function";
635 Product(1) = data[1][1] * V(1);
636 Product(2) = data[2][1] * V(2);
637 Product(3) = data[3][1] * V(3);
642 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644 void FGColumnVector::Debug(void)
646 //TODO: Add your source code here
649 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%