Ejemplo n.º 1
0
 /**
  * Get the value of the function at x, return a quiet NAN if x is not in the definiton domain.
  **/
 virtual double _function(double x) const override
     {
     if ((_tab == nullptr) || (_len == 0)) return std::numeric_limits<double>::quiet_NaN();
     if (!((x >= _minDomain) && (x<=_maxDomain))) return std::numeric_limits<double>::quiet_NaN();
     double _e = (_maxDomain - _minDomain) / _len;
     if (!((_e >= DBL_MIN * 2) && (_e <= DBL_MAX / 2.0))) return std::numeric_limits<double>::quiet_NaN();
     int t = interpolationMethod();
     if (t == INTERPOLATION_NONE)
         {
         size_t n = (size_t)((x - _minDomain) / _e);
         if (n >= _len) return std::numeric_limits<double>::quiet_NaN();
         double y;
         try { y = (double)_tab[n]; } catch (...) { y = std::numeric_limits<double>::quiet_NaN(); }
         return y;
         }
     if (t == INTERPOLATION_LINEAR)
         {
         size_t n = (size_t)((x - _minDomain) / _e);
         if (n >= _len) std::numeric_limits<double>::quiet_NaN();
         double x1 = _minDomain + n*_e;
         double x2 = x1 + _e;
         double y1 = std::numeric_limits<double>::quiet_NaN();
         double y2 = std::numeric_limits<double>::quiet_NaN();
         try { y1 = (double)_tab[n]; } catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
         try { y2 = (n+1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); } catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
         return linearInterpolation(x, fVec2(x1, y1), fVec2(x2, y2));
         }
     size_t n = (size_t)((x - _minDomain) / _e);
     if (n >= _len) std::numeric_limits<double>::quiet_NaN();
     double x1 = _minDomain + n*_e;
     double x0 = x1 - _e;
     double x2 = x1 + _e;
     double x3 = x2 + _e;
     double y0 = std::numeric_limits<double>::quiet_NaN();
     double y1 = std::numeric_limits<double>::quiet_NaN();
     double y2 = std::numeric_limits<double>::quiet_NaN();
     double y3 = std::numeric_limits<double>::quiet_NaN();
     try { y0 = (n == 0) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n - 1]); } catch (...) { y0 = std::numeric_limits<double>::quiet_NaN(); }
     try { y1 = (double)_tab[n]; } catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
     try { y2 = (n + 1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); } catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
     try { y3 = (n + 2 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 2]); } catch (...) { y3 = std::numeric_limits<double>::quiet_NaN(); }
     if (t == INTERPOLATION_CUBIC) return cubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
     return monotoneCubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
     }
Ejemplo n.º 2
0
			/**
			* Get the value of the function at x, return a quiet NAN if x is not in the definiton domain.
			**/
			virtual double _function(double x) const override
				{
				if (_pmap->size() == 0)	{ return  std::numeric_limits<double>::quiet_NaN(); }
				_minDomain = (_pmap->begin())->first;
				_maxDomain = (_pmap->rbegin())->first;
				if ((x < _minDomain)||(x > _maxDomain)) { return  std::numeric_limits<double>::quiet_NaN(); }
				
				auto it2 = _pmap->lower_bound(x);
				if (it2 == _pmap->end()) { return  std::numeric_limits<double>::quiet_NaN(); }
				if (it2 == _pmap->begin()) { if (x < (double)(it2->first)) { return  std::numeric_limits<double>::quiet_NaN(); } else { return it2->second; } }
				
				double x2 = (double)it2->first;
				double y2 = (double)it2->second;
				auto it1 = it2; it1--;
				double x1 = (double)it1->first;
				double y1 = (double)it1->second;

				int t = interpolationMethod();
				if (t == INTERPOLATION_NONE) { return y1; }
				if (t == INTERPOLATION_LINEAR) { return linearInterpolation(x, fVec2(x1, y1), fVec2(x2, y2)); }

				double x0 = x1 - 1.0;
				double x3 = x2 + 1.0;
				double y0 = std::numeric_limits<double>::quiet_NaN();
				double y3 = std::numeric_limits<double>::quiet_NaN();
				if (it1 != _pmap->begin())
					{
					it1--;
				    x0 = (double)it1->first;
					y0 = (double)it1->second;
					}
				it2++;
				if (it2 != _pmap->end())
					{
					x3 = (double)it2->first;
					y3 = (double)it2->second;
					}
				if (t == INTERPOLATION_CUBIC) return cubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
				return monotoneCubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));

				/*
				if ((_tab == nullptr) || (_len == 0)) return std::numeric_limits<double>::quiet_NaN();
				if (!((x >= _minDomain) && (x <= _maxDomain))) return std::numeric_limits<double>::quiet_NaN();
				double _e = (_maxDomain - _minDomain) / _len;
				if (!((_e >= DBL_MIN * 2) && (_e <= DBL_MAX / 2.0))) return std::numeric_limits<double>::quiet_NaN();
				int t = interpolationMethod();
				if (t == INTERPOLATION_NONE)
					{
					size_t n = (size_t)((x - _minDomain) / _e);
					if (n >= _len) return std::numeric_limits<double>::quiet_NaN();
					double y;
					try { y = (double)_tab[n]; }
					catch (...) { y = std::numeric_limits<double>::quiet_NaN(); }
					return y;
					}
				if (t == INTERPOLATION_LINEAR)
					{
					size_t n = (size_t)((x - _minDomain) / _e);
					if (n >= _len) std::numeric_limits<double>::quiet_NaN();
					double x1 = _minDomain + n*_e;
					double x2 = x1 + _e;
					double y1 = std::numeric_limits<double>::quiet_NaN();
					double y2 = std::numeric_limits<double>::quiet_NaN();
					try { y1 = (double)_tab[n]; }
					catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
					try { y2 = (n + 1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); }
					catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
					return linearInterpolation(x, fVec2(x1, y1), fVec2(x2, y2));
					}
				size_t n = (size_t)((x - _minDomain) / _e);
				if (n >= _len) std::numeric_limits<double>::quiet_NaN();
				double x1 = _minDomain + n*_e;
				double x0 = x1 - _e;
				double x2 = x1 + _e;
				double x3 = x2 + _e;
				double y0 = std::numeric_limits<double>::quiet_NaN();
				double y1 = std::numeric_limits<double>::quiet_NaN();
				double y2 = std::numeric_limits<double>::quiet_NaN();
				double y3 = std::numeric_limits<double>::quiet_NaN();
				try { y0 = (n == 0) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n - 1]); }
				catch (...) { y0 = std::numeric_limits<double>::quiet_NaN(); }
				try { y1 = (double)_tab[n]; }
				catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
				try { y2 = (n + 1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); }
				catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
				try { y3 = (n + 2 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 2]); }
				catch (...) { y3 = std::numeric_limits<double>::quiet_NaN(); }
				if (t == INTERPOLATION_CUBIC) return cubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
				return monotoneCubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
				*/
				}