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 /*******************************************************************************
24 ************************************ CODE **************************************
25 *******************************************************************************/
27 double** FGalloc(int rows, int cols)
31 A = new double *[rows+1];
34 for (int i=0; i <= rows; i++){
35 A[i] = new double [cols+1];
36 if (!A[i]) return NULL;
41 /******************************************************************************/
43 void dealloc(double **A, int rows)
45 for(int i=0;i<= rows;i++) delete[] A[i];
49 /******************************************************************************/
51 FGMatrix::FGMatrix(const unsigned int r, const unsigned int c) : rows(r), cols(c)
53 data = FGalloc(rows,cols);
58 /******************************************************************************/
60 FGMatrix::FGMatrix(const FGMatrix& M)
67 /******************************************************************************/
69 FGMatrix::~FGMatrix(void)
76 /******************************************************************************/
78 ostream& operator<<(ostream& os, const FGMatrix& M)
80 for (unsigned int i=1; i<=M.Rows(); i++) {
81 for (unsigned int j=1; j<=M.Cols(); j++) {
82 if (i == M.Rows() && j == M.Cols())
85 os << M.data[i][j] << ", ";
91 /******************************************************************************/
93 FGMatrix& FGMatrix::operator<<(const float ff)
95 data[rowCtr][colCtr] = ff;
96 if (++colCtr > Cols()) {
98 if (++rowCtr > Rows())
104 /******************************************************************************/
106 istream& operator>>(istream& is, FGMatrix& M)
108 for (unsigned int i=1; i<=M.Rows(); i++) {
109 for (unsigned int j=1; j<=M.Cols(); j++) {
116 /******************************************************************************/
118 FGMatrix& FGMatrix::operator=(const FGMatrix& M)
121 if (data != NULL) dealloc(data,rows);
130 data = FGalloc(rows,cols);
131 for (unsigned int i=0; i<=rows; i++) {
132 for (unsigned int j=0; j<=cols; j++) {
133 data[i][j] = M.data[i][j];
140 /******************************************************************************/
142 unsigned int FGMatrix::Rows(void) const
147 /******************************************************************************/
149 unsigned int FGMatrix::Cols(void) const
154 /******************************************************************************/
156 void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
158 FGMatrix::delim = delim;
159 FGMatrix::width = width;
160 FGMatrix::prec = prec;
161 FGMatrix::origin = origin;
164 /******************************************************************************/
166 void FGMatrix::InitMatrix(double value)
169 for (unsigned int i=0;i<=rows;i++) {
170 for (unsigned int j=0;j<=cols;j++) {
171 operator()(i,j) = value;
177 /******************************************************************************/
179 void FGMatrix::InitMatrix(void)
184 // *****************************************************************************
185 // binary operators ************************************************************
186 // *****************************************************************************
188 FGMatrix FGMatrix::operator-(const FGMatrix& M)
190 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
192 mE.Message = "Invalid row/column match in Matrix operator -";
196 FGMatrix Diff(Rows(), Cols());
198 for (unsigned int i=1; i<=Rows(); i++) {
199 for (unsigned int j=1; j<=Cols(); j++) {
200 Diff(i,j) = data[i][j] - M(i,j);
206 /******************************************************************************/
208 void FGMatrix::operator-=(const FGMatrix &M)
210 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
212 mE.Message = "Invalid row/column match in Matrix operator -=";
216 for (unsigned int i=1; i<=Rows(); i++) {
217 for (unsigned int j=1; j<=Cols(); j++) {
218 data[i][j] -= M(i,j);
223 /******************************************************************************/
225 FGMatrix FGMatrix::operator+(const FGMatrix& M)
227 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
229 mE.Message = "Invalid row/column match in Matrix operator +";
233 FGMatrix Sum(Rows(), Cols());
235 for (unsigned int i=1; i<=Rows(); i++) {
236 for (unsigned int j=1; j<=Cols(); j++) {
237 Sum(i,j) = data[i][j] + M(i,j);
243 /******************************************************************************/
245 void FGMatrix::operator+=(const FGMatrix &M)
247 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
249 mE.Message = "Invalid row/column match in Matrix operator +=";
253 for (unsigned int i=1; i<=Rows(); i++) {
254 for (unsigned int j=1; j<=Cols(); j++) {
260 /******************************************************************************/
262 FGMatrix operator*(double scalar, FGMatrix &M)
264 FGMatrix Product(M.Rows(), M.Cols());
266 for (unsigned int i=1; i<=M.Rows(); i++) {
267 for (unsigned int j=1; j<=M.Cols(); j++) {
268 Product(i,j) = scalar*M(i,j);
274 /******************************************************************************/
276 void FGMatrix::operator*=(const double scalar)
278 for (unsigned int i=1; i<=Rows(); i++) {
279 for (unsigned int j=1; j<=Cols(); j++) {
280 data[i][j] *= scalar;
285 /******************************************************************************/
287 FGMatrix FGMatrix::operator*(const FGMatrix& M)
289 if (Cols() != M.Rows()) {
291 mE.Message = "Invalid row/column match in Matrix operator *";
295 FGMatrix Product(Rows(), M.Cols());
297 for (unsigned int i=1; i<=Rows(); i++) {
298 for (unsigned int j=1; j<=M.Cols(); j++) {
300 for (unsigned int k=1; k<=Cols(); k++) {
301 Product(i,j) += data[i][k] * M(k,j);
308 /******************************************************************************/
310 void FGMatrix::operator*=(const FGMatrix& M)
312 if (Cols() != M.Rows()) {
314 mE.Message = "Invalid row/column match in Matrix operator *=";
320 prod = FGalloc(Rows(), M.Cols());
321 for (unsigned int i=1; i<=Rows(); i++) {
322 for (unsigned int j=1; j<=M.Cols(); j++) {
324 for (unsigned int k=1; k<=Cols(); k++) {
325 prod[i][j] += data[i][k] * M(k,j);
329 dealloc(data, Rows());
334 /******************************************************************************/
336 FGMatrix FGMatrix::operator/(const double scalar)
338 FGMatrix Quot(Rows(), Cols());
341 for (unsigned int i=1; i<=Rows(); i++) {
342 for (unsigned int j=1; j<=Cols(); j++) {
343 Quot(i,j) = data[i][j]/scalar;
351 /******************************************************************************/
353 void FGMatrix::operator/=(const double scalar)
357 for (unsigned int i=1; i<=Rows(); i++) {
358 for (unsigned int j=1; j<=Cols(); j++) {
365 /******************************************************************************/
367 void FGMatrix::T(void)
372 TransposeNonSquare();
375 /******************************************************************************/
377 FGColumnVector FGMatrix::operator*(const FGColumnVector& Col)
379 FGColumnVector Product(Col.Rows());
381 if (Cols() != Col.Rows()) {
383 mE.Message = "Invalid row/column match in Column Vector operator *";
387 for (unsigned int i=1;i<=Rows();i++) {
389 for (unsigned int j=1;j<=Cols();j++) {
390 Product(i) += Col(j)*data[i][j];
396 /******************************************************************************/
398 void FGMatrix::TransposeSquare(void)
400 for (unsigned int i=1; i<=rows; i++) {
401 for (unsigned int j=i+1; j<=cols; j++) {
402 double tmp = data[i][j];
403 data[i][j] = data[j][i];
409 /******************************************************************************/
411 void FGMatrix::TransposeNonSquare(void)
415 tran = FGalloc(rows,cols);
417 for (unsigned int i=1; i<=rows; i++) {
418 for (unsigned int j=1; j<=cols; j++) {
419 tran[j][i] = data[i][j];
426 unsigned int m = rows;
431 /******************************************************************************/
433 FGColumnVector::FGColumnVector(void):FGMatrix(3,1) { }
434 FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
435 FGColumnVector::FGColumnVector(const FGColumnVector& b):FGMatrix(b) { }
436 FGColumnVector::~FGColumnVector() { }
438 /******************************************************************************/
440 double& FGColumnVector::operator()(int m) const
442 return FGMatrix::operator()(m,1);
445 /******************************************************************************/
447 FGColumnVector operator*(const FGMatrix& Mat, const FGColumnVector& Col)
449 FGColumnVector Product(Col.Rows());
451 if (Mat.Cols() != Col.Rows()) {
453 mE.Message = "Invalid row/column match in Column Vector operator *";
457 for (unsigned int i=1;i<=Mat.Rows();i++) {
459 for (unsigned int j=1;j<=Mat.Cols();j++) {
460 Product(i) += Col(j)*Mat(i,j);
467 /******************************************************************************/
469 FGColumnVector FGColumnVector::operator+(const FGColumnVector& C)
471 if (Rows() != C.Rows()) {
473 mE.Message = "Invalid row/column match in Column Vector operator *";
477 FGColumnVector Sum(C.Rows());
479 for (unsigned int i=1; i<=C.Rows(); i++) {
480 Sum(i) = C(i) + data[i][1];
486 /******************************************************************************/
488 FGColumnVector FGColumnVector::operator*(const double scalar)
490 FGColumnVector Product(Rows());
492 for (unsigned int i=1; i<=Rows(); i++) Product(i) = scalar * data[i][1];
497 /******************************************************************************/
499 FGColumnVector FGColumnVector::operator-(const FGColumnVector& V)
501 if ((Rows() != V.Rows()) || (Cols() != V.Cols())) {
503 mE.Message = "Invalid row/column match in Column Vector operator -";
507 FGColumnVector Diff(Rows());
509 for (unsigned int i=1; i<=Rows(); i++) {
510 Diff(i) = data[i][1] - V(i);
516 /******************************************************************************/
518 FGColumnVector FGColumnVector::operator/(const double scalar)
520 FGColumnVector Quotient(Rows());
522 for (unsigned int i=1; i<=Rows(); i++) Quotient(i) = data[i][1] / scalar;
527 /******************************************************************************/
529 FGColumnVector operator*(const double scalar, const FGColumnVector& C)
531 FGColumnVector Product(C.Rows());
533 for (unsigned int i=1; i<=C.Rows(); i++) {
534 Product(i) = scalar * C(i);
540 /******************************************************************************/
542 float FGColumnVector::Magnitude(void)
546 if ((data[1][1] == 0.00) &&
547 (data[2][1] == 0.00) &&
548 (data[3][1] == 0.00))
552 for (unsigned int i = 1; i<=Rows(); i++) num += data[i][1]*data[i][1];
557 /******************************************************************************/
559 FGColumnVector FGColumnVector::Normalize(void)
561 double Mag = Magnitude();
564 for (unsigned int i=1; i<=Rows(); i++)
565 for (unsigned int j=1; j<=Cols(); j++)
566 data[i][j] = data[i][j]/Mag;
572 /******************************************************************************/
574 FGColumnVector FGColumnVector::operator*(const FGColumnVector& V)
576 if (Rows() != 3 || V.Rows() != 3) {
578 mE.Message = "Invalid row count in vector cross product function";
582 FGColumnVector Product(3);
584 Product(1) = data[2][1] * V(3) - data[3][1] * V(2);
585 Product(2) = data[3][1] * V(1) - data[1][1] * V(3);
586 Product(3) = data[1][1] * V(2) - data[2][1] * V(1);
591 /******************************************************************************/
593 FGColumnVector FGColumnVector::multElementWise(const FGColumnVector& V)
595 if (Rows() != 3 || V.Rows() != 3) {
597 mE.Message = "Invalid row count in vector cross product function";
601 FGColumnVector Product(3);
603 Product(1) = data[1][1] * V(1);
604 Product(2) = data[2][1] * V(2);
605 Product(3) = data[3][1] * V(3);
610 /******************************************************************************/