应用Boost自动微分失败

发布于 2025-01-13 00:59:01 字数 2227 浏览 1 评论 0原文

我想使用 boost autodiff 功能来计算复杂函数的二阶导数。

在 boost 帮助中,我可以看一下以下示例:

#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>

template <typename T>
T fourth_power(T const& x) {
    T x4 = x * x;  // retval in operator*() uses x4's memory via NRVO.
    x4 *= x4;      // No copies of x4 are made within operator*=() even when squaring.
    return x4;     // x4 uses y's memory in main() via NRVO.
}

int main() {
    using namespace boost::math::differentiation;

    constexpr unsigned Order = 5;                  // Highest order derivative to be calculated.
    auto const x = make_fvar<double, Order>(2.0);  // Find derivatives at x=2.
    auto const y = fourth_power(x);
    for (unsigned i = 0; i <= Order; ++i)
        std::cout << "y.derivative(" << i << ") = " << y.derivative(i) << std::endl;
    return 0;
}

我想使用这种可能性来计算我的类结构中的导数,但我不明白如何做。这是我的 .cxx 文件的简化代码示例。我有一个参数方程,它分为两个函数来获取 x 和 y 坐标。 半径是一个成员变量。我想计算该参数方程在位置 phi 处的二阶导数。

#include <boost/math/differentiation/autodiff.hpp>

double
get_x_coordinate(const double phi) const {
    return (radius*cos(phi));
}

double
get_y_coordinate(const double phi) const {
    return (radius*sin(phi));
}

double
do_something(const double phi) const {
    auto const x = boost::math::differentiation::make_fvar<double, 2>(phi);
    auto fx = [this](auto x) { return get_x_coordinate(x); };
    auto fy = [this](auto x) { return get_y_coordinate(x); };
    auto const dx = fx(x);
    auto const dy = fy(x);
    return (dx.derivative(2)+dy.derivative(2));
}

该示例因以下错误而失败。

无法从 boost::math:: Differentiation::autodiff_v1::detail::fvar转换参数 1'到“const double”

我无法更改 get_x_coefficient 和 get_y_coordinate 接收 const double 并返回 double,因为我在其他位置的代码中使用了它们。所以我真的不知道如何继续。

之间有什么区别

#include <boost/math/differentiation/autodiff.hpp>

#include <boost/math/differentiation/autodiff_cpp11.hpp>

另外,我正在使用 Visual studio 2017。我问自己,如果我使用 VS2017,我是否必须使用 cpp11 ?两者都可以在我的 boost 版本中使用。

I want to use the boost autodiff functionality to calculate the 2nd derivative of a complicated function.

At the boost help I can take a look on the following example:

#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>

template <typename T>
T fourth_power(T const& x) {
    T x4 = x * x;  // retval in operator*() uses x4's memory via NRVO.
    x4 *= x4;      // No copies of x4 are made within operator*=() even when squaring.
    return x4;     // x4 uses y's memory in main() via NRVO.
}

int main() {
    using namespace boost::math::differentiation;

    constexpr unsigned Order = 5;                  // Highest order derivative to be calculated.
    auto const x = make_fvar<double, Order>(2.0);  // Find derivatives at x=2.
    auto const y = fourth_power(x);
    for (unsigned i = 0; i <= Order; ++i)
        std::cout << "y.derivative(" << i << ") = " << y.derivative(i) << std::endl;
    return 0;
}

I want to use this possibility to calculate a derivative in my class structure but I don't understand how. Here is a simplified code example of my .cxx file. I have a parametric equation which is seperated in two functions to get the x and y-coordinate. radius is a member variable. I want to calculate the second derivative of this parametric equation at a position phi.

#include <boost/math/differentiation/autodiff.hpp>

double
get_x_coordinate(const double phi) const {
    return (radius*cos(phi));
}

double
get_y_coordinate(const double phi) const {
    return (radius*sin(phi));
}

double
do_something(const double phi) const {
    auto const x = boost::math::differentiation::make_fvar<double, 2>(phi);
    auto fx = [this](auto x) { return get_x_coordinate(x); };
    auto fy = [this](auto x) { return get_y_coordinate(x); };
    auto const dx = fx(x);
    auto const dy = fy(x);
    return (dx.derivative(2)+dy.derivative(2));
}

This example fails because of the following error.

cannot convert argument 1 from boost::math::differentiation::autodiff_v1::detail::fvar<RealType,10>' to 'const double'

I cannot change that get_x_coordinate and get_y_coordinate receive a const double and return a double because I use them in my code at other positions. So I don't really know how to continue.

Also I'm using Visual studio 2017. I ask myself what is the difference between

#include <boost/math/differentiation/autodiff.hpp>

and

#include <boost/math/differentiation/autodiff_cpp11.hpp>

Do I have to use cpp11 if I use VS2017? Both are available in my boost version.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

摇划花蜜的午后 2025-01-20 00:59:01

感兴趣的函数将转换为可以接受 double 或 boost fvar 参数的模板。请注意,boost 提供了标准库(例如 sin、cos)中适合 fvar 的三角函数的自定义实现:

#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>
#include <math.h>

constexpr double const radius{4.0};

template <typename T>
T get_x_coordinate(T const & phi)
{
    return radius * cos(phi);
}

int main()
{
    double const phi{2.0};
    auto const x{::boost::math::differentiation::make_fvar<double, 2>(phi)};
    auto const dx{get_x_coordinate(x)};
    ::std::cout << dx.derivative(2) << ::std::endl;
    return 0;
}

在线编译器

Functions of interest are to be converted into templates that may accept either double or boost fvar arguments. Note that boost provides custom implementations of trigonometric functions from standard library (such as sin, cos) suitable for fvar:

#include <boost/math/differentiation/autodiff.hpp>
#include <iostream>
#include <math.h>

constexpr double const radius{4.0};

template <typename T>
T get_x_coordinate(T const & phi)
{
    return radius * cos(phi);
}

int main()
{
    double const phi{2.0};
    auto const x{::boost::math::differentiation::make_fvar<double, 2>(phi)};
    auto const dx{get_x_coordinate(x)};
    ::std::cout << dx.derivative(2) << ::std::endl;
    return 0;
}

online compiler

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文