📄 fgtable.cpp
字号:
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGTable.cpp Author: Jon S. Berndt Date started: 1/9/2001 Purpose: Models a lookup table ------------- Copyright (C) 2001 Jon S. Berndt (jsb@hal-pc.org) ------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Further information about the GNU Lesser General Public License can also be found on the world wide web at http://www.gnu.org.FUNCTIONAL DESCRIPTION--------------------------------------------------------------------------------Models a lookup tableHISTORY--------------------------------------------------------------------------------JSB 1/9/00 Created%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include "FGTable.h"#include <iomanip>using namespace std;namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_TABLE;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/FGTable::FGTable(int NRows) : nRows(NRows), nCols(1), PropertyManager(0){ Type = tt1D; colCounter = 0; rowCounter = 1; nTables = 0; Data = Allocate(); Debug(0); lastRowIndex=lastColumnIndex=2;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGTable::FGTable(const FGTable& t) : PropertyManager(t.PropertyManager){ Type = t.Type; colCounter = t.colCounter; rowCounter = t.rowCounter; tableCounter = t.tableCounter; nRows = t.nRows; nCols = t.nCols; nTables = t.nTables; dimension = t.dimension; internal = t.internal; Name = t.Name; lookupProperty[0] = t.lookupProperty[0]; lookupProperty[1] = t.lookupProperty[1]; lookupProperty[2] = t.lookupProperty[2]; Tables = t.Tables; Data = Allocate(); for (unsigned int r=0; r<=nRows; r++) { for (unsigned int c=0; c<=nCols; c++) { Data[r][c] = t.Data[r][c]; } } lastRowIndex = t.lastRowIndex; lastColumnIndex = t.lastColumnIndex; lastTableIndex = t.lastTableIndex;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGTable::FGTable(FGPropertyManager* propMan, Element* el) : PropertyManager(propMan){ unsigned int i; stringstream buf; string property_string; string lookup_axis; string call_type; string parent_type; string brkpt_string; FGPropertyManager* node; Element *tableData=0; Element *parent_element=0; Element *axisElement=0; string operation_types = "function, product, sum, difference, quotient," "pow, abs, sin, cos, asin, acos, tan, atan, table"; nTables = 0; // Is this an internal lookup table? internal = false; Name = el->GetAttributeValue("name"); // Allow this table to be named with a property call_type = el->GetAttributeValue("type"); if (call_type == string("internal")) { parent_element = el->GetParent(); parent_type = parent_element->GetName(); if (operation_types.find(parent_type) == string::npos) { internal = true; } else { // internal table is a child element of a restricted type cerr << endl << fgred << " An internal table cannot be nested within another type," << endl; cerr << " such as a function. The 'internal' keyword is ignored." << fgdef << endl << endl; } } else if (!call_type.empty()) { cerr << endl << fgred << " An unknown table type attribute is listed: " << call_type << ". Execution cannot continue." << fgdef << endl << endl; abort(); } // Determine and store the lookup properties for this table unless this table // is part of a 3D table, in which case its independentVar property indexes will // be set by a call from the owning table during creation dimension = 0; axisElement = el->FindElement("independentVar"); if (axisElement) { // The 'internal' attribute of the table element cannot be specified // at the same time that independentVars are specified. if (internal) { cerr << endl << fgred << " This table specifies both 'internal' call type" << endl; cerr << " and specific lookup properties via the 'independentVar' element." << endl; cerr << " These are mutually exclusive specifications. The 'internal'" << endl; cerr << " attribute will be ignored." << fgdef << endl << endl; internal = false; } for (i=0; i<3; i++) lookupProperty[i] = 0; while (axisElement) { property_string = axisElement->GetDataLine(); // The property string passed into GetNode() must have no spaces or tabs. node = PropertyManager->GetNode(property_string); if (node == 0) { cerr << "IndependenVar property, " << property_string << " in Table definition is not defined." << endl; abort(); } lookup_axis = axisElement->GetAttributeValue("lookup"); if (lookup_axis == string("row")) { lookupProperty[eRow] = node; } else if (lookup_axis == string("column")) { lookupProperty[eColumn] = node; } else if (lookup_axis == string("table")) { lookupProperty[eTable] = node; } else { // assumed single dimension table; row lookup lookupProperty[eRow] = node; } dimension++; axisElement = el->FindNextElement("independentVar"); } } else if (internal) { // This table is an internal table // determine how many rows, columns, and tables in this table (dimension). if (el->GetNumElements("tableData") > 1) { dimension = 3; // this is a 3D table } else { tableData = el->FindElement("tableData"); string test_line = tableData->GetDataLine(1); // examine second line in table for dimension if (FindNumColumns(test_line) == 2) dimension = 1; // 1D table else if (FindNumColumns(test_line) > 2) dimension = 2; // 2D table else { cerr << "Invalid number of columns in table" << endl; } } } else { brkpt_string = el->GetAttributeValue("breakPoint"); if (brkpt_string.empty()) { // no independentVars found, and table is not marked as internal, nor is it a 3D table cerr << endl << fgred << "No independent variable found for table." << fgdef << endl << endl; abort(); } } // end lookup property code if (brkpt_string.empty()) { // Not a 3D table "table element" tableData = el->FindElement("tableData"); } else { // This is a table in a 3D table tableData = el; dimension = 2; // Currently, infers 2D table } for (i=0; i<tableData->GetNumDataLines(); i++) { buf << tableData->GetDataLine(i) << string(" "); } switch (dimension) { case 1: nRows = tableData->GetNumDataLines(); nCols = 1; Type = tt1D; colCounter = 0; rowCounter = 1; Data = Allocate(); Debug(0); lastRowIndex = lastColumnIndex = 2; *this << buf; break; case 2: nRows = tableData->GetNumDataLines()-1; if (nRows >= 2) nCols = FindNumColumns(tableData->GetDataLine(0)); else { cerr << endl << fgred << "Not enough rows in this table." << fgdef << endl; abort(); } Type = tt2D; colCounter = 1; rowCounter = 0; Data = Allocate(); lastRowIndex = lastColumnIndex = 2; *this << buf; break; case 3: nTables = el->GetNumElements("tableData"); nRows = nTables; nCols = 1; Type = tt3D; colCounter = 1; rowCounter = 1; lastRowIndex = lastColumnIndex = 2; Data = Allocate(); // this data array will contain the keys for the associated tables Tables.reserve(nTables); // necessary? tableData = el->FindElement("tableData"); for (i=0; i<nTables; i++) { Tables.push_back(new FGTable(PropertyManager, tableData)); Data[i+1][1] = tableData->GetAttributeValueAsNumber("breakPoint"); Tables[i]->SetRowIndexProperty(lookupProperty[eRow]); Tables[i]->SetColumnIndexProperty(lookupProperty[eColumn]); tableData = el->FindNextElement("tableData"); } Debug(0); break; default: cout << "No dimension given" << endl; break; } bind(); if (debug_lvl & 1) Print();}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%double** FGTable::Allocate(void){ Data = new double*[nRows+1]; for (unsigned int r=0; r<=nRows; r++) { Data[r] = new double[nCols+1]; for (unsigned int c=0; c<=nCols; c++) { Data[r][c] = 0.0; } } return Data;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGTable::~FGTable(){ if (nTables > 0) { for (unsigned int i=0; i<nTables; i++) delete Tables[i]; Tables.clear(); } for (unsigned int r=0; r<=nRows; r++) delete[] Data[r]; delete[] Data; Debug(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -