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);
57 /******************************************************************************/
59 FGMatrix::FGMatrix(const FGMatrix& M)
66 /******************************************************************************/
68 FGMatrix::~FGMatrix(void)
75 /******************************************************************************/
77 ostream& operator<<(ostream& os, const FGMatrix& M)
79 for (unsigned int i=1; i<=M.Rows(); i++) {
80 for (unsigned int j=1; j<=M.Cols(); j++) {
81 if (i == M.Rows() && j == M.Cols())
84 os << M.data[i][j] << ", ";
90 /******************************************************************************/
92 FGMatrix& FGMatrix::operator<<(const float ff)
94 data[rowCtr][colCtr] = ff;
95 if (++colCtr > Cols()) {
97 if (++rowCtr > Rows())
103 /******************************************************************************/
105 istream& operator>>(istream& is, FGMatrix& M)
107 for (unsigned int i=1; i<=M.Rows(); i++) {
108 for (unsigned int j=1; j<=M.Cols(); j++) {
115 /******************************************************************************/
117 FGMatrix& FGMatrix::operator=(const FGMatrix& M)
120 if (data != NULL) dealloc(data,rows);
129 data = FGalloc(rows,cols);
130 for (unsigned int i=0; i<=rows; i++) {
131 for (unsigned int j=0; j<=cols; j++) {
132 data[i][j] = M.data[i][j];
139 /******************************************************************************/
141 unsigned int FGMatrix::Rows(void) const
146 /******************************************************************************/
148 unsigned int FGMatrix::Cols(void) const
153 /******************************************************************************/
155 void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
157 FGMatrix::delim = delim;
158 FGMatrix::width = width;
159 FGMatrix::prec = prec;
160 FGMatrix::origin = origin;
163 /******************************************************************************/
165 void FGMatrix::InitMatrix(double value)
168 for (unsigned int i=0;i<=rows;i++) {
169 for (unsigned int j=0;j<=cols;j++) {
170 operator()(i,j) = value;
176 /******************************************************************************/
178 void FGMatrix::InitMatrix(void)
183 // *****************************************************************************
184 // binary operators ************************************************************
185 // *****************************************************************************
187 FGMatrix FGMatrix::operator-(const FGMatrix& M)
189 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
191 mE.Message = "Invalid row/column match in Matrix operator -";
195 FGMatrix Diff(Rows(), Cols());
197 for (unsigned int i=1; i<=Rows(); i++) {
198 for (unsigned int j=1; j<=Cols(); j++) {
199 Diff(i,j) = (*this)(i,j) - M(i,j);
205 /******************************************************************************/
207 void FGMatrix::operator-=(const FGMatrix &M)
209 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
211 mE.Message = "Invalid row/column match in Matrix operator -=";
215 for (unsigned int i=1; i<=Rows(); i++) {
216 for (unsigned int j=1; j<=Cols(); j++) {
217 (*this)(i,j) -= M(i,j);
222 /******************************************************************************/
224 FGMatrix FGMatrix::operator+(const FGMatrix& M)
226 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
228 mE.Message = "Invalid row/column match in Matrix operator +";
232 FGMatrix Sum(Rows(), Cols());
234 for (unsigned int i=1; i<=Rows(); i++) {
235 for (unsigned int j=1; j<=Cols(); j++) {
236 Sum(i,j) = (*this)(i,j) + M(i,j);
242 /******************************************************************************/
244 void FGMatrix::operator+=(const FGMatrix &M)
246 if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
248 mE.Message = "Invalid row/column match in Matrix operator +=";
252 for (unsigned int i=1; i<=Rows(); i++) {
253 for (unsigned int j=1; j<=Cols(); j++) {
254 (*this)(i,j)+=M(i,j);
259 /******************************************************************************/
261 FGMatrix operator*(double scalar, FGMatrix &M)
263 FGMatrix Product(M.Rows(), M.Cols());
265 for (unsigned int i=1; i<=M.Rows(); i++) {
266 for (unsigned int j=1; j<=M.Cols(); j++) {
267 Product(i,j) = scalar*M(i,j);
273 /******************************************************************************/
275 void FGMatrix::operator*=(const double scalar)
277 for (unsigned int i=1; i<=Rows(); i++) {
278 for (unsigned int j=1; j<=Cols(); j++) {
279 (*this)(i,j) *= scalar;
284 /******************************************************************************/
286 FGMatrix FGMatrix::operator*(const FGMatrix& M)
288 if (Cols() != M.Rows()) {
290 mE.Message = "Invalid row/column match in Matrix operator *";
294 FGMatrix Product(Rows(), M.Cols());
296 for (unsigned int i=1; i<=Rows(); i++) {
297 for (unsigned int j=1; j<=M.Cols(); j++) {
299 for (unsigned int k=1; k<=Cols(); k++) {
300 Product(i,j) += (*this)(i,k) * M(k,j);
307 /******************************************************************************/
309 void FGMatrix::operator*=(const FGMatrix& M)
311 if (Cols() != M.Rows()) {
313 mE.Message = "Invalid row/column match in Matrix operator *=";
319 prod = FGalloc(Rows(), M.Cols());
320 for (unsigned int i=1; i<=Rows(); i++) {
321 for (unsigned int j=1; j<=M.Cols(); j++) {
323 for (unsigned int k=1; k<=Cols(); k++) {
324 prod[i][j] += (*this)(i,k) * M(k,j);
328 dealloc(data, Rows());
333 /******************************************************************************/
335 FGMatrix FGMatrix::operator/(const double scalar)
337 FGMatrix Quot(Rows(), Cols());
339 for (unsigned int i=1; i<=Rows(); i++) {
340 for (unsigned int j=1; j<=Cols(); j++) {
341 Quot(i,j) = (*this)(i,j)/scalar;
347 /******************************************************************************/
349 void FGMatrix::operator/=(const double scalar)
351 for (unsigned int i=1; i<=Rows(); i++) {
352 for (unsigned int j=1; j<=Cols(); j++) {
353 (*this)(i,j)/=scalar;
358 /******************************************************************************/
360 void FGMatrix::T(void)
365 TransposeNonSquare();
368 /******************************************************************************/
370 FGColumnVector FGMatrix::operator*(const FGColumnVector& Col)
372 FGColumnVector Product(Col.Rows());
374 if (Cols() != Col.Rows()) {
376 mE.Message = "Invalid row/column match in Column Vector operator *";
380 for (unsigned int i=1;i<=Rows();i++) {
382 for (unsigned int j=1;j<=Cols();j++) {
383 Product(i) += Col(j)*data[i][j];
389 /******************************************************************************/
391 void FGMatrix::TransposeSquare(void)
393 for (unsigned int i=1; i<=rows; i++) {
394 for (unsigned int j=i+1; j<=cols; j++) {
395 double tmp = data[i][j];
396 data[i][j] = data[j][i];
402 /******************************************************************************/
404 void FGMatrix::TransposeNonSquare(void)
408 tran = FGalloc(rows,cols);
410 for (unsigned int i=1; i<=rows; i++) {
411 for (unsigned int j=1; j<=cols; j++) {
412 tran[j][i] = data[i][j];
419 unsigned int m = rows;
424 /******************************************************************************/
426 FGColumnVector::FGColumnVector(void):FGMatrix(3,1) { }
427 FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
428 FGColumnVector::FGColumnVector(const FGColumnVector& b):FGMatrix(b) { }
429 FGColumnVector::~FGColumnVector() { }
431 /******************************************************************************/
433 double& FGColumnVector::operator()(int m) const
435 return FGMatrix::operator()(m,1);
438 /******************************************************************************/
440 FGColumnVector operator*(const FGMatrix& Mat, const FGColumnVector& Col)
442 FGColumnVector Product(Col.Rows());
444 if (Mat.Cols() != Col.Rows()) {
446 mE.Message = "Invalid row/column match in Column Vector operator *";
450 for (unsigned int i=1;i<=Mat.Rows();i++) {
452 for (unsigned int j=1;j<=Mat.Cols();j++) {
453 Product(i) += Col(j)*Mat(i,j);
460 /******************************************************************************/
462 FGColumnVector FGColumnVector::operator+(const FGColumnVector& C)
464 if (Rows() != C.Rows()) {
466 mE.Message = "Invalid row/column match in Column Vector operator *";
470 FGColumnVector Sum(C.Rows());
472 for (unsigned int i=1; i<=C.Rows(); i++) {
473 Sum(i) = C(i) + data[i][1];
479 /******************************************************************************/
481 FGColumnVector FGColumnVector::operator*(const double scalar)
483 FGColumnVector Product(Rows());
485 for (unsigned int i=1; i<=Rows(); i++) Product(i) = scalar * data[i][1];
490 /******************************************************************************/
492 FGColumnVector FGColumnVector::operator/(const double scalar)
494 FGColumnVector Quotient(Rows());
496 for (unsigned int i=1; i<=Rows(); i++) Quotient(i) = data[i][1] / scalar;
501 /******************************************************************************/
503 FGColumnVector operator*(const double scalar, const FGColumnVector& C)
505 FGColumnVector Product(C.Rows());
507 for (unsigned int i=1; i<=C.Rows(); i++) {
508 Product(i) = scalar * C(i);
514 /******************************************************************************/
515 float FGColumnVector::Magnitude(void)
519 if ((data[1][1] == 0.00) &&
520 (data[2][1] == 0.00) &&
521 (data[3][1] == 0.00))
525 for (unsigned int i = 1; i<=Rows(); i++) num += data[i][1]*data[i][1];
530 /******************************************************************************/
532 FGColumnVector FGColumnVector::Normalize(void)
534 return *this/Magnitude();