11 #include <unsupported/Eigen/AutoDiff> 13 template<
typename Scalar>
20 return x*2 - 1 +
static_cast<Scalar
>(
pow(1+x,2)) + 2*
sqrt(y*y+0) - 4 *
sin(0+x) + 2 *
cos(y+0) -
exp(Scalar(-0.5)*x*x+0);
25 template<
typename Vector>
28 typedef typename Vector::Scalar Scalar;
29 return (p-Vector(Scalar(-1),Scalar(1.))).norm() + (p.array() * p.array()).
sum() + p.dot(p);
32 template<
typename _Scalar,
int NX=Dynamic,
int NY=Dynamic>
37 InputsAtCompileTime = NX,
38 ValuesAtCompileTime = NY
40 typedef Matrix<Scalar,InputsAtCompileTime,1>
InputType;
41 typedef Matrix<Scalar,ValuesAtCompileTime,1>
ValueType;
42 typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime>
JacobianType;
46 TestFunc1() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
47 TestFunc1(
int inputs,
int values) : m_inputs(inputs), m_values(values) {}
49 int inputs()
const {
return m_inputs; }
50 int values()
const {
return m_values; }
53 void operator() (
const Matrix<T,InputsAtCompileTime,1>& x, Matrix<T,ValuesAtCompileTime,1>* _v)
const 55 Matrix<T,ValuesAtCompileTime,1>& v = *_v;
57 v[0] = 2 * x[0] * x[0] + x[0] * x[1];
58 v[1] = 3 * x[1] * x[0] + 0.5 * x[1] * x[1];
66 v[2] = 3 * x[1] * x[0] * x[0];
68 if (inputs()>2 &&
values()>2)
72 void operator() (
const InputType& x, ValueType* v, JacobianType* _j)
const 78 JacobianType& j = *_j;
80 j(0,0) = 4 * x[0] + x[1];
84 j(1,1) = 3 * x[0] + 2 * 0.5 * x[1];
93 j(2,0) = 3 * x[1] * 2 * x[0];
94 j(2,1) = 3 * x[0] * x[0];
96 if (inputs()>2 &&
values()>2)
101 j(2,2) = 3 * x[1] * x[0] * x[0];
102 j(2,2) = 3 * x[1] * x[0] * x[0];
109 #if EIGEN_HAS_VARIADIC_TEMPLATES 111 template <
typename Scalar>
112 struct integratorFunctor
120 integratorFunctor(
const Scalar gain) : _gain(gain) {}
121 integratorFunctor(
const integratorFunctor&
f) : _gain(f._gain) {}
124 template <
typename T1,
typename T2>
125 void operator() (
const T1 &input, T2 *output,
const Scalar dt)
const 130 o[0] = input[0] + input[1] * dt * _gain;
131 o[1] = input[1] * _gain;
135 template <
typename T1,
typename T2,
typename T3>
136 void operator() (
const T1 &input, T2 *output, T3 *jacobian,
const Scalar dt)
const 141 o[0] = input[0] + input[1] * dt * _gain;
142 o[1] = input[1] * _gain;
149 j(0, 1) = dt * _gain;
157 template<
typename Func>
void forward_jacobian_cpp11(
const Func&
f)
159 typedef typename Func::ValueType::Scalar
Scalar;
160 typedef typename Func::ValueType
ValueType;
161 typedef typename Func::InputType
InputType;
162 typedef typename AutoDiffJacobian<Func>::JacobianType
JacobianType;
164 InputType x = InputType::Random(InputType::RowsAtCompileTime);
166 JacobianType j, jref;
168 const Scalar dt = internal::random<double>();
172 f(x, &yref, &jref, dt);
179 AutoDiffJacobian<Func> autoj(f);
180 autoj(x, &y, &j, dt);
186 VERIFY_IS_APPROX(y, yref);
187 VERIFY_IS_APPROX(j, jref);
193 typename Func::InputType x = Func::InputType::Random(f.inputs());
194 typename Func::ValueType y(f.values()), yref(f.values());
195 typename Func::JacobianType j(f.values(),f.inputs()), jref(f.values(),f.inputs());
205 AutoDiffJacobian<Func> autoj(f);
210 VERIFY_IS_APPROX(y, yref);
211 VERIFY_IS_APPROX(j, jref);
218 Vector2f p = Vector2f::Random();
219 typedef AutoDiffScalar<Vector2f> AD;
220 AD ax(p.x(),Vector2f::UnitX());
221 AD ay(p.y(),Vector2f::UnitY());
222 AD res = foo<AD>(ax,ay);
223 VERIFY_IS_APPROX(res.value(),
foo(p.x(),p.y()));
231 Vector2f p = Vector2f::Random();
232 typedef AutoDiffScalar<Vector2f> AD;
233 typedef Matrix<AD,2,1> VectorAD;
234 VectorAD ap = p.cast<AD>();
235 ap.x().derivatives() = Vector2f::UnitX();
236 ap.y().derivatives() = Vector2f::UnitY();
238 AD res = foo<VectorAD>(ap);
239 VERIFY_IS_APPROX(res.value(),
foo(p));
250 #if EIGEN_HAS_VARIADIC_TEMPLATES 251 CALL_SUBTEST(( forward_jacobian_cpp11(integratorFunctor<double>(10)) ));
259 typedef AutoDiffScalar<VectorXd> AD;
260 typedef Matrix<AD,Eigen::Dynamic,1> VectorAD;
261 typedef AutoDiffScalar<VectorAD> ADD;
262 typedef Matrix<ADD,Eigen::Dynamic,1> VectorADD;
264 double s1 = internal::random<double>(), s2 = internal::random<double>(), s3 = internal::random<double>(), s4 = internal::random<double>();
269 x(0).derivatives().resize(2);
270 x(0).derivatives().setZero();
271 x(0).derivatives()(0)= 1;
272 x(1).derivatives().resize(2);
273 x(1).derivatives().setZero();
274 x(1).derivatives()(1)=1;
277 x(0).value().derivatives() = VectorXd::Unit(2,0);
278 x(1).value().derivatives() = VectorXd::Unit(2,1);
281 for(
int idx=0; idx<2; idx++) {
282 x(0).derivatives()(idx).derivatives() = VectorXd::Zero(2);
283 x(1).derivatives()(idx).derivatives() = VectorXd::Zero(2);
286 ADD y =
sin(AD(s3)*x(0) + AD(s4)*x(1));
288 VERIFY_IS_APPROX(y.value().derivatives()(0), y.derivatives()(0).value());
289 VERIFY_IS_APPROX(y.value().derivatives()(1), y.derivatives()(1).value());
290 VERIFY_IS_APPROX(y.value().derivatives()(0), s3*
std::cos(s1*s3+s2*s4));
291 VERIFY_IS_APPROX(y.value().derivatives()(1), s4*
std::cos(s1*s3+s2*s4));
292 VERIFY_IS_APPROX(y.derivatives()(0).derivatives(), -
std::sin(s1*s3+s2*s4)*Vector2d(s3*s3,s4*s3));
293 VERIFY_IS_APPROX(y.derivatives()(1).derivatives(), -
std::sin(s1*s3+s2*s4)*Vector2d(s3*s4,s4*s4));
296 VERIFY_IS_APPROX(z.derivatives()(0).derivatives(), Vector2d(0,1));
297 VERIFY_IS_APPROX(z.derivatives()(1).derivatives(), Vector2d(1,0));
302 const double _cv1_3 = 1.0;
303 const AD chi_3 = 1.0;
305 const AD denom = chi_3 + _cv1_3;
306 return denom.
value();
313 const double _cv1_3 = 1.0;
314 const AD chi_3 = 1.0;
315 const AD denom = 1.0;
319 #define EIGEN_TEST_SPACE 324 return t.value() + t2.value();
336 typedef AutoDiffScalar<Matrix2d> AD;
337 typedef Matrix<AD,2,1> VectorAD;
340 const AD maxVal = v.maxCoeff();
341 const AD minVal = v.minCoeff();
342 return maxVal.value() + minVal.value();
346 typedef AutoDiffScalar<Vector2d> AD;
348 const Matrix<AD, 3, 1> v1;
349 const Matrix<AD, 3, 1> v2 = (s + 3.0) * v1;
350 return v2(0).value();
355 for(
int i = 0; i < g_repeat; i++) {
356 CALL_SUBTEST_1( test_autodiff_scalar<1>() );
357 CALL_SUBTEST_2( test_autodiff_vector<1>() );
358 CALL_SUBTEST_3( test_autodiff_jacobian<1>() );
359 CALL_SUBTEST_4( test_autodiff_hessian<1>() );
Matrix< Scalar, ValuesAtCompileTime, 1 > ValueType
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half &a, const half &b)
A scalar type replacement with automatic differentation capability.
void test_autodiff_hessian()
std::vector< double > values
EIGEN_DEVICE_FUNC const ExpReturnType exp() const
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
#define EIGEN_ASM_COMMENT(X)
void test_autodiff_scalar()
EIGEN_DONT_INLINE Scalar foo(const Scalar &x, const Scalar &y)
void forward_jacobian(const Func &f)
TestFunc1(int inputs, int values)
#define EIGEN_DONT_INLINE
EIGEN_DEVICE_FUNC const CosReturnType cos() const
Matrix< Scalar, InputsAtCompileTime, 1 > InputType
Matrix< Scalar, ValuesAtCompileTime, InputsAtCompileTime > JacobianType
void test_autodiff_vector()
const mpreal sum(const mpreal tab[], const unsigned long int n, int &status, mp_rnd_t mode=mpreal::get_default_rnd())
void test_autodiff_jacobian()
TFSIMD_FORCE_INLINE const tfScalar & z() const
const Scalar & value() const
EIGEN_DEVICE_FUNC const SinReturnType sin() const