#ifndef CPP2TAYLOR_H_CPP2 #define CPP2TAYLOR_H_CPP2 //=== Cpp2 type declarations ==================================================== #include "cpp2util.h" #line 1 "cpp2taylor.h2" #line 4 "cpp2taylor.h2" namespace cpp2 { template class taylor; #line 257 "cpp2taylor.h2" } //=== Cpp2 type definitions and function declarations =========================== #line 1 "cpp2taylor.h2" #ifndef CPP2_CPP2TAYLOR_H #define CPP2_CPP2TAYLOR_H #line 4 "cpp2taylor.h2" namespace cpp2 { template class taylor { public: std::array v {}; public: explicit taylor(); public: taylor(R const& d1); #line 10 "cpp2taylor.h2" public: auto operator=(R const& d1) -> taylor& ; #line 14 "cpp2taylor.h2" public: taylor(taylor const& that); #line 14 "cpp2taylor.h2" public: auto operator=(taylor const& that) -> taylor& ; #line 14 "cpp2taylor.h2" public: taylor(taylor&& that) noexcept; #line 14 "cpp2taylor.h2" public: auto operator=(taylor&& that) noexcept -> taylor& ; public: taylor(std::initializer_list const& l); #line 16 "cpp2taylor.h2" public: auto operator=(std::initializer_list const& l) -> taylor& ; #line 23 "cpp2taylor.h2" // C++ interface public: [[nodiscard]] auto operator[](cpp2::impl::in k) const& -> R; #line 35 "cpp2taylor.h2" public: auto set(cpp2::impl::in k, cpp2::impl::in value) & -> void; #line 45 "cpp2taylor.h2" // C++2 interface / AD interface public: [[nodiscard]] auto get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R; #line 58 "cpp2taylor.h2" // Overload for reverse AD. public: auto operator+=(cpp2::impl::in o) & -> auto&&; #line 64 "cpp2taylor.h2" // Overload for reverse AD. public: auto operator-=(cpp2::impl::in o) & -> auto&&; #line 70 "cpp2taylor.h2" // Overload for simple handling of connected adds. public: [[nodiscard]] auto operator+(cpp2::impl::in o) const& -> taylor; #line 75 "cpp2taylor.h2" // Overload for simple handling of connected minuses. public: [[nodiscard]] auto operator-(cpp2::impl::in o) const& -> taylor; #line 80 "cpp2taylor.h2" // Overload for simple handling of prefix +. public: [[nodiscard]] auto operator+() const& -> taylor; #line 85 "cpp2taylor.h2" // Overload for simple handling of prefix -. public: [[nodiscard]] auto operator-() const& -> taylor; #line 97 "cpp2taylor.h2" public: [[nodiscard]] auto add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; #line 108 "cpp2taylor.h2" public: [[nodiscard]] auto sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; #line 119 "cpp2taylor.h2" public: template [[nodiscard]] auto mul(taylor const& o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; #line 133 "cpp2taylor.h2" public: [[nodiscard]] auto div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor; #line 151 "cpp2taylor.h2" public: [[nodiscard]] auto sqrt(cpp2::impl::in v0) const& -> taylor; #line 170 "cpp2taylor.h2" public: [[nodiscard]] auto log(cpp2::impl::in v0) const& -> taylor; #line 189 "cpp2taylor.h2" public: [[nodiscard]] auto exp(cpp2::impl::in v0) const& -> taylor; #line 208 "cpp2taylor.h2" public: static auto comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void; #line 225 "cpp2taylor.h2" public: [[nodiscard]] auto sin(cpp2::impl::in v0) const& -> taylor; #line 235 "cpp2taylor.h2" public: [[nodiscard]] auto cos(cpp2::impl::in v0) const& -> taylor; #line 244 "cpp2taylor.h2" }; template [[nodiscard]] auto to_string(taylor const& o) -> std::string; #line 257 "cpp2taylor.h2" } // cpp2 namespace #endif // CPP2_CPP2TAYLOR_H //=== Cpp2 function definitions ================================================= #line 1 "cpp2taylor.h2" #line 4 "cpp2taylor.h2" namespace cpp2 { #line 9 "cpp2taylor.h2" template taylor::taylor(){} #line 10 "cpp2taylor.h2" template taylor::taylor(R const& d1) : v{ }{ #line 12 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS_LITERAL(v, 0) = d1; } #line 10 "cpp2taylor.h2" template auto taylor::operator=(R const& d1) -> taylor& { v = {}; #line 12 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS_LITERAL(v, 0) = d1; return *this; #line 13 "cpp2taylor.h2" } #line 14 "cpp2taylor.h2" template taylor::taylor(taylor const& that) : v{ that.v }{} #line 14 "cpp2taylor.h2" template auto taylor::operator=(taylor const& that) -> taylor& { v = that.v; return *this; } #line 14 "cpp2taylor.h2" template taylor::taylor(taylor&& that) noexcept : v{ std::move(that).v }{} #line 14 "cpp2taylor.h2" template auto taylor::operator=(taylor&& that) noexcept -> taylor& { v = std::move(that).v; return *this; } #line 16 "cpp2taylor.h2" template taylor::taylor(std::initializer_list const& l){ { auto i{1}; #line 18 "cpp2taylor.h2" for ( auto const& cur : l ) { set(i, cur); } } #line 21 "cpp2taylor.h2" } #line 16 "cpp2taylor.h2" template auto taylor::operator=(std::initializer_list const& l) -> taylor& { v = {}; { auto i{1}; #line 18 "cpp2taylor.h2" for ( auto const& cur : l ) { set(i, cur); } } return *this; #line 21 "cpp2taylor.h2" } #line 25 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator[](cpp2::impl::in k) const& -> R{ if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } R r {CPP2_ASSERT_IN_BOUNDS(v, k - 1)}; { auto i{2}; #line 29 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { r *= i; } } #line 32 "cpp2taylor.h2" return r; } #line 35 "cpp2taylor.h2" template auto taylor::set(cpp2::impl::in k, cpp2::impl::in value) & -> void{ if (cpp2::cpp2_default.is_active() && !([_0 = 1, _1 = k, _2 = dim]{ return cpp2::impl::cmp_less_eq(_0,_1) && cpp2::impl::cmp_less_eq(_1,_2); }()) ) { cpp2::cpp2_default.report_violation(""); } CPP2_ASSERT_IN_BOUNDS(v, k - 1) = value; { auto i{2}; #line 40 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,k); i += 1 ) { CPP2_ASSERT_IN_BOUNDS(v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(v, k - 1)),i); } } #line 43 "cpp2taylor.h2" } #line 47 "cpp2taylor.h2" template [[nodiscard]] auto taylor::get(cpp2::impl::in i, cpp2::impl::in v0) const& -> R{ if (i == 0) { return v0; } else {if (cpp2::impl::cmp_greater(i,dim)) { return 0.0; }} return CPP2_ASSERT_IN_BOUNDS(v, i - 1); } #line 59 "cpp2taylor.h2" template auto taylor::operator+=(cpp2::impl::in o) & -> auto&&{ (*this) = (*this) + o; return (*this); } #line 65 "cpp2taylor.h2" template auto taylor::operator-=(cpp2::impl::in o) & -> auto&&{ (*this) = (*this) - o; return (*this); } #line 71 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+(cpp2::impl::in o) const& -> taylor{ return add(o, 0.0, 0.0); // Primal values are not required. } #line 76 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-(cpp2::impl::in o) const& -> taylor{ return sub(o, 0.0, 0.0); // Primal values are not required. } #line 81 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator+() const& -> taylor{ return (*this); } #line 86 "cpp2taylor.h2" template [[nodiscard]] auto taylor::operator-() const& -> taylor{ taylor r {}; { auto k{1}; #line 90 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = -CPP2_ASSERT_IN_BOUNDS(v, k - 1); } } #line 94 "cpp2taylor.h2" return r; } #line 97 "cpp2taylor.h2" template [[nodiscard]] auto taylor::add(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; #line 101 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) + CPP2_UFCS(get)(o, k, o0); } } #line 105 "cpp2taylor.h2" return r; } #line 108 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sub(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; { auto k{1}; #line 112 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0) - CPP2_UFCS(get)(o, k, o0); } } #line 116 "cpp2taylor.h2" return r; } #line 119 "cpp2taylor.h2" template template [[nodiscard]] auto taylor::mul(taylor const& o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ int constexpr dim_r{ std::max(dim, dim_o) }; taylor r {}; { auto k{1}; #line 124 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim_r); k += 1 ) { { auto j{0}; #line 126 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += get(j, v0) * o.get(k - j, o0); } } #line 129 "cpp2taylor.h2" } } #line 130 "cpp2taylor.h2" return r; } #line 133 "cpp2taylor.h2" template [[nodiscard]] auto taylor::div(cpp2::impl::in o, cpp2::impl::in v0, cpp2::impl::in o0) const& -> taylor{ taylor r {}; R r0 {v0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(v0),o0)}; R factor {1.0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(1.0),o0)}; { auto k{1}; #line 140 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{0}; #line 143 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= CPP2_UFCS(get)(r, j, r0) * o.get(k - j, o0); } } #line 146 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } #line 148 "cpp2taylor.h2" return r; } #line 151 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sqrt(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::sqrt(v0)}; R factor {0.5 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(0.5),r0)}; { auto k{1}; #line 158 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = get(k, v0); { auto j{1}; #line 161 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= r.get(j, r0) * r.get(k - j, r0); } } #line 164 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor; } } #line 167 "cpp2taylor.h2" return r; } #line 170 "cpp2taylor.h2" template [[nodiscard]] auto taylor::log(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::log(v0)}; R factor {1.0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(1.0),v0)}; { auto k{1}; #line 177 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) = k * get(k, v0); { auto j{1}; #line 180 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) -= j * get(k - j, v0) * r.get(j, r0); } } #line 183 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) *= factor / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(factor),k); } } #line 186 "cpp2taylor.h2" return r; } #line 189 "cpp2taylor.h2" template [[nodiscard]] auto taylor::exp(cpp2::impl::in v0) const& -> taylor{ taylor r {}; R r0 {std::exp(v0)}; R factor {1.0 / CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(1.0),v0)}; { auto k{1}; #line 196 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; #line 198 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) += j * r.get(k - j, r0) * get(j, v0); } } #line 201 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(r.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(r.v, k - 1)),k); } } #line 204 "cpp2taylor.h2" return r; } #line 208 "cpp2taylor.h2" template auto taylor::comp_sin_cos(taylor& s, taylor& c, cpp2::impl::in u, cpp2::impl::in u0) -> void{ R s0 {std::sin(u0)}; R c0 {std::cos(u0)}; { auto k{1}; #line 213 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(k,dim); k += 1 ) { { auto j{1}; #line 215 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(j,k); j += 1 ) { CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) += j * u.get(j, u0) * c.get(k - j, c0); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) -= j * u.get(j, u0) * s.get(k - j, s0); } } #line 219 "cpp2taylor.h2" CPP2_ASSERT_IN_BOUNDS(s.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(s.v, k - 1)),k); CPP2_ASSERT_IN_BOUNDS(c.v, k - 1) /= CPP2_ASSERT_NOT_ZERO(CPP2_TYPEOF(CPP2_ASSERT_IN_BOUNDS(c.v, k - 1)),k); } } #line 222 "cpp2taylor.h2" } #line 225 "cpp2taylor.h2" template [[nodiscard]] auto taylor::sin(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; comp_sin_cos(r, t, (*this), v0); static_cast(cpp2::move(t)); return r; } #line 235 "cpp2taylor.h2" template [[nodiscard]] auto taylor::cos(cpp2::impl::in v0) const& -> taylor{ taylor t {}; taylor r {}; comp_sin_cos(t, r, (*this), v0); static_cast(cpp2::move(t)); return r; } #line 246 "cpp2taylor.h2" template [[nodiscard]] auto to_string(taylor const& o) -> std::string{ std::string r {"("}; { auto i{1}; #line 249 "cpp2taylor.h2" for( ; cpp2::impl::cmp_less_eq(i,order); i += 1 ) { r += " " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(o, i)) + ""; } } #line 252 "cpp2taylor.h2" r += " )"; return r; } } #endif