TMB Documentation  v1.9.11
interpol.hpp
Go to the documentation of this file.
1 
6 #ifdef TMBAD_FRAMEWORK
7 
8 #include <memory>
9 
10 namespace tmbutils {
11 
13 template<class Type>
15  interpol2D_config(Type R=2) :
16  R(asDouble(R)), safe_check(true) { }
24  double R;
26  bool safe_check;
27 };
28 
29 template<class Type>
30 struct interpol2Dtab {
31  matrix<double> data;
32  double xmin, xmax, ymin, ymax;
39  template<class T>
40  T f(T x) { return .5 * ( 1 + cos(x * M_PI) ) ; }
46  template<class T>
47  T kernel(T x) { return f(1 - f(x)) ; }
48  // helper
49  template<class T>
50  T sq(T x) { return x * x; }
54  template<class T>
55  T eval(T x_, T y_) {
56  double R = cfg.R;
57  int nrow = data.rows();
58  int ncol = data.cols();
59  T hx = (xmax - xmin) / (nrow - 1);
60  T hy = (ymax - ymin) / (ncol - 1);
61  // Transform (x_, y_) to 'lattice coordinates':
62  T i_ = (x_ - xmin) / hx;
63  T j_ = (y_ - ymin) / hy;
64  // Check
65  bool ok = (0 <= i_) && (i_ <= nrow-1) && (0 <= j_) && (j_ <= ncol-1);
66  if (!ok) return R_NaN;
67  // Envelope window: W := (i_, j_) + [-R, R]^2
68  // Get sub-lattice within envelope: (i_min:i_max) x (j_min:j_max)
69  int i_min = std::max(asDouble(i_) - R, (double) 0);
70  int j_min = std::max(asDouble(j_) - R, (double) 0);
71  int i_max = std::min(asDouble(i_) + R, (double) (nrow-1) );
72  int j_max = std::min(asDouble(j_) + R, (double) (ncol-1) );
73  // Loop through sub-lattice
74  T FWsum = 0, Wsum = 0;
75  for (int i = i_min; i <= i_max; i++) {
76  for (int j = j_min; j <= j_max; j++) {
77  T dist2 = sq( (T) i - i_ ) + sq( (T) j - j_ ) ;
78  double tiny = 1e-100;
79  T dist = sqrt( dist2 + tiny );
80  if (dist <= R) {
81  double F = data(i, j);
82  if (! ISNA(F) ) {
83  T W = kernel(dist / R);
84  FWsum += F * W;
85  Wsum += W;
86  }
87  }
88  }
89  }
90  return FWsum / Wsum;
91  }
93  template<int order>
94  double D_eval(double x_, double y_, int ny) {
95  typedef atomic::tiny_ad::variable<order, 2> T;
96  int i = (1 << ny) - 1;
97  T x(x_, 0);
98  T y(y_, 1);
99  return eval(x, y).getDeriv()[i];
100  }
102  double operator()(double x_, double y_, int nx=0, int ny=0) {
103  int order = nx + ny;
104  if (order == 0) {
105  return eval(x_, y_);
106  } else if (order == 1) {
107  return D_eval<1>(x_, y_, ny);
108  } else if (order == 2) {
109  return D_eval<2>(x_, y_, ny);
110  } else if (order == 3) {
111  return D_eval<3>(x_, y_, ny);
112  } else {
113  Rf_error("Order not implemented");
114  }
115  return 0;
116  }
117 };
118 
144 template<class Type>
146  std::shared_ptr<interpol2Dtab<Type> > dtab;
147  int xorder, yorder;
148  matrix<double> asDoubleCheck(matrix<Type> x, bool do_check=true) {
149  matrix<double> y(x.rows(), x.cols());
150  for (int i=0; i<x.rows(); i++) {
151  for (int j=0; j<x.cols(); j++) {
152  if (do_check && CppAD::Variable(x(i,j)))
153  Rf_error("Matrix values must be constants");
154  y(i,j) = asDouble(x(i,j));
155  }
156  }
157  return y;
158  }
166  vector<Type> x_range,
167  vector<Type> y_range,
169  dtab(std::make_shared<interpol2Dtab<Type> >(interpol2Dtab<Type>({
170  asDoubleCheck(data, cfg.safe_check),
171  asDouble(x_range[0]),
172  asDouble(x_range[1]),
173  asDouble(y_range[0]),
174  asDouble(y_range[1]),
175  cfg
176  }))),
177  xorder(0),
178  yorder(0)
179  { }
180  TMBad::Index input_size() const {
181  return 2;
182  }
183  TMBad::Index output_size() const {
184  return 1;
185  }
186  typedef TMBad::ad_aug ad;
193  double operator()(double x, double y, int nx=0, int ny=0) {
194  return (*dtab)(x, y, nx, ny);
195  }
202  ad operator()(ad x, ad y, int nx=0, int ny=0) {
203  std::vector<ad> xy(2); xy[0]=x; xy[1]=y;
204  interpol2D cpy(*this);
205  cpy.xorder = nx; cpy.yorder=ny;
206  std::vector<ad> z = TMBad::global::Complete<interpol2D>(cpy)(xy);
207  return z[0];
208  }
209 #define Type T
210  VECTORIZE2_tt(operator())
211 #undef Type
212  // Forward pass
213  template<class T>
214  void forward(TMBad::ForwardArgs<T> &args) {
215  args.y(0) = (*this)(args.x(0), args.x(1), xorder, yorder);
216  }
217  // Reverse pass
218  template<class T>
219  void reverse(TMBad::ReverseArgs<T> &args) {
220  T dy = args.dy(0);
221  args.dx(0) += (*this)(args.x(0), args.x(1), xorder + 1, yorder) * dy;
222  args.dx(1) += (*this)(args.x(0), args.x(1), xorder, yorder + 1) * dy;
223  }
224  // sources code writers are not implemented for this class
225  void forward(TMBad::ForwardArgs<TMBad::Writer> &args) { ASSERT(false); }
226  void reverse(TMBad::ReverseArgs<TMBad::Writer> &args) { ASSERT(false); }
227  const char* op_name() { return "IP2D"; }
228 };
229 
230 }
231 
232 #endif
#define VECTORIZE2_tt(FUN)
Vectorize 2-argument functions.
Definition: Vectorize.hpp:71
double R
Interpolation radius relative to integer lattice.
Definition: interpol.hpp:24
Access input/output values and derivatives during a reverse pass. Write access granted for the input ...
Definition: global.hpp:311
bool safe_check
Enable safety check that data really are constant?
Definition: interpol.hpp:26
Access input/output values during a forward pass. Write access granted for the output value only...
Definition: global.hpp:279
Configuration for Interpol2D
Definition: interpol.hpp:14
Type min(const vector< Type > &x)
Augmented AD type.
Definition: global.hpp:2831
Type x(Index j) const
j&#39;th input variable of this operator
Definition: global.hpp:285
Get a smooth representation of a data matrix.
Definition: interpol.hpp:145
Type & y(Index j)
j&#39;th output variable of this operator
Definition: global.hpp:287
Type x(Index j) const
j&#39;th input variable of this operator
Definition: global.hpp:318
Type dy(Index j) const
Partial derivative of end result wrt. j&#39;th output variable of this operator.
Definition: global.hpp:326
Taped sorting of a vector.
Definition: order.hpp:20
Operator auto-completion.
Definition: global.hpp:2129
Operator that requires dynamic allocation. Compile time known input/output size.
Definition: global.hpp:1590
double operator()(double x, double y, int nx=0, int ny=0)
Scalar evaluation with double types.
Definition: interpol.hpp:193
Vector class used by TMB.
Definition: tmbutils.hpp:18
interpol2D(matrix< Type > data, vector< Type > x_range, vector< Type > y_range, interpol2D_config< Type > cfg=interpol2D_config< Type >())
Construct interpolation object.
Definition: interpol.hpp:165
Type & dx(Index j)
Partial derivative of end result wrt. j&#39;th input variable of this operator.
Definition: global.hpp:323
ad operator()(ad x, ad y, int nx=0, int ny=0)
Scalar evaluation with ad types.
Definition: interpol.hpp:202
Utility functions for TMB (automatically included)
Definition: concat.hpp:5
Type max(const vector< Type > &x)
License: GPL v2