1
0
Fork 0
flightgear/src/FDM/JSBSim/FGMatrix.cpp

557 lines
13 KiB
C++
Raw Normal View History

1999-02-13 01:12:03 +00:00
/*******************************************************************************
Module: FGMatrix.cpp
2000-04-24 23:49:06 +00:00
Author: Originally by Tony Peden [formatted here (and broken??) by JSB]
Date started: 1998
1999-02-13 01:12:03 +00:00
Purpose: FGMatrix class
Called by: Various
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
??/??/?? TP Created
2000-04-24 23:49:06 +00:00
03/16/2000 JSB Added exception throwing
1999-02-13 01:12:03 +00:00
********************************************************************************
INCLUDES
*******************************************************************************/
#include "FGMatrix.h"
/*******************************************************************************
************************************ CODE **************************************
*******************************************************************************/
2000-04-24 23:49:06 +00:00
double** FGalloc(int rows, int cols)
1999-02-13 01:12:03 +00:00
{
double **A;
A = new double *[rows+1];
2000-04-24 23:49:06 +00:00
if (!A) return NULL;
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
for (int i=0; i <= rows; i++){
A[i] = new double [cols+1];
1999-02-13 01:12:03 +00:00
if (!A[i]) return NULL;
}
return A;
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
void dealloc(double **A, int rows)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
for(int i=0;i<= rows;i++) delete[] A[i];
1999-02-13 01:12:03 +00:00
delete[] A;
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix::FGMatrix(const unsigned int r, const unsigned int c) : rows(r), cols(c)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
data = FGalloc(rows,cols);
2000-04-28 19:59:46 +00:00
InitMatrix();
2000-04-24 23:49:06 +00:00
rowCtr = colCtr = 1;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix::FGMatrix(const FGMatrix& M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
data = NULL;
rowCtr = colCtr = 1;
*this = M;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
FGMatrix::~FGMatrix(void)
{
2000-04-24 23:49:06 +00:00
dealloc(data,rows);
rowCtr = colCtr = 1;
rows = cols = 0;
}
/******************************************************************************/
ostream& operator<<(ostream& os, const FGMatrix& M)
{
for (unsigned int i=1; i<=M.Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
if (i == M.Rows() && j == M.Cols())
os << M.data[i][j];
else
os << M.data[i][j] << ", ";
1999-02-13 01:12:03 +00:00
}
}
2000-04-24 23:49:06 +00:00
return os;
}
/******************************************************************************/
FGMatrix& FGMatrix::operator<<(const float ff)
{
data[rowCtr][colCtr] = ff;
if (++colCtr > Cols()) {
colCtr = 1;
if (++rowCtr > Rows())
rowCtr = 1;
}
1999-02-13 01:12:03 +00:00
return *this;
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
istream& operator>>(istream& is, FGMatrix& M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=M.Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
is >> M.data[i][j];
}
}
return is;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix& FGMatrix::operator=(const FGMatrix& M)
{
if (&M != this) {
if (data != NULL) dealloc(data,rows);
width = M.width;
prec = M.prec;
delim = M.delim;
origin = M.origin;
rows = M.rows;
cols = M.cols;
data = FGalloc(rows,cols);
for (unsigned int i=0; i<=rows; i++) {
for (unsigned int j=0; j<=cols; j++) {
data[i][j] = M.data[i][j];
}
}
}
return *this;
}
/******************************************************************************/
unsigned int FGMatrix::Rows(void) const
1999-02-13 01:12:03 +00:00
{
return rows;
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
unsigned int FGMatrix::Cols(void) const
1999-02-13 01:12:03 +00:00
{
return cols;
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
{
2000-04-24 23:49:06 +00:00
FGMatrix::delim = delim;
FGMatrix::width = width;
FGMatrix::prec = prec;
FGMatrix::origin = origin;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
void FGMatrix::InitMatrix(double value)
{
if (data) {
1999-06-28 17:39:20 +00:00
for (unsigned int i=0;i<=rows;i++) {
2000-04-24 23:49:06 +00:00
for (unsigned int j=0;j<=cols;j++) {
operator()(i,j) = value;
}
}
}
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
void FGMatrix::InitMatrix(void)
{
2000-04-24 23:49:06 +00:00
this->InitMatrix(0);
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
// *****************************************************************************
// binary operators ************************************************************
// *****************************************************************************
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix FGMatrix::operator-(const FGMatrix& M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator -";
throw mE;
}
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix Diff(Rows(), Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
Diff(i,j) = data[i][j] - M(i,j);
2000-04-24 23:49:06 +00:00
}
}
return Diff;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
void FGMatrix::operator-=(const FGMatrix &M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator -=";
throw mE;
}
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
data[i][j] -= M(i,j);
2000-04-24 23:49:06 +00:00
}
}
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix FGMatrix::operator+(const FGMatrix& M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator +";
throw mE;
}
FGMatrix Sum(Rows(), Cols());
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
Sum(i,j) = data[i][j] + M(i,j);
2000-04-24 23:49:06 +00:00
}
}
return Sum;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
void FGMatrix::operator+=(const FGMatrix &M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
if ((Rows() != M.Rows()) || (Cols() != M.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator +=";
throw mE;
}
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
data[i][j]+=M(i,j);
2000-04-24 23:49:06 +00:00
}
}
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix operator*(double scalar, FGMatrix &M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
FGMatrix Product(M.Rows(), M.Cols());
for (unsigned int i=1; i<=M.Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
Product(i,j) = scalar*M(i,j);
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
}
return Product;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
void FGMatrix::operator*=(const double scalar)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
data[i][j] *= scalar;
1999-02-13 01:12:03 +00:00
}
}
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix FGMatrix::operator*(const FGMatrix& M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
if (Cols() != M.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator *";
throw mE;
}
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix Product(Rows(), M.Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
Product(i,j) = 0;
for (unsigned int k=1; k<=Cols(); k++) {
Product(i,j) += data[i][k] * M(k,j);
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
}
}
return Product;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
void FGMatrix::operator*=(const FGMatrix& M)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
if (Cols() != M.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Matrix operator *=";
throw mE;
}
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
double **prod;
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
prod = FGalloc(Rows(), M.Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=M.Cols(); j++) {
prod[i][j] = 0;
for (unsigned int k=1; k<=Cols(); k++) {
prod[i][j] += data[i][k] * M(k,j);
2000-04-24 23:49:06 +00:00
}
}
}
dealloc(data, Rows());
data = prod;
cols = M.cols;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
FGMatrix FGMatrix::operator/(const double scalar)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
FGMatrix Quot(Rows(), Cols());
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
Quot(i,j) = data[i][j]/scalar;
2000-04-24 23:49:06 +00:00
}
}
return Quot;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
void FGMatrix::operator/=(const double scalar)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=Rows(); i++) {
for (unsigned int j=1; j<=Cols(); j++) {
data[i][j]/=scalar;
2000-04-24 23:49:06 +00:00
}
}
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
void FGMatrix::T(void)
{
2000-04-24 23:49:06 +00:00
if (rows==cols)
TransposeSquare();
else
TransposeNonSquare();
}
/******************************************************************************/
FGColumnVector FGMatrix::operator*(const FGColumnVector& Col)
{
FGColumnVector Product(Col.Rows());
if (Cols() != Col.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator *";
throw mE;
}
for (unsigned int i=1;i<=Rows();i++) {
Product(i) = 0.00;
for (unsigned int j=1;j<=Cols();j++) {
Product(i) += Col(j)*data[i][j];
}
}
return Product;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
void FGMatrix::TransposeSquare(void)
{
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=rows; i++) {
for (unsigned int j=i+1; j<=cols; j++) {
double tmp = data[i][j];
data[i][j] = data[j][i];
data[j][i] = tmp;
}
}
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
void FGMatrix::TransposeNonSquare(void)
{
2000-04-24 23:49:06 +00:00
double **tran;
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
tran = FGalloc(rows,cols);
1999-02-13 01:12:03 +00:00
2000-04-24 23:49:06 +00:00
for (unsigned int i=1; i<=rows; i++) {
for (unsigned int j=1; j<=cols; j++) {
tran[j][i] = data[i][j];
}
}
dealloc(data,rows);
data = tran;
unsigned int m = rows;
rows = cols;
cols = m;
1999-02-13 01:12:03 +00:00
}
2000-04-24 23:49:06 +00:00
/******************************************************************************/
1999-02-13 01:12:03 +00:00
FGColumnVector::FGColumnVector(void):FGMatrix(3,1) { }
FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
2000-04-24 23:49:06 +00:00
FGColumnVector::FGColumnVector(const FGColumnVector& b):FGMatrix(b) { }
1999-02-13 01:12:03 +00:00
FGColumnVector::~FGColumnVector() { }
2000-04-24 23:49:06 +00:00
/******************************************************************************/
double& FGColumnVector::operator()(int m) const
{
return FGMatrix::operator()(m,1);
}
/******************************************************************************/
FGColumnVector operator*(const FGMatrix& Mat, const FGColumnVector& Col)
{
FGColumnVector Product(Col.Rows());
if (Mat.Cols() != Col.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator *";
throw mE;
}
for (unsigned int i=1;i<=Mat.Rows();i++) {
Product(i) = 0.00;
for (unsigned int j=1;j<=Mat.Cols();j++) {
Product(i) += Col(j)*Mat(i,j);
}
}
return Product;
}
/******************************************************************************/
FGColumnVector FGColumnVector::operator+(const FGColumnVector& C)
{
if (Rows() != C.Rows()) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator *";
throw mE;
}
FGColumnVector Sum(C.Rows());
for (unsigned int i=1; i<=C.Rows(); i++) {
Sum(i) = C(i) + data[i][1];
}
return Sum;
}
/******************************************************************************/
FGColumnVector FGColumnVector::operator*(const double scalar)
{
FGColumnVector Product(Rows());
for (unsigned int i=1; i<=Rows(); i++) Product(i) = scalar * data[i][1];
return Product;
}
/******************************************************************************/
FGColumnVector FGColumnVector::operator-(const FGColumnVector& V)
{
if ((Rows() != V.Rows()) || (Cols() != V.Cols())) {
MatrixException mE;
mE.Message = "Invalid row/column match in Column Vector operator -";
throw mE;
}
FGColumnVector Diff(Rows());
for (unsigned int i=1; i<=Rows(); i++) {
Diff(i) = data[i][1] - V(i);
}
return Diff;
}
/******************************************************************************/
2000-04-24 23:49:06 +00:00
FGColumnVector FGColumnVector::operator/(const double scalar)
{
FGColumnVector Quotient(Rows());
for (unsigned int i=1; i<=Rows(); i++) Quotient(i) = data[i][1] / scalar;
return Quotient;
}
/******************************************************************************/
FGColumnVector operator*(const double scalar, const FGColumnVector& C)
{
FGColumnVector Product(C.Rows());
for (unsigned int i=1; i<=C.Rows(); i++) {
Product(i) = scalar * C(i);
}
return Product;
}
/******************************************************************************/
float FGColumnVector::Magnitude(void)
{
double num=0.0;
if ((data[1][1] == 0.00) &&
(data[2][1] == 0.00) &&
(data[3][1] == 0.00))
{
return 0.00;
} else {
for (unsigned int i = 1; i<=Rows(); i++) num += data[i][1]*data[i][1];
return sqrt(num);
}
}
/******************************************************************************/
FGColumnVector FGColumnVector::Normalize(void)
1999-02-13 01:12:03 +00:00
{
2000-04-24 23:49:06 +00:00
return *this/Magnitude();
1999-02-13 01:12:03 +00:00
}