TMB Documentation  v1.9.11
atomic_convolve.hpp
1 // Copyright (C) 2013-2016 Kasper Kristensen
2 // License: GPL-2
3 
4 namespace atomic {
5 
6 /* Workhorse version (used while sweeping - pre-allocated output) */
7 Eigen::MatrixXd convol2d_work(const Eigen::MatrixXd& x,
8  const Eigen::MatrixXd& K) CSKIP({
9  int kr = K.rows();
10  int kc = K.cols();
11  Eigen::MatrixXd y(x.rows() - kr + 1, x.cols() - kc + 1);
12  for (int i = 0; i < y.rows(); i++)
13  for (int j = 0; j < y.cols(); j++)
14  y(i, j) = (x.block(i, j, kr, kc).array() * K.array()).sum();
15  return y;
16 })
17 
18 /* Forward declare version used while taping (for AD types) */
19 template <class DerivedA, class DerivedB>
21 convol2d(const Eigen::MatrixBase<DerivedA>& x,
22  const Eigen::MatrixBase<DerivedB>& K);
23 
25  // ATOMIC_NAME
26  convol2d,
27  // OUTPUT_DIM
28  (CppAD::Integer(tx[0]) - CppAD::Integer(tx[2]) + 1) *
29  (CppAD::Integer(tx[1]) - CppAD::Integer(tx[3]) + 1),
30  // ATOMIC_DOUBLE
31  typedef TypeDefs<double>::MapMatrix MapMatrix_t;
32  typedef TypeDefs<double>::ConstMapMatrix ConstMapMatrix_t;
33  int nx1 = CppAD::Integer(tx[0]); int nx2 = CppAD::Integer(tx[1]);
34  int nk1 = CppAD::Integer(tx[2]); int nk2 = CppAD::Integer(tx[3]);
35  int ny1 = nx1 - nk1 + 1; int ny2 = nx2 - nk2 + 1;
36  ConstMapMatrix_t X(&tx[4 ], nx1, nx2);
37  ConstMapMatrix_t K(&tx[4 + nx1 * nx2], nk1, nk2);
38  MapMatrix_t Y(&ty[0 ], ny1, ny2);
39  Y = convol2d_work(X, K);
40  ,
41  // ATOMIC_REVERSE
42  typedef typename TypeDefs<Type>::MapMatrix MapMatrix_t;
43  typedef typename TypeDefs<Type>::ConstMapMatrix ConstMapMatrix_t;
44  int nx1 = CppAD::Integer(tx[0]); int nx2 = CppAD::Integer(tx[1]);
45  int nk1 = CppAD::Integer(tx[2]); int nk2 = CppAD::Integer(tx[3]);
46  int ny1 = nx1 - nk1 + 1; int ny2 = nx2 - nk2 + 1;
47  ConstMapMatrix_t X(&tx[4 ], nx1, nx2);
48  ConstMapMatrix_t K(&tx[4 + nx1 * nx2], nk1, nk2);
49  ConstMapMatrix_t Y(&ty[0 ], ny1, ny2);
50  ConstMapMatrix_t W(&py[0 ], ny1, ny2);
51  matrix<Type> Kflip = K.reverse();
52  matrix<Type> Wexpand(W.rows() + 2 * (K.rows() - 1),
53  W.cols() + 2 * (K.cols() - 1));
54  Wexpand.setZero();
55  Wexpand.block(K.rows() - 1, K.cols() - 1, W.rows(), W.cols()) = W;
56  MapMatrix_t P0(&px[0 ], 1, 4);
57  MapMatrix_t PX(&px[4 ], nx1, nx2);
58  MapMatrix_t PK(&px[4 + nx1 * nx2], nk1, nk2);
59  P0.setZero();
60  PX = convol2d(Wexpand, Kflip);
61  PK = convol2d( X, W);
62 )
63 
64 /* Implementation of the forward declared version */
65 template <class DerivedA, class DerivedB>
67  const Eigen::MatrixBase<DerivedA>& x,
68  const Eigen::MatrixBase<DerivedB>& K) {
69  typedef typename DerivedA::Scalar Type;
70  CppAD::vector<Type> arg(4 + x.size() + K.size());
71  arg[0] = x.rows(); arg[1] = x.cols();
72  arg[2] = K.rows(); arg[3] = K.cols();
73  for (int i = 0; i < x.size(); i++) {
74  arg[4 + i] = x(i);
75  }
76  for (int i = 0; i < K.size(); i++) {
77  arg[4 + i + x.size()] = K(i);
78  }
79  CppAD::vector<Type> res = convol2d(arg);
80  matrix<Type> y = vec2mat(res, x.rows() - K.rows() + 1, x.cols() - K.cols() + 1);
81  return y;
82 }
83 
84 }
Namespace with special functions and derivatives.
Matrix class used by TMB.
Definition: vector.hpp:101
Type sum(Vector< Type > x)
Definition: convenience.hpp:33
#define TMB_ATOMIC_VECTOR_FUNCTION( ATOMIC_NAME, OUTPUT_DIM, ATOMIC_DOUBLE, ATOMIC_REVERSE)
Construct atomic vector function based on known derivatives.
License: GPL v2