INET Framework for OMNeT++/OMNEST
inet::math::ApproximatedFunction< R, D, DIMENSION, X > Class Template Reference

Approximates the values and partitioning of a multidimensional function along one of the dimensions. More...

#include <CompoundFunctions.h>

Inheritance diagram for inet::math::ApproximatedFunction< R, D, DIMENSION, X >:
inet::math::FunctionBase< R, D > inet::math::IFunction< R, D >

Public Member Functions

 ApproximatedFunction (X lower, X upper, X step, const IInterpolator< X, R > *interpolator, const Ptr< const IFunction< R, D >> &function)
 
virtual R getValue (const typename D::P &p) const override
 Returns the value of the function at the given point. More...
 
virtual void partition (const typename D::I &i, std::function< void(const typename D::I &, const IFunction< R, D > *)> callback) const override
 
virtual bool isFinite (const typename D::I &i) const override
 Returns true if the function value is finite in the given domain. More...
 
virtual void printStructure (std::ostream &os, int level=0) const override
 Prints the internal data structure of this function in a human readable form to the provided stream. More...
 
- Public Member Functions inherited from inet::math::FunctionBase< R, D >
virtual void partition (const typename D::I &i, const std::function< void(const typename D::I &, const IFunction< R, D > *)> callback) const override
 Subdivides the provided domain and calls back f with the subdomains and the corresponding potentially simpler domain limited functions. More...
 
virtual Interval< R > getRange () const override
 Returns the valid range of the function as an interval. More...
 
virtual Interval< R > getRange (const typename D::I &i) const override
 Returns the valid range of the function as an interval for the given domain. More...
 
virtual D::I getDomain () const override
 Returns the valid domain of the function as an interval. More...
 
virtual bool isFinite () const override
 Returns true if the function value is finite in the whole domain. More...
 
virtual bool isNonZero () const override
 Returns true if the function value is non-zero in the whole domain. More...
 
virtual bool isNonZero (const typename D::I &i) const override
 Returns true if the function value is non-zero in the given domain. More...
 
virtual R getMin () const override
 Returns the minimum value for the whole domain. More...
 
virtual R getMin (const typename D::I &i) const override
 Returns the minimum value for the given domain. More...
 
virtual R getMax () const override
 Returns the maximum value for the whole domain. More...
 
virtual R getMax (const typename D::I &i) const override
 Returns the maximum value for the given domain. More...
 
virtual R getMean () const override
 Returns the mean value for the whole domain. More...
 
virtual R getMean (const typename D::I &i) const override
 Returns the mean value for the given domain. More...
 
virtual R getIntegral () const override
 Returns the integral value for the whole domain. More...
 
virtual R getIntegral (const typename D::I &i) const override
 Returns the integral value for the given domain. More...
 
virtual const Ptr< const IFunction< R, D > > add (const Ptr< const IFunction< R, D >> &o) const override
 Adds the provided function to this function. More...
 
virtual const Ptr< const IFunction< R, D > > subtract (const Ptr< const IFunction< R, D >> &o) const override
 Substracts the provided function from this function. More...
 
virtual const Ptr< const IFunction< R, D > > multiply (const Ptr< const IFunction< double, D >> &o) const override
 Multiplies the provided function with this function. More...
 
virtual const Ptr< const IFunction< double, D > > divide (const Ptr< const IFunction< R, D >> &o) const override
 Divides this function with the provided function. More...
 
virtual std::ostream & printOn (std::ostream &os) const override
 
virtual void print (std::ostream &os, int level=0) const override
 Prints this function in human readable form to the provided stream for the whole domain. More...
 
virtual void print (std::ostream &os, const typename D::I &i, int level=0) const override
 Prints this function in a human readable form to the provided stream for the given domain. More...
 
virtual void printPartitioning (std::ostream &os, const typename D::I &i, int level) const override
 Prints the partitioning of this function in a human readable form to the provided stream for the given domain. More...
 
virtual void printPartition (std::ostream &os, const typename D::I &i, int level=0) const override
 Prints a single partition of this function in a human readable form to the provided stream for the given domain. More...
 
- Public Member Functions inherited from inet::math::IFunction< R, D >
virtual ~IFunction ()
 

Protected Attributes

const X lower
 
const X upper
 
const X step
 
const IInterpolator< X, R > * interpolator
 
const Ptr< const IFunction< R, D > > function
 

Detailed Description

template<typename R, typename D, int DIMENSION, typename X>
class inet::math::ApproximatedFunction< R, D, DIMENSION, X >

