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"
|
|
|
|
|
2000-10-14 02:10:10 +00:00
|
|
|
static const char *IdSrc = "$Header$";
|
|
|
|
static const char *IdHdr = ID_MATRIX;
|
|
|
|
|
1999-02-13 01:12:03 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
************************************ 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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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++) {
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
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());
|
|
|
|
|
2000-07-24 17:26:05 +00:00
|
|
|
if(scalar != 0) {
|
|
|
|
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
|
|
|
}
|
2000-07-24 17:26:05 +00:00
|
|
|
|
2000-08-04 16:08:55 +00:00
|
|
|
} else
|
|
|
|
cerr << "Attempt to divide by zero in method FGMatrix::operator/(const double scalar), object at " << this << endl;
|
|
|
|
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-08-04 16:08:55 +00:00
|
|
|
|
2000-07-24 17:26:05 +00:00
|
|
|
if(scalar != 0) {
|
|
|
|
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
|
|
|
}
|
2000-08-04 16:08:55 +00:00
|
|
|
} else
|
|
|
|
cerr << "Attempt to divide by zero in method FGMatrix::operator/=(const double scalar), object " << this << endl;
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
Updates from the Jon and Tony show.
Tony submitted:
JSBsim:
Added trimming routine, it is longitudinal & in-air only at this point
Added support for taking wind & weather data from external source
Added support for flaps.
Added independently settable pitch trim
Added alphamin and max to config file, stall modeling and warning to
follow
c172.cfg:
Flaps!
Adjusted Cmo, model should be speed stable now
FG:
Hooked up Christian's weather code, should be using it soon.
Hooked up the trimming routine. Note that the X-15 will not trim.
This is not a model or trimming routine deficiency, just the
nature of the X-15
The trimming routine sets the pitch trim and and throttle at startup.
The throttle is set using Norman's code for the autothrottle so the
autothrottle is on by default. --notrim will turn it off.
Added --vc, --mach, and --notrim switches
(vc is airspeed in knots)
uBody, vBody, and wBody are still supported, last one entered
on the command line counts, i.e. you can set vc or mach or u,v,
and w but any combination will be ignored.
2000-05-16 21:35:11 +00:00
|
|
|
|
|
|
|
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());
|
2000-07-24 17:26:05 +00:00
|
|
|
if(scalar != 0) {
|
2000-08-04 16:08:55 +00:00
|
|
|
|
|
|
|
|
2000-07-24 17:26:05 +00:00
|
|
|
for (unsigned int i=1; i<=Rows(); i++) Quotient(i) = data[i][1] / scalar;
|
2000-08-04 16:08:55 +00:00
|
|
|
|
|
|
|
} else
|
|
|
|
cerr << "Attempt to divide by zero in method FGColumnVector::operator/(const double scalar), object " << this << endl;
|
2000-04-24 23:49:06 +00:00
|
|
|
return Quotient;
|
2000-08-04 16:08:55 +00:00
|
|
|
|
|
|
|
|
2000-04-24 23:49:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
2000-05-27 05:48:14 +00:00
|
|
|
|
2000-04-24 23:49:06 +00:00
|
|
|
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-05-27 05:48:14 +00:00
|
|
|
double Mag = Magnitude();
|
|
|
|
|
2000-07-24 17:26:05 +00:00
|
|
|
if (Mag != 0) {
|
|
|
|
for (unsigned int i=1; i<=Rows(); i++)
|
|
|
|
for (unsigned int j=1; j<=Cols(); j++)
|
|
|
|
data[i][j] = data[i][j]/Mag;
|
|
|
|
}
|
2000-05-27 05:48:14 +00:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
FGColumnVector FGColumnVector::operator*(const FGColumnVector& V)
|
|
|
|
{
|
|
|
|
if (Rows() != 3 || V.Rows() != 3) {
|
|
|
|
MatrixException mE;
|
|
|
|
mE.Message = "Invalid row count in vector cross product function";
|
|
|
|
throw mE;
|
|
|
|
}
|
|
|
|
|
|
|
|
FGColumnVector Product(3);
|
|
|
|
|
|
|
|
Product(1) = data[2][1] * V(3) - data[3][1] * V(2);
|
|
|
|
Product(2) = data[3][1] * V(1) - data[1][1] * V(3);
|
|
|
|
Product(3) = data[1][1] * V(2) - data[2][1] * V(1);
|
|
|
|
|
|
|
|
return Product;
|
1999-02-13 01:12:03 +00:00
|
|
|
}
|
|
|
|
|
2000-05-27 05:48:14 +00:00
|
|
|
/******************************************************************************/
|
|
|
|
|
2000-07-06 21:02:46 +00:00
|
|
|
FGColumnVector FGColumnVector::multElementWise(const FGColumnVector& V)
|
|
|
|
{
|
|
|
|
if (Rows() != 3 || V.Rows() != 3) {
|
|
|
|
MatrixException mE;
|
|
|
|
mE.Message = "Invalid row count in vector cross product function";
|
|
|
|
throw mE;
|
|
|
|
}
|
|
|
|
|
|
|
|
FGColumnVector Product(3);
|
|
|
|
|
|
|
|
Product(1) = data[1][1] * V(1);
|
|
|
|
Product(2) = data[2][1] * V(2);
|
|
|
|
Product(3) = data[3][1] * V(3);
|
|
|
|
|
|
|
|
return Product;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|