#ifndef GRID_MULTILIN_INTERPOLATOR_DEF #define GRID_MULTILIN_INTERPOLATOR_DEF #include "GridMultilinearInterpolator.h" double GridMultilinearInterpolator::get_grid_z_value(const vector &point) const{ long index = 0, indexFactor = 1; for(long d=grid_points.size()-1; d>=0; --d){ index += indexFactor * point[d]; indexFactor *= grid_points[d].size(); } return z_values[index]; } void GridMultilinearInterpolator::string2numvector(const string &s, vector &v){ istringstream ss(s); v.clear(); double d; do{ ss >> d; if(ss.fail()) break; v.push_back(d); }while(true); } string GridMultilinearInterpolator::vector2string(const vector &v, string separator){ ostringstream ss; for(long n=0; n &parts, const string &haystack, const string &separator, int maxPartsCount){ parts.clear(); int previousPos = 0, nextPos, separatorLen = separator.length(); while(((nextPos = haystack.find(separator, previousPos)) != string::npos) && ((maxPartsCount>1) || (maxPartsCount<0))){ parts.push_back(haystack.substr(previousPos, nextPos - previousPos)); previousPos = nextPos + separatorLen; -- maxPartsCount; } parts.push_back(haystack.substr(previousPos)); } bool GridMultilinearInterpolator::load(long D, const string &s){ vector parts; explodeString(parts, s, ",", D+1); if(parts.size() &location) const{ const long D = grid_points.size(); for(long d=0; dgrid_points[d].back()) return false; } return true; } long GridMultilinearInterpolator::findOn1DGrid(const vector &gridValues, double value){ if(gridValues.empty()) return -1; if(valuegridValues.back()) return gridValues.size(); const double value_du = value + abs(value)*EPSILON; const double value_dd = value - abs(value)*EPSILON; for(long i=1; i=value_dd){ return i-1; } } return 0; // this should not happen } long GridMultilinearInterpolator::numberOfVertices(long D){ long V = 1; for(long d=0; d &location, double default_z_value, bool flatExtrapolate) const{ //find grid box const long D = grid_points.size(); vector box(D); vector boxVolumeFraction(D); vector N(D); //find and evaluate appropriate grid box (linear search) for(long d=0; d::quiet_NaN() : default_z_value); box[d] = findOn1DGrid(grid_points[d], location[d]); if(box[d]<0 || box[d]>=N[d]){ // not within s-grid if(!flatExtrapolate) return default_z_value; boxVolumeFraction[d] = 0; }else{ // within s-grid boxVolumeFraction[d] = (location[d]-grid_points[d][box[d]])/(grid_points[d][box[d]+1] - grid_points[d][box[d]]); } } double z=0; long d; int s; const long Nvertices = numberOfVertices(D); long vertex_index, vertex_index_factor, remainder; double vertex_weight; for(long v=0; v=0; --d){ // d enumerates the D grid dimensions s = remainder % 2; // s identifies the vertex side (left or right) along the d-th dimension remainder = (remainder-s)/2; vertex_index += (box[d]<0 ? 0 : (box[d]>=N[d] ? N[d]-1 : (s==0 ? box[d] : box[d]+1))) * vertex_index_factor; vertex_index_factor *= N[d]; vertex_weight *= (s==0 ? 1-boxVolumeFraction[d] : boxVolumeFraction[d]); } z += z_values[vertex_index] * vertex_weight; } return z; } double GridMultilinearInterpolator::interpolateWithDefault(const vector &location, double default_z_value) const{ return interpolate( location, default_z_value, false); } double GridMultilinearInterpolator::interpolate(const vector &location) const{ return interpolate( location, 0, true); } double GridMultilinearInterpolator::interpolate(int dummy, ...) const{ vector location(grid_points.size()); va_list args; va_start(args, dummy); for(long d=0; d location(grid_points.size()); va_list args; va_start(args, default_z_value); for(long d=0; d > &_layer_points){ grid_points.resize(_layer_points.size()+1); grid_points[0].clear(); for(long d=1; d &new_z_values){ grid_points[0].push_back(location); z_values.insert(z_values.end(), new_z_values.begin(), new_z_values.end()); return true; } long GridMultilinearInterpolator::getGridSize() const{ if(grid_points.empty()) return 0; long S=1; for(long d=0; d point(D); if(gridSize==0) return; long remainder, index1D, index, indexFactor, d; for(long p=0; p=0; --d){ index1D = remainder % grid_points[d].size(); remainder = (remainder - index1D)/grid_points[d].size(); index += indexFactor * index1D; indexFactor *= grid_points[d].size(); point[d] = grid_points[d][index1D]; } for(d=0; d