Approximates the values and partitioning of a multidimensional function along one of the dimensions.

Constructor & Destructor Documentation

◆ ApproximatedFunction()

template<typename R , typename D , int DIMENSION, typename X >
inet::math::ApproximatedFunction< R, D, DIMENSION, X >::ApproximatedFunction ( lower,
upper,
step,
const IInterpolator< X, R > *  interpolator,
const Ptr< const IFunction< R, D >> &  function 
)
inline
321  :
322  lower(lower), upper(upper), step(step), interpolator(interpolator), function(function)
323  {}

Member Function Documentation

◆ getValue()

template<typename R , typename D , int DIMENSION, typename X >
virtual R inet::math::ApproximatedFunction< R, D, DIMENSION, X >::getValue ( const typename D::P &  p) const
inlineoverridevirtual

Returns the value of the function at the given point.

The returned value falls into the range of the function. The provided point must fall into the domain of the function.

Implements inet::math::IFunction< R, D >.

325  {
326  X x = std::get<DIMENSION>(p);
327  if (x < lower)
328  return function->getValue(p.template getReplaced<X, DIMENSION>(lower));
329  else if (x > upper)
330  return function->getValue(p.template getReplaced<X, DIMENSION>(upper));
331  else {
332  X x1 = lower + step * floor(toDouble(x - lower) / toDouble(step));
333  X x2 = math::minnan(upper, x1 + step);
334  R r1 = function->getValue(p.template getReplaced<X, DIMENSION>(x1));
335  R r2 = function->getValue(p.template getReplaced<X, DIMENSION>(x2));
336  return interpolator->getValue(x1, r1, x2, r2, x);
337  }
338  }

◆ isFinite()

template<typename R , typename D , int DIMENSION, typename X >
virtual bool inet::math::ApproximatedFunction< R, D, DIMENSION, X >::isFinite ( const typename D::I &  i) const
inlineoverridevirtual

Returns true if the function value is finite in the given domain.

Reimplemented from inet::math::FunctionBase< R, D >.

466  {
467  return function->isFinite(i);
468  }

◆ partition()

