如何找到本征的AutoDiffScalar二阶导数?

时间:2019-06-22 09:53:12

标签: eigen autodiff

我正在研究Eigen-3.3.7的AutoDiff模块。考虑这个简单的示例,该示例找到x 2 的导数。

#include <eigen3/Eigen/Core>
#include <eigen3/unsupported/Eigen/AutoDiff>
#include <iostream>

int main()
{
  Eigen::AutoDiffScalar<Eigen::Vector2d> x(8.0, Eigen::Vector2d(1,0)), y;

  y = x*x;

  std::cout << "x = " << x << "\n"
            << "y = " << y << "\n"
            << "y' = " << y.derivatives()[0] << "\n"
            << "y'' = " << y.derivatives()[1] << "\n";

  return 0;
}

二阶导数的输出为0而不是2。如何正确找到它?

1 个答案:

答案 0 :(得分:0)

这是我发现的一个半官方示例:

  1. 函数定义(应输出标量)
    template <typename T>
    T my_matrixfun(
        Eigen::Matrix<T,Eigen::Dynamic,1> const &a,
        Eigen::Matrix<T,Eigen::Dynamic,1> const &b)
    {
        Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic> m(a.size(),a.size());
        m.setZero();
        m.diagonal() = a;
        return (b.transpose() * m * b)(0,0);
    }
  1. 提取梯度和粗麻布:

     typedef Eigen::Matrix<double,Eigen::Dynamic,1> inner_derivative_type;
     typedef Eigen::AutoDiffScalar<inner_derivative_type> inner_active_scalar;
     typedef Eigen::Matrix<inner_active_scalar,Eigen::Dynamic,1>    outer_derivative_type;
     typedef Eigen::AutoDiffScalar<outer_derivative_type> outer_active_scalar;
     typedef Eigen::Matrix<outer_active_scalar,Eigen::Dynamic,1> AVector;
     AVector Aa(a.size()),Ab(b.size());
    
     // copy value from non-active example
     for(int i=0;i<a.size();i++)Aa(i).value().value() = a(i);
     for(int i=0;i<b.size();i++)Ab(i).value().value() = b(i);
     // initialize derivative vectors
     const int derivative_num = a.size() + b.size();
     int derivative_idx = 0;
     for(int i=0;i<Aa.size();i++){
         init_twice_active_var(Aa(i),derivative_num,derivative_idx);
         derivative_idx++;
     }
     for(int i=0;i<Ab.size();i++){
         init_twice_active_var(Ab(i),derivative_num,derivative_idx);
         derivative_idx++;
     }
    
     outer_active_scalar Ac = my_matrixfun(Aa,Ab);
     std::cout << "Result: " << Ac.value().value() << std::endl;
     std::cout << "Gradient: " <<
                  Ac.value().derivatives().transpose() << std::endl;
    
     std::cout << "Hessian" << std::endl;
     Eigen::MatrixXd hessian(Ac.derivatives().size(),Ac.derivatives().size());
     for(int idx=0;idx<Ac.derivatives().size();idx++){
         hessian.middleRows(idx,1) =
                 Ac.derivatives()(idx).derivatives().transpose();
     }
     std::cout << hessian << std::endl;