/// linear interpolation of the function y = f(x) at point xi /// assumes that x is strictly increasing double interp(const Vector& x, const Vector& y, double xi, InterpMethod interpMethod, ExtrapMethod extrapMethod){ unsigned N = x.size(); double result = 0.0; if (y.size() != N){ return result; } InterpInfo info = interpInfo(x, xi); if (info.extrapolated){ switch(extrapMethod){ case NoneExtrap: // set to zero result = 0.0; break; case NearestExtrap: // pick closest point result = (info.wa > info.wb ? y(info.ia) : y(info.ib)); break; } }else{ switch(interpMethod){ case LinearInterp: // linear interpolation result = info.wa*y(info.ia) + info.wb*y(info.ib); break; case NearestInterp: // pick closest point result = (info.wa > info.wb ? y(info.ia) : y(info.ib)); break; case HoldLastInterp: // set to previous value result = y(info.ia); break; case HoldNextInterp: // set to next value result = y(info.ib); break; } } return result; }
/// linear interpolation of the function v = f(x, y) at point xi, yi /// assumes that x and y are strictly increasing double interp(const Vector& x, const Vector& y, const Matrix& v, double xi, double yi, InterpMethod interpMethod, ExtrapMethod extrapMethod) { double result = 0.0; unsigned M = x.size(); unsigned N = y.size(); if ((M != v.size1()) || (N != v.size2())) { return result; } InterpInfo xInfo = interpInfo(x, xi); if (xInfo.extrapolated) { switch(extrapMethod) { case NoneExtrap: // set all weights to zero xInfo.wa = 0.0; xInfo.wb = 0.0; break; case NearestExtrap: // pick closest point // no-op break; } } else { switch(interpMethod) { case LinearInterp: // linear interpolation // no-op break; case NearestInterp: // pick closest point if(xInfo.wa > xInfo.wb) { xInfo.wa = 1.0; xInfo.wb = 0.0; } else { xInfo.wa = 0.0; xInfo.wb = 1.0; } break; case HoldLastInterp: // set to previous value xInfo.wa = 1.0; xInfo.wb = 0.0; break; case HoldNextInterp: // set to next value xInfo.wa = 0.0; xInfo.wb = 1.0; break; } } InterpInfo yInfo = interpInfo(y, yi); if (yInfo.extrapolated) { switch(extrapMethod) { case NoneExtrap: // set all weights to zero yInfo.wa = 0.0; yInfo.wb = 0.0; break; case NearestExtrap: // pick closest point // no-op break; } } else { switch(interpMethod) { case LinearInterp: // linear interpolation // no-op break; case NearestInterp: // pick closest point if(yInfo.wa > yInfo.wb) { yInfo.wa = 1.0; yInfo.wb = 0.0; } else { yInfo.wa = 0.0; yInfo.wb = 1.0; } break; case HoldLastInterp: // set to previous value yInfo.wa = 1.0; yInfo.wb = 0.0; break; case HoldNextInterp: // set to next value yInfo.wa = 0.0; yInfo.wb = 1.0; break; } } // we have set weights appropriately so that here we can compute in the same way all the time result = xInfo.wa*yInfo.wa*v(xInfo.ia, yInfo.ia) + xInfo.wa*yInfo.wb*v(xInfo.ia, yInfo.ib) + xInfo.wb*yInfo.wa*v(xInfo.ib, yInfo.ia) + xInfo.wb*yInfo.wb*v(xInfo.ib, yInfo.ib); return result; }