template<typename R , typename D , int DIMENSION, typename X >
virtual void inet::math::ApproximatedFunction< R, D, DIMENSION, X >::partition ( const typename D::I &  i,
std::function< void(const typename D::I &, const IFunction< R, D > *)>  callback 
) const
inlineoverridevirtual
340  {
341  unsigned char b = 1 << std::tuple_size<typename D::P::type>::value >> 1;
342  auto m = (b >> DIMENSION);
343  auto fixed = i.getFixed() & m;
344  const auto& pl = i.getLower();
345  const auto& pu = i.getUpper();
346  X xl = std::get<DIMENSION>(pl);
347  X xu = std::get<DIMENSION>(pu);
348  if (xl < lower) {
349  function->partition(i.template getFixed<X, DIMENSION>(lower), [&] (const typename D::I& i1, const IFunction<R, D> *f1) {
350  if (auto f1c = dynamic_cast<const ConstantFunction<R, D> *>(f1)) {
351  auto p1 = i1.getLower().template getReplaced<X, DIMENSION>(xl);
352  auto p2 = i1.getUpper().template getReplaced<X, DIMENSION>(math::minnan(lower, xu));
353  ConstantFunction<R, D> g(f1c->getConstantValue());
354  typename D::I i2(p1, p2, i.getLowerClosed() | fixed, (i.getUpperClosed() & ~m) | fixed, i.getFixed());
355  callback(i2, &g);
356  }
357  else
358  throw cRuntimeError("TODO");
359  });
360  }
361  if (xu >= lower && upper >= xl) {
362  X min = lower + step * floor(toDouble(math::maxnan(lower, xl) - lower) / toDouble(step));
363  X max = (i.getFixed() & m) ? min + step : lower + step * ceil(toDouble(math::minnan(upper, xu) - lower) / toDouble(step));
364  for (X x = min; x < max; x += step) {
365  X x1 = x;
366  X x2 = x + step;
367  Interval<X> j(math::maxnan(x1, xl), math::minnan(x2, xu), true, fixed, fixed);
368  // determine the smallest intervals along the other dimensions for which the primitive functions are calculated
369  function->partition(i.template getFixed<X, DIMENSION>(x1), [&] (const typename D::I& i2, const IFunction<R, D> *f2) {
370  function->partition(i2.template getFixed<X, DIMENSION>(x2), [&] (const typename D::I& i3, const IFunction<R, D> *f3) {
371  auto i4 = i3.template getReplaced<X, DIMENSION>(j);
372  if (auto f2c = dynamic_cast<const ConstantFunction<R, D> *>(f2)) {
373  auto r1 = f2c->getConstantValue();
374  if (auto f3c = dynamic_cast<const ConstantFunction<R, D> *>(f3)) {
375  auto r2 = f3c->getConstantValue();
376  if (dynamic_cast<const ConstantInterpolatorBase<X, R> *>(interpolator)) {
377  ConstantFunction<R, D> g(interpolator->getValue(x1, r1, x2, r2, (x1 + x2) / 2));
378  callback(i4, &g);
379  }
380  else if (dynamic_cast<const LinearInterpolator<X, R> *>(interpolator)) {
381  auto p3 = i3.getLower().template getReplaced<X, DIMENSION>(x1);
382  auto p4 = i3.getUpper().template getReplaced<X, DIMENSION>(x2);
383  UnilinearFunction<R, D> g(p3, p4, r1, r2, DIMENSION);
384  simplifyAndCall(i4, &g, callback);
385  }
386  else
387  throw cRuntimeError("TODO");
388  }
389  else if (auto f3l = dynamic_cast<const UnilinearFunction<R, D> *>(f3)) {
390  if (dynamic_cast<const ConstantInterpolatorBase<X, R> *>(interpolator))
391  throw cRuntimeError("TODO");
392  else if (dynamic_cast<const LinearInterpolator<X, R> *>(interpolator)) {
393  typename D::P lowerLower = i4.getLower();
394  typename D::P lowerUpper = i4.getUpper();
395  typename D::P upperLower = i3.getLower().template getReplaced<X, DIMENSION>(x1);
396  typename D::P upperUpper = i3.getUpper().template getReplaced<X, DIMENSION>(x2);
397  R rLowerLower = f2c->getConstantValue();
398  R rLowerUpper = f2c->getConstantValue();
399  R rUpperLower = f3l->getRLower();
400  R rUpperUpper = f3l->getRUpper();
401  BilinearFunction<R, D> g(lowerLower, lowerUpper, upperLower, upperUpper, rLowerLower, rLowerUpper, rUpperLower, rUpperUpper, f3l->getDimension(), DIMENSION);
402  simplifyAndCall(i4, &g, callback);
403  }
404  else
405  throw cRuntimeError("TODO");
406  }
407  else
408  throw cRuntimeError("TODO");
409  }
410  else if (auto f2l = dynamic_cast<const UnilinearFunction<R, D> *>(f2)) {
411  if (auto f3c = dynamic_cast<const ConstantFunction<R, D> *>(f3)) {
412  if (dynamic_cast<const ConstantInterpolatorBase<X, R> *>(interpolator))
413  throw cRuntimeError("TODO");
414  else if (dynamic_cast<const LinearInterpolator<X, R> *>(interpolator)) {
415  typename D::P lowerLower = i2.getLower().template getReplaced<X, DIMENSION>(x1);
416  typename D::P lowerUpper = i2.getUpper().template getReplaced<X, DIMENSION>(x2);
417  typename D::P upperLower = i4.getLower();
418  typename D::P upperUpper = i4.getUpper();
419  R rLowerLower = f2l->getRLower();
420  R rLowerUpper = f2l->getRUpper();
421  R rUpperLower = f3c->getConstantValue();
422  R rUpperUpper = f3c->getConstantValue();
423  BilinearFunction<R, D> g(lowerLower, lowerUpper, upperLower, upperUpper, rLowerLower, rLowerUpper, rUpperLower, rUpperUpper, f2l->getDimension(), DIMENSION);
424  simplifyAndCall(i4, &g, callback);
425  }
426  else
427  throw cRuntimeError("TODO");
428  }
429  else if (auto f3l = dynamic_cast<const UnilinearFunction<R, D> *>(f3)) {
430  ASSERT(f2l->getDimension() == f3l->getDimension());
431  typename D::P lowerLower = i2.getLower().template getReplaced<X, DIMENSION>(x1);
432  typename D::P lowerUpper = i2.getUpper().template getReplaced<X, DIMENSION>(x2);
433  typename D::P upperLower = i3.getLower().template getReplaced<X, DIMENSION>(x1);
434  typename D::P upperUpper = i3.getUpper().template getReplaced<X, DIMENSION>(x2);
435  R rLowerLower = f2l->getRLower();
436  R rLowerUpper = f2l->getRUpper();
437  R rUpperLower = f3l->getRLower();
438  R rUpperUpper = f3l->getRUpper();
439  BilinearFunction<R, D> g(lowerLower, lowerUpper, upperLower, upperUpper, rLowerLower, rLowerUpper, rUpperLower, rUpperUpper, f2l->getDimension(), DIMENSION);
440  simplifyAndCall(i4, &g, callback);
441  }
442  else
443  throw cRuntimeError("TODO");
444  }
445  else
446  throw cRuntimeError("TODO");
447  });
448  });
449  }
450  }
451  if (xu > upper) {
452  function->partition(i.template getFixed<X, DIMENSION>(upper), [&] (const typename D::I& i1, const IFunction<R, D> *f1) {
453  if (auto f1c = dynamic_cast<const ConstantFunction<R, D> *>(f1)) {
454  auto p1 = i1.getLower().template getReplaced<X, DIMENSION>(math::maxnan(upper, xl));
455  auto p2 = i1.getUpper().template getReplaced<X, DIMENSION>(xu);
456  ConstantFunction<R, D> g(f1c->getConstantValue());
457  typename D::I i2(p1, p2, i.getLowerClosed() | m, (i.getUpperClosed() & ~m) | fixed, i.getFixed());
458  callback(i2, &g);
459  }
460  else
461  throw cRuntimeError("TODO");
462  });
463  }
464  }

