13 #include "../utility/strutil.h"
21 "respond to a request for a value lookup" );
32 "Looks up table value based on indices v1 and v2, and sends"
33 "value back using the 'lookupOut' message",
36 static Finfo* lookupReturnShared[] =
41 static SharedFinfo lookupReturn2D(
"lookupReturn2D",
42 "This is a shared message for doing lookups on the table. "
43 "Receives 2 doubles: x, y. "
44 "Sends back a double with the looked-up z value.",
45 lookupReturnShared,
sizeof( lookupReturnShared ) /
sizeof(
Finfo * )
52 "Minimum value for x axis of lookup table",
57 "Maximum value for x axis of lookup table",
62 "# of divisions on x axis of lookup table",
67 "Increment on x axis of lookup table",
72 "Minimum value for y axis of lookup table",
77 "Maximum value for y axis of lookup table",
82 "# of divisions on y axis of lookup table",
87 "Increment on y axis of lookup table",
93 "Lookup an entry on the table",
98 tableVector2D(
"tableVector2D",
99 "Get the entire table.",
105 "Interpolated value for specified x and y. This is provided for"
106 " debugging. Normally other objects will retrieve interpolated values"
107 " via lookup message.",
117 static Finfo* interpol2DFinfos[] =
133 static string doc[] =
135 "Name",
"Interpol2D",
136 "Author",
"Niraj Dudani, 2009, NCBS",
137 "Description",
"Interpol2D: Interpolation class. "
138 "Handles lookup from a 2-dimensional grid of real-numbered values. "
139 "Returns 'z' value based on given 'x' and 'y' values. "
140 "Can either use interpolation or roundoff to the nearest index.",
147 interpol2DFinfos,
sizeof( interpol2DFinfos ) /
sizeof(
Finfo * ),
150 sizeof(doc)/
sizeof(
string)
164 : xmin_( 0.0 ), xmax_( 1.0 ), invDx_( 1.0 ),
165 ymin_( 0.0 ), ymax_( 1.0 ), invDy_( 1.0 ),
169 table_[ 0 ].resize( 2, 0.0 );
170 table_[ 1 ].resize( 2, 0.0 );
174 unsigned int xdivs,
double xmin,
double xmax,
175 unsigned int ydivs,
double ymin,
double ymax )
176 : xmin_( xmin ), xmax_( xmax ),
177 ymin_( ymin ), ymax_( ymax ),
180 resize( xdivs+1, ydivs+1 );
202 unsigned int oldx =
table_.size();
203 unsigned int oldy = 0;
206 if ( xsize == 0 ) xsize = oldx;
207 if ( ysize == 0 ) ysize = oldy;
209 if ( xsize != oldx ) {
211 if ( xsize > oldx ) {
212 for (
unsigned int i = oldx; i < xsize; ++i )
217 if ( ysize != oldy ) {
218 for (
unsigned int i = 0; i < xsize; ++i )
234 cerr <<
"Error: Interpol2D::setXmin: Xmin ~= Xmax : Assignment failed\n";
248 cerr <<
"Error: Interpol2D::setXmax: Xmin ~= Xmax : Assignment failed\n";
270 unsigned int xdivs =
static_cast< unsigned int >(
272 if ( xdivs < 1 || xdivs >
MAX_DIVS ) {
274 "Error: Interpol2D::localSetDx Out of range:" <<
275 xdivs + 1 <<
" entries in table.\n";
298 cerr <<
"Error: Interpol2D::setYmin: Ymin ~= Ymax : Assignment failed\n";
312 cerr <<
"Error: Interpol2D::setYmax: Ymin ~= Ymax : Assignment failed\n";
327 if (
table_[0].size() > 0 )
328 return table_[0].size() - 1;
338 unsigned int ydivs =
static_cast< unsigned int >(
340 if ( ydivs < 1 || ydivs >
MAX_DIVS ) {
342 "Error: Interpol2D::localSetDy Out of range:" <<
343 ydivs + 1 <<
" entries in table.\n";
366 double ratio = value /
sy_;
367 vector< vector< double > >::iterator i;
368 vector< double >::iterator j;
370 for ( j = i->begin(); j != i->end(); j++ )
374 cerr <<
"Error: Interpol2D::localSetSy: sy too small:" <<
386 assert( index.size() == 2 );
387 unsigned int i0 = index[ 0 ];
388 unsigned int i1 = index[ 1 ];
391 table_[ i0 ][ i1 ] = value;
393 cerr <<
"Error: Interpol2D::setTableValue: Index out of bounds!\n";
404 assert( index.size() == 2 );
405 unsigned int i0 = index[ 0 ];
406 unsigned int i1 = index[ 1 ];
409 if ( i0 >=
table_.size() )
412 if ( i1 >=
table_[i0].size() )
413 i1 =
table_[i0].size() - 1;
415 return table_[ i0 ][ i1 ];
438 return table_[0].size() - 1;
452 }
else if (xy[0] >
xmax_){
459 }
else if (xy[1] >
ymax_){
491 assert(
table_.size() > 1 );
493 unsigned long xInteger =
static_cast< unsigned long >( ( x -
xmin_ ) *
invDx_ );
494 assert( xInteger <
table_.size() );
496 unsigned long yInteger =
static_cast< unsigned long >( ( y -
ymin_ ) *
invDy_ );
497 assert( yInteger <
table_[ 0 ].size() );
499 return table_[ xInteger ][ yInteger ];
510 bool isEndOfX =
false;
511 bool isEndOfY =
false;
512 double z00=0.0, z01=0.0, z10=0.0, z11=0.0;
513 assert(
table_.size() > 1 );
516 unsigned long xInteger =
static_cast< unsigned long >(xv);
517 if (xInteger >=
table_.size()){
518 xInteger =
table_.size() - 1;
520 if (xInteger ==
table_.size() - 1){
524 assert(xInteger >= 0);
525 double xFraction = xv - xInteger;
527 unsigned long yInteger =
static_cast< unsigned long >(yv);
528 if (yInteger >=
table_[xInteger].size()){
529 yInteger =
table_[xInteger].size() - 1;
531 assert(yInteger >= 0);
532 if (yInteger ==
table_[xInteger].size() - 1){
535 double yFraction = yv - yInteger;
536 double xFyF = xFraction * yFraction;
549 z00 =
table_[xInteger][yInteger];
551 z10 =
table_[xInteger+1][yInteger];
553 z11 =
table_[xInteger+1][yInteger+1];
554 z01 =
table_[xInteger][yInteger+1];
556 }
else if (!isEndOfY){
557 z01 =
table_[xInteger][yInteger+1];
568 z00 * ( 1 - xFraction - yFraction + xFyF ) +
569 z10 * ( xFraction - xFyF ) +
570 z01 * ( yFraction - xFyF ) +
612 for (
size_t i = 0; i <
table_.size(); i++ ) {
613 for (
size_t j = 0; j <
table_[ i ].size(); j++ ) {
630 in >> int2dTable.
xmin_;
631 in >> int2dTable.
xmax_;
633 in >> int2dTable.
ymin_;
634 in >> int2dTable.
ymax_;
637 for (
unsigned int i = 0; i < int2dTable.
table_.size(); ++i )
639 for (
unsigned int j = 0; j < int2dTable.
table_.size(); ++j )
640 in >> int2dTable.
table_[i][j];
649 const vector< vector< double > >&
value )
654 unsigned int ysize =
value[ 0 ].size();
655 vector< vector< double > >::const_iterator i;
656 for ( i =
value.begin() + 1; i !=
value.end(); i++ )
657 if ( i->size() != ysize ) {
662 if ( ysize == ~0u ) {
664 "Error: Interpol2D::localAppendTableVector: All rows should have a "
665 "uniform width. Not changing anything.\n";
669 if ( !
table_.empty() && ysize !=
table_[ 0 ].size() ) {
671 "Error: Interpol2D: localAppendTableVector: Table widths must match. "
672 "Not changing anything.\n";
684 fout.open( fname.c_str(), std::ios::app );
686 fout.open( fname.c_str(), std::ios::trunc );
688 vector< vector< double > >::const_iterator i;
689 vector< double >::const_iterator j;
691 for ( j = i->begin(); j != i->end(); j++ )
704 cerr <<
"Warning: Interpol2D::innerLoad: Loading 2-D table from '" <<
706 "'xdivs' and 'ydivs' need not be specified. If you have set these fields, "
707 "then they will be overridden while loading.\n";
709 vector< double >::iterator i;
710 std::ifstream fin( fname.c_str() );
714 for ( i = 0; i < skiplines; i++ ) {
716 getline( fin, line );
726 unsigned int lastWidth = ~0u;
728 while( fin.good() ) {
731 getline( fin, line );
733 istringstream sstream( line );
734 while( sstream >> y )
735 table_.back().push_back( y );
740 if (
table_.back().empty() ) {
745 if ( lastWidth != ~0u &&
746 table_.back().size() != lastWidth )
748 cerr <<
"Error: Interpol2D::innerLoad: " <<
749 "In file " << fname <<
750 ", line " <<
table_.size() <<
751 ", row widths are not uniform! Will stop loading now.\n";
756 lastWidth =
table_.back().size();
762 cerr <<
"Error: Interpol2D::innerLoad: Failed to open file " <<
768 void testInterpol2D()
846 #endif // DO_UNIT_TESTS
void lookupReturn(const Eref &e, double v1, double v2)
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
bool operator<(const Interpol2D &other) const
double getTableValue(vector< unsigned int > index) const
void lookup(double v1, double v2)
void load(const string &fname, unsigned int skiplines)
void setXmin(double value)
void setYdivs(unsigned int value)
vector< vector< double > > getTableVector() const
void setXdivs(unsigned int value)
unsigned int getXdivs() const
void resize(unsigned int xsize, unsigned int ysize, double init=0.0)
static const Cinfo * interpol2DCinfo
double indexWithoutCheck(double x, double y) const
bool doubleApprox(double x, double y)
bool doubleEq(double x, double y)
double getInterpolatedValue(vector< double > xy) const
istream & operator>>(istream &in, Interpol2D &int2dTable)
unsigned int xdivs() const
unsigned int ydivs() const
void setTableVector(vector< vector< double > > value)
unsigned int getYdivs() const
void setYmax(double value)
void setTableValue(vector< unsigned int > index, double value)
double innerLookup(double x, double y) const
void appendTableVector(vector< vector< double > > value)
vector< vector< double > > table_
void print(const string &fname, bool doAppend) const
static const Cinfo * initCinfo()
bool operator==(const Interpol2D &other) const
static SrcFinfo1< double > * lookupOut()
double interpolate(double x, double y) const
static const unsigned int MAX_DIVS
static const Cinfo * initCinfo()
void setYmin(double value)
std::string trim(const std::string myString, const string &delimiters)
void setXmax(double value)