我正在研究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。如何正确找到它?
答案 0 :(得分:0)
这是我发现的一个半官方示例:
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);
}
提取梯度和粗麻布:
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;