Flow123d  jenkins-Flow123d-windows-release-multijob-285
interpolant_impl.hh
Go to the documentation of this file.
1 #ifndef INTERPOLANT_IMPL_H
2 #define INTERPOLANT_IMPL_H
3 
4 #include <cmath>
5 
6 #include "interpolant.hh"
7 #include "system/xio.h"
8 
9 /********************************** InterpolantBase ********************************/
10 
11 inline double InterpolantBase::error()
12 {
13  return error_;
14 }
15 
17 {
18  return stats;
19 }
20 
21 inline double InterpolantBase::bound_a() const
22 {
23  return bound_a_;
24 }
25 
26 inline double InterpolantBase::bound_b() const
27 {
28  return bound_b_;
29 }
30 
31 inline unsigned int InterpolantBase::size() const
32 {
33  return size_;
34 }
35 
36 
37 /********************************** Interpolant ********************************/
38 
39 template<template<class> class Func, class Type >
40 Interpolant::Interpolant(Func<Type>* func, bool interpolate_derivative)
41  : func(func),
42  interpolate_derivative(interpolate_derivative)
43 {
44  func_diff = new Func<B<Type> >();
45  func_diffn = new Func<T<Type> >();
46 
48  func_diffn->set_param_from_func(func);
49 
50  checks[Check::functor] = true;
51 }
52 
53 
54 template<template<class> class Func, class Type >
55 void Interpolant::set_functor(Func<Type>* func, bool interpolate_derivative)
56 {
57  this->interpolate_derivative = interpolate_derivative;
58  this->func = func;
59  func_diff = new Func<B<Type> >();
60  func_diffn = new Func<T<Type> >();
62  func_diffn->set_param_from_func(func);
63 
64  checks[Check::functor] = true;
65 }
66 
67 
68 inline double Interpolant::val(double x)
69 {
70  //increase calls
72 
73  //uncomment if we want to do the check automatically
74  //every STATISTIC_CHECK calls check the statistics
75  //if((stats.total_calls % STATISTIC_CHECK == 0) && use_statistics)
76  // this->check_and_reinterpolate();
77 
78  //return value
79  if(x < bound_a_) //left miss
80  {
81  //DBGMSG("test\n");
82  //std::cout << "test a" << std::endl;
84  stats.min = std::min(stats.min, x);
85 
86  switch(extrapolation)
87  {
89  return f_vec[0];
91  return (f_vec[1] - f_vec[0])*(x/step-a_div_step) + f_vec[0]; //f_vec[0] + p1_vec[0]*(x-x_vec[0]);
93  default:
94  return f_val(x); //otherwise compute original functor
95  }
96  }
97  else if(x > bound_b_) //right miss
98  {
99  //DBGMSG("test\n");
100  //std::cout << "test b" << std::endl;
102  stats.max = std::max(stats.max, x);
103 
104  switch(extrapolation)
105  {
107  return f_vec[size_];
109  return (f_vec[size_] - f_vec[size_-1])*(x-bound_b_+step)/step + f_vec[size_-1];//f_vec[size_-1] + p1_vec[size_-1]*(x-x_vec[size_-1]);
111  default:
112  return f_val(x); //otherwise compute original functor
113  }
114  }
115  else //hit the interval
116  {
117  return val_p1(x);
118  }
119 }
120 
121 inline double Interpolant::val_test(double x)
122 {
123  /*
124  //increase calls
125  stats.total_calls++;
126 
127  if(x < bound_a_)
128  {
129  //std::cout << "test a" << std::endl;
130  return 0;
131  }
132  else if(x > bound_b_) //right miss
133  {
134  //std::cout << "test b" << std::endl;
135  return 0;
136  }
137  else //*/
138  return val_p1(x);
139 }
140 
141 inline DiffValue Interpolant::diff(double x)
142 {
143  ASSERT(interpolate_derivative, "Derivative is not interpolated. Flag must be switched true in constructor (or set_functor).");
144  //increase calls
145  stats.total_calls++;
146 
147  //uncomment if we want to do the check automatically
148  //every STATISTIC_CHECK calls check the statistics
149  //if((stats.total_calls % STATISTIC_CHECK == 0) && use_statistics)
150  // this->check_and_reinterpolate();
151 
152  if(x < bound_a_) //left miss
153  {
155  stats.min = std::min(stats.min, x);
156  switch(extrapolation)
157  {
159  return DiffValue(f_vec[0],
160  df_vec[0]);
162  return DiffValue((f_vec[1] - f_vec[0])*(x/step-a_div_step) + f_vec[0], //f_vec[0] + p1_vec[0]*(x-x_vec[0]),
163  (df_vec[1] - df_vec[0])*(x/step-a_div_step) + df_vec[0]);//df_vec[0] + p1d_vec[0]*(x-x_vec[0]));
165  default:
166  return f_diff(x); //otherwise compute original functor
167  }
168  }
169  else if(x > bound_b_) //right miss
170  {
172  stats.max = std::max(stats.max, x);
173  switch(extrapolation)
174  {
176  return DiffValue(f_vec[size_],
177  df_vec[size_]);
179  return DiffValue((f_vec[size_] - f_vec[size_-1])*(x-bound_b_+step)/step + f_vec[size_-1], //f_vec[size_-1] + p1_vec[size_-1]*(x-x_vec[size_-1]),
180  (df_vec[size_] - df_vec[size_-1])*(x-bound_b_+step)/step + df_vec[size_-1]);//df_vec[size_-1] + p1d_vec[size_-1]*(x-x_vec[size_-1]) );
182  default:
183  return f_diff(x); //otherwise compute original functor
184  }
185  }
186  else //hit the interval
187  {
188  return diff_p1(x);
189  }
190 }
191 
192 inline double Interpolant::f_val(double x)
193 {
194  return func->operator()(x);
195 }
196 
198 {
199  B<double> xx(x); // Initialize arguments
200  //Func func; // Instantiate functor
201  B<double> f(func_diff->operator()(xx)); // Evaluate function and record DAG
202  f.diff(0,1); // Differentiate
203 
204  DiffValue d;
205  d.first = f.x(); // Value of function
206  d.second = xx.d(0); // Value of df/dx
207  return d; // Return function value
208 }
209 
210 /*
211 inline unsigned int Interpolant::find_interval(double x)
212 {
213  //counts in which interval x is (the last node before x)
214  return floor((x - bound_a_) / step);
215 }
216 */
217 
218 /* //CONSTANT INTERPOLATION
219 inline double Interpolant::val_p0(double x)
220 {
221  return f_vec[find_interval(x)];
222 }
223 
224 inline DiffValue Interpolant::diff_p0(double x)
225 {
226  DiffValue result;
227  unsigned int i = find_interval(x);
228  result.f = f_vec[i];
229  result.dfdx = df_vec[i];
230  return result;
231 }
232 */
233 
234 inline double Interpolant::val_p1(double x)
235 {
236  /*
237 [ OK ] InterpolantTest.InterpolantEval_val (184 ms)
238 [ OK ] InterpolantTest.InterpolantEval_val_p1 (192 ms)
239 [ OK ] InterpolantTest.InterpolantEval_val_test (190 ms)
240 
241  When we used precomputed coeficients of P1 interpolation.
242  */
243  //unsigned int i = floor(x / step - a_div_step);
244  //return p1_vec[i]*(x-x_vec[i]) + f_vec[i];
245 
246  /*
247 [ OK ] InterpolantTest.InterpolantEval_val (162 ms)
248 [ OK ] InterpolantTest.InterpolantEval_val_p1 (163 ms)
249 [ OK ] InterpolantTest.InterpolantEval_val_test (162 ms)
250 
251 These results are satisfying:
252  + the function val_p1 itself is by 14% faster than before
253  + we use only one array to keep the function values
254  + all three functions take the same time which means
255  that the collecting statistics and going through several IF commands
256  does not affect the evaluation time
257  */
258  double x_step = x / step;
259  unsigned int i = floor(x_step - a_div_step);
260 
261  return (f_vec[i+1] - f_vec[i])*(x_step-i-a_div_step) + f_vec[i];
262 }
263 
264 
266 {
267  DiffValue result;
268  //unsigned int i = find_interval(x);
269  //result.first = p1_vec[i]*(x-x_vec[i]) + f_vec[i];
270  //result.second = p1d_vec[i]*(x-x_vec[i]) + df_vec[i];
271 
272  double x_step = x / step;
273  unsigned int i = floor(x_step - a_div_step);
274 
275  result.first = (f_vec[i+1] - f_vec[i])*(x_step-i-a_div_step) + f_vec[i];
276  result.second = (df_vec[i+1] - df_vec[i])*(x_step-i-a_div_step) + df_vec[i];
277 
278  return result;
279 }
280 
281 
282 /** Functor class that computes the argument of the integral \f$ (f(x)-i(x))^p + (f'(x)-i'(x))^p \f$ in the norm \f$ \|f-i\|_{W^1_p} \f$.
283  * It is used as input functor to integration.
284  */
286 {
287 public:
289  : interpolant(interpolant), p_(p), tol_(tol) {}
290 
291  inline double p() {return p_;}
292  inline double tol() {return tol_;}
293 
294  virtual double operator()(double x)
295  {
296  double f_val = interpolant->f_val(x);
297  double a = std::abs(f_val - interpolant->val(x)) / (std::abs(f_val) + tol_);
298 
299  return std::pow(a, p_);
300  }
301 
302 private:
304  double p_;
305  double tol_;
306 };
307 
308  /** Functor class that computes the argument of the integral \f$ (f(x)-i(x))^p + (f'(x)-i'(x))^p \f$ in the norm \f$ \|f-i\|_{W^1_p} \f$.
309  * It is used as input functor to integration.
310  */
312 {
313 public:
315  : interpolant(interpolant), p_(p), tol_(tol) {}
316 
317  inline double p() {return p_;}
318  inline double tol() {return tol_;}
319 
320  virtual double operator()(double x)
321  {
322  DiffValue f = interpolant->f_diff(x);
323  DiffValue g = interpolant->diff(x);
324  double a = std::abs(f.first - g.first) / (std::abs(f.first) + tol_)
325  + std::abs(f.second - g.second) / (std::abs(f.second) + tol_);
326 
327  return std::pow(a, p_);
328  }
329 
330 private:
332  double p_;
333  double tol_;
334 };
335 
336 
337 
338 /********************************** InterpolantImplicit ********************************/
339 
340 template<template<class> class Func, class Type >
341 void InterpolantImplicit::set_functor(Func<Type>* func, bool interpolate_derivative)
342 {
343  this->func = func;
344  func_diff = new Func<B<Type> >();
345  func_diffn = new Func<T<Type> >();
346 
348  func_diffn->set_param_from_func(func);
349 
350  this->interpolate_derivative = interpolate_derivative;
351 
352  checks[Check::functor] = true;
353 }
354 
355 template<template<class> class Func, class Type >
356 InterpolantImplicit::InterpolantImplicit(Func<Type>* func, bool interpolate_derivative)
357  : func(func),
358  interpolate_derivative(interpolate_derivative),
359  explicit_interpolant(NULL),
360  fix_(IFixVariable::no_fix)
361 {
362  func_diff = new Func<B<Type> >();
363  func_diffn = new Func<T<Type> >();
364 
366  func_diffn->set_param_from_func(func);
367 
368  checks[Check::functor] = true;
369 }
370 
371  ///class FuncExplicit.
372  /** This functor transforms implicit functor with two variables into
373  * an explicit functor with only one variable and the other one fixed.
374  */
375  template<class Type>
377  {
378  public:
379  ///Constructor.
381 
382  //constructor from templated implicit functor
383  template<class TType>
385  : func_impl(&func_impl), fix_(fix), fix_val(fix_val) {}
386 
387  Type operator()(Type u)
388  {
389  Type ret;
391  ret = func_impl->operator()(fix_val,u);
393  ret = func_impl->operator()(u,fix_val);
394 
395  return ret;
396  }
397 
398  private:
401  double fix_val;
402  };
403 
404 
405 inline double InterpolantImplicit::val(double u)
406 {
407  return explicit_interpolant->val(u);
408 }
409 
411 {
412  return explicit_interpolant->diff(u);
413 }
414 
415 #endif //INTERPOLATION_IMPL_H
FunctorBase< B< double > > * func_diff
Pointer to original functor with FADBAD B type.
Definition: interpolant.hh:361
double bound_b() const
Returns right boundary of the interval.
double a_div_step
bound_ divided by step - precomputed value for evaluation
Definition: interpolant.hh:145
bool interpolate_derivative
Is true if we want to interpolate the derivative too.
Definition: interpolant.hh:507
unsigned int interval_miss_b
counts right misses of the interval
Definition: interpolant.hh:123
FuncError_wp1(Interpolant *interpolant, double p, double tol)
InterpolantImplicit()
constructor
Definition: interpolant.cc:530
Type operator()(Type u)
Virtual operator () with type Type.
Abstract templated implicit functor class.
Definition: functors.hh:114
void set_functor(Func< Type > *func, bool interpolate_derivative=false)
Sets the implicit functor.
unsigned int total_calls
counts total calls of evaluation
Definition: interpolant.hh:123
virtual double operator()(double x)
Virtual operator () with type Type.
double error()
Returns error of the interpolation.
double val_test(double x)
Do NOT use, only for testing purpose.
std::vector< double > df_vec
Vector of function derivatives values at nodes.
Definition: interpolant.hh:368
FunctorBase< T< double > > * func_diffn
Pointer to original functor with FADBAD T type.
Definition: interpolant.hh:362
std::pair< double, double > DiffValue
Definition: interpolant.hh:13
FuncError_lp(Interpolant *interpolant, double p, double tol)
I/O functions with filename storing, able to track current line in opened file. All standard stdio fu...
double f_val(double x)
Returns value of the original functor.
std::vector< double > f_vec
Vector of function values at nodes.
Definition: interpolant.hh:367
void set_functor(Func< Type > *func, bool interpolate_derivative=false)
Sets the functor.
double error_
Error of the interpolation.
Definition: interpolant.hh:159
unsigned int size() const
Returns the size of the interpolation table.
IFunctorBase< B< double > > * func_diff
Definition: interpolant.hh:504
Interpolant * explicit_interpolant
Definition: interpolant.hh:509
double max
maximal x for which the evaluation was called outside the interval ((initially is equal the right bou...
Definition: interpolant.hh:127
DiffValue diff(double x)
Returns interpolated value of the derivation.
DiffValue diff_p1(double x)
Finds interval on which x lies.
FuncExplicit(IFunctorBase< TType > &func_impl, IFixVariable::Type fix, double fix_val)
double val_p1(double x)
Do NOT use, unless you are 100% sure.
#define ASSERT(...)
Definition: global_defs.h:121
means that the linear approximation on the first and last subintervals will be used outside the inter...
Definition: interpolant.hh:21
Structure that keeps statistics of evaluation.
Definition: interpolant.hh:122
x variable will be fixed with given value
Definition: interpolant.hh:42
Abstract templated explicit functor class.
Definition: functors.hh:93
FunctorBase< double > * func
Pointer to original functor with double type.
Definition: interpolant.hh:358
DiffValue diff(double u)
Returns interpolated value of the derivation.
means that the values at the boundary points will be used outside the interval_miss_a ...
Definition: interpolant.hh:20
double val(double x)
Returns interpolated value.
double step
Chosen interpolation step.
Definition: interpolant.hh:145
means that the original functor will be called outside interpolation interval
Definition: interpolant.hh:22
std::vector< bool > checks
Vector of boolean values telling us which parameters are set or not.
Definition: interpolant.hh:184
EvalStatistics stats
Structure which keeps evaluation statistics. See InterpolantBase::eval_statistics.
Definition: interpolant.hh:192
Extrapolation::Type extrapolation
Definition: interpolant.hh:164
The main class for interpolation of functors.
Definition: interpolant.hh:269
IFunctorBase< T< double > > * func_diffn
Definition: interpolant.hh:505
virtual double operator()(double x)
Virtual operator () with type Type.
double bound_a() const
Returns left boundary of the interval.
IFunctorBase< double > * func
Definition: interpolant.hh:503
void set_param_from_func(FunctorCommon< TType > *func)
Sets a functor's parameters from another functor.
double bound_a_
Left interval boundary.
Definition: interpolant.hh:145
unsigned int interval_miss_a
counts left misses of the interval
Definition: interpolant.hh:123
double val(double u)
Returns interpolated value.
bool interpolate_derivative
Is true if we want to interpolate the derivative too.
Definition: interpolant.hh:364
DiffValue f_diff(double x)
Returns 1st derivative of original functor using FADBAD.
double bound_b_
Right interval boundary.
Definition: interpolant.hh:145
Interpolant()
Default constructor.
Definition: interpolant.cc:142
y variable will be fixed with given value
Definition: interpolant.hh:43
double min
minimal x for which the evaluation was called outside the interval (initially is equal the left bound...
Definition: interpolant.hh:127
EvalStatistics statistics() const
Returns structure with evaluation statistics.
unsigned int size_
Number of dividing intervals.
Definition: interpolant.hh:150