2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-25 06:22:09 +00:00
Files
math/example/autodiff_multiprecision.cpp

47 lines
1.8 KiB
C++

// Copyright Matthew Pulver 2018 - 2019.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/math/differentiation/autodiff.hpp>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <iostream>
template<typename T>
T f(const T& w, const T& x, const T& y, const T& z)
{
using namespace std;
return exp(w*sin(x*log(y)/z) + sqrt(w*z/(x*y))) + w*w/tan(z);
}
int main()
{
using cpp_bin_float_50 = boost::multiprecision::cpp_bin_float_50;
using namespace boost::math::differentiation;
constexpr int Nw=3; // Max order of derivative to calculate for w
constexpr int Nx=2; // Max order of derivative to calculate for x
constexpr int Ny=4; // Max order of derivative to calculate for y
constexpr int Nz=3; // Max order of derivative to calculate for z
using var = autodiff_fvar<cpp_bin_float_50,Nw,Nx,Ny,Nz>;
const var w = make_fvar<cpp_bin_float_50,Nw>(11);
const var x = make_fvar<cpp_bin_float_50,0,Nx>(12);
const var y = make_fvar<cpp_bin_float_50,0,0,Ny>(13);
const var z = make_fvar<cpp_bin_float_50,0,0,0,Nz>(14);
const var v = f(w,x,y,z);
// Calculated from Mathematica symbolic differentiation.
const cpp_bin_float_50 answer("1976.319600747797717779881875290418720908121189218755");
std::cout << std::setprecision(std::numeric_limits<cpp_bin_float_50>::digits10)
<< "mathematica : " << answer << '\n'
<< "autodiff : " << v.derivative(Nw,Nx,Ny,Nz) << '\n'
<< "relative error: " << std::setprecision(3) << (v.derivative(Nw,Nx,Ny,Nz)/answer-1)
<< std::endl;
return 0;
}
/*
Output:
mathematica : 1976.3196007477977177798818752904187209081211892188
autodiff : 1976.3196007477977177798818752904187209081211892188
relative error: 2.67e-50
**/