◆ printStructure()

template<typename R , typename D , int DIMENSION, typename X >
virtual void inet::math::ApproximatedFunction< R, D, DIMENSION, X >::printStructure ( std::ostream &  os,
int  level = 0 
) const
inlineoverridevirtual

Prints the internal data structure of this function in a human readable form to the provided stream.

Reimplemented from inet::math::FunctionBase< R, D >.

470  {
471  os << "(Approximated\n" << std::string(level + 2, ' ');
472  function->printStructure(os, level + 2);
473  os << ")";
474  }

Member Data Documentation

◆ function

template<typename R , typename D , int DIMENSION, typename X >
const Ptr<const IFunction<R, D> > inet::math::ApproximatedFunction< R, D, DIMENSION, X >::function
protected

◆ interpolator

template<typename R , typename D , int DIMENSION, typename X >
const IInterpolator<X, R>* inet::math::ApproximatedFunction< R, D, DIMENSION, X >::interpolator
protected

◆ lower

template<typename R , typename D , int DIMENSION, typename X >
const X inet::math::ApproximatedFunction< R, D, DIMENSION, X >::lower
protected

◆ step

template<typename R , typename D , int DIMENSION, typename X >
const X inet::math::ApproximatedFunction< R, D, DIMENSION, X >::step
protected

◆ upper

template<typename R , typename D , int DIMENSION, typename X >
const X inet::math::ApproximatedFunction< R, D, DIMENSION, X >::upper
protected

The documentation for this class was generated from the following file:
inet::sctp::min
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SctpAssociation.h:261
inet::math::ApproximatedFunction::step
const X step
Definition: CompoundFunctions.h:316
inet::math::toDouble
double toDouble(const T v)
Definition: Point.h:28
inet::units::units::g
milli< kg >::type g
Definition: Units.h:1071
inet::math::maxnan
const T maxnan(const T &a, const T &b)
This function properly and symmetrically handles NaNs in contrast with std::max and std::fmax.
Definition: INETMath.h:234
inet::math::ApproximatedFunction::lower
const X lower
Definition: CompoundFunctions.h:314
inet::math::ApproximatedFunction::interpolator
const IInterpolator< X, R > * interpolator
Definition: CompoundFunctions.h:317
inet::units::constants::R
const value< double, compose< units::J, compose< pow< units::mol, -1 >, pow< units::kg, -1 > > > > R(8.314472)
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::sctp::max
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SctpAssociation.h:266
inet::math::IInterpolator::getValue
virtual Y getValue(const X x1, const Y y1, const X x2, const Y y2, const X x) const =0
Returns the interpolated value for the given x.
inet::math::minnan
const T minnan(const T &a, const T &b)
This function properly and symmetrically handles NaNs in contrast with std::min and std::fmin.
Definition: INETMath.h:216
inet::units::values::m
value< double, units::m > m
Definition: Units.h:1233
inet::math::ApproximatedFunction::upper
const X upper
Definition: CompoundFunctions.h:315