E.V.E
v2023.02.15
Loading...
Searching...
No Matches
Mathematical functions

Detailed Description

Current Mathematical functions.

This module provides implementation for scalar and SIMD versions of mathematical functions, mainly libc++ ones.

Required header:

#include <eve/module/math.hpp>

Contents

 Constants
 Continued Fractions
 Exponential
 Hyperbolic
 Inverse hyperbolic
 Inverse trigonometric
 Logarithm
 Trigonometric

Variables

constexpr auto eve::horner = functor<horner_t>
 Implement the horner scheme to evaluate polynomials with coefficients in decreasing power order.
constexpr auto eve::reverse_horner = functor<reverse_horner_t>
 implement the horner scheme to evaluate polynomials with coefficients in increasing power order
constexpr auto eve::tchebsum = functor<tchebsum_t>
 Implement the evaluation of tchebytchev polynomials with coefficients in increasing or decreasing power order.

Variable Documentation

◆ horner

auto eve::horner = functor<horner_t>
inlineconstexpr

Implement the horner scheme to evaluate polynomials with coefficients in decreasing power order.

If \((c_i)_{0\le i\le n-1}\) denotes the coefficients of the polynomial by decreasing power order, the Horner scheme evaluates the polynom \(p\) at \(x\) by :

\(\qquad\displaystyle p(x) = (((c_0x+c_1)x+ ... )x + c_{n-1})\)

Header file

#include <eve/module/math.hpp>

Callable Signatures

namespace eve
{
// Regular overloads
constexpr auto horner(floating_value auto x, value auto ...ci) noexcept; // 1
constexpr auto horner(floating_value auto x, eve::coefficients auto tci) noexcept; // 2
// Lanes masking
constexpr auto horner[conditional_expr auto c](/*any of the above overloads*/) noexcept; // 3
constexpr auto horner[logical_value auto m](/*any of the above overloads*/) noexcept; // 3
// Semantic options
constexpr auto horner[pedantic](/*any of the above overloads*/) noexcept; // 4
constexpr auto horner[kahan](/*any of the above overloads*/) noexcept; // 5
constexpr auto horner[widen](/*any of the above overloads*/) noexcept; // 6
}
Specifies that a type is a Conditional Expression.
Definition conditional.hpp:28
The concept floating_value<T> is satisfied if and only if T satisfies eve::value and the element type...
Definition value.hpp:116
The concept logical_value<T> is satisfied if and only if T satisfies eve::value and the element type ...
Definition value.hpp:134
The concept value<T> is satisfied if and only if T satisfies either eve::scalar_value or eve::simd_va...
Definition value.hpp:34
constexpr auto widen
Computes the result in the upgraded element type.
Definition core.hpp:106
constexpr auto pedantic
Follows the corner cases of the corresponding standard function.
Definition core.hpp:91
constexpr auto horner
Implement the horner scheme to evaluate polynomials with coefficients in decreasing power order.
Definition horner.hpp:120
EVE Main Namespace.
Definition abi.hpp:19

Parameters

Return value

If \((c_i)_{0\le i\le n-1}\) denotes the coefficients of the polynomial by decreasing power order, the Horner scheme evaluates the polynom \(p\) at \(x\) by : \(\qquad\qquad\displaystyle p(x) = (((c_0x+c_1)x+ ... )x + c_{n-1})\)

  1. The value of the polynom at x is returned.
  2. Same as the call with the elements of the tuple.
  3. The operation is performed conditionally.
  4. fma[pedantic] instead of fma is used in internal computations.
  5. a Kahan like compensated algorithm is used to enhance accuracy.
  6. the computation is applied to upgraded types values when available.
Note
If the coefficients are simd values of cardinal N, this means you simultaneously compute the values of N polynomials.
  • If x is scalar, the polynomials are all computed at the same point
  • If x is simd, the nth polynomial is computed on the nth value of x

External references

Example

// revision 1 TODO
#include <eve/module/math.hpp>
#include <iostream>
#include <iomanip>
int main()
{
eve::wide xd = {-0.3, 0.5, 0.0, 2.0};
eve::wide b = {-2.0, 10.5, -4.0, 0.1};
double x(0.2);
kumi::tuple v {1.0, -2.0, 3.0, -4.0};
using w_t = decltype(xd);
kumi::tuple wv{ w_t{1.5, 1, 2, 3}, w_t{4, 5, 6, 7}, w_t{8, 9, 10, 11} };
auto t =kumi::tuple{1.5,4.0,8.0};
std::cout << "<- xd = " << xd << '\n';
std::cout << "<- x = " << x << '\n';
std::cout << "<- v = " << v << '\n';
std::cout << "<- wv = " << wv << '\n';
std::cout << "<- b = " << b << '\n';
std::cout << "-> horner(xd, 1.0, -2.0, 3.0, -4.0) = " << eve::horner(xd, 1.0, -2.0, 3.0, -4.0) << '\n';
std::cout << "-> horner(0.5, 1, b, 3, -4) = " << eve::horner(0.5, 1, b, 3, -4) << '\n';
std::cout << "-> horner(xd, 1, -2, 3, -4) = " << eve::horner(xd, 1, -2, 3, -4) << '\n';
std::cout << "-> horner(xd, eve::coefficients(v)) = " << eve::horner(xd, eve::coefficients(v)) << '\n';
std::cout << "-> horner(xd, eve::coefficients(t)) = " << eve::horner(xd, eve::coefficients(t)) << '\n';
std::cout << "-> horner(x, eve::coefficients(t)) = " << eve::horner(x, eve::coefficients(t)) << '\n';
std::cout << "-> horner(w_t(x), eve::coefficients(t)) = " << eve::horner(w_t(x), eve::coefficients(t)) << '\n';
std::cout << "-> horner(x, eve::coefficients(wv)) = " << eve::horner(x, eve::coefficients(wv)) << '\n';
std::cout << "-> horner(0.5f, eve::coefficients(wv)) = " << eve::horner(0.5, eve::coefficients(wv)) << '\n';
std::cout << "-> horner(xd, eve::coefficients(wv)) = " << eve::horner(xd, eve::coefficients(wv)) << '\n';
std::cout << "-> horner(2.0, eve::coefficients(t)) = " << eve::horner(2.0, eve::coefficients(t)) << '\n';
std::cout << "-> horner(2.0,1.5,4.0,8.0) = " << eve::horner(2.0, 1.5,4.0,8.0) << '\n';
std::cout << "-> horner(w_t(2.0),1.5,4.0,8.0) = " << eve::horner(w_t(2.0), 1.5,4.0,8.0) << '\n';
}
Wrapper for SIMD registers.
Definition wide.hpp:94

◆ reverse_horner

auto eve::reverse_horner = functor<reverse_horner_t>
inlineconstexpr

implement the horner scheme to evaluate polynomials with coefficients in increasing power order

Header file

#include <eve/module/math.hpp>

Callable Signatures

namespace eve
{
// Regular overloads
constexpr auto reverse_horner(floating_value auto x, value auto ci...) noexcept; // 1
constexpr auto reverse_horner(floating_value auto x, eve::coefficients tci) noexcept; // 2
// Semantic options
constexpr auto reverse_horner[pedantic](/*any of the above overloads*/) noexcept; // 3
constexpr auto reverse_horner[kahan](/*any of the above overloads*/) noexcept; // 4
constexpr auto reverse_horner[widen](/*any of the above overloads*/) noexcept; // 5
}
constexpr auto reverse_horner
implement the horner scheme to evaluate polynomials with coefficients in increasing power order
Definition reverse_horner.hpp:117
  1. Polynom is evaluated at x the other inputs are the polynomial coefficients.
  2. Polynom is evaluated at x the other input is a range or a kumi::tuple containing the coefficients
  3. fma[pedantic] instead of fma is used in internal computations.
  4. a Kahan like compensated algorithm is used to enhance accuracy.
  5. the computation is applied to upgraded types values when available.

Parameters

Return value

If \((c_i)_{0\le i\le n-1}\) denotes the coefficients of the polynomial by increasing power order, the reverse Horner scheme evaluates the polynom \(p\) at \(x\) using the following formula:

\(\qquad\qquad\displaystyle p(x) = (((c_{n-1}x+c_{n-2})x+ ... )x + c_0)\)

  1. The value of the polynom at x is returned.
  2. same as the call with the elements of the tuple. 3.fma[pedantic] instead of fma is used in internal computations. This is intended to insure more accurate computations where needed. This has no cost (and is automatically done) if the system has hard wired fma but is very expansive if it is not the case.
Note
If the coefficients are simd values of cardinal N, this means you simultaneously compute the values of N polynomials.
  • If x is scalar, the polynomials are all computed at the same point
  • If x is simd, the nth polynomial is computed on the nth value of x

External references

Example

// revision 1
#include <eve/module/math.hpp>
#include <iostream>
#include <iomanip>
int main()
{
eve::wide xd = {-0.3, 0.5, 0.0, 2.0};
eve::wide b = {-2.0, 10.5, -4.0, 0.1};
double x(0.2);
kumi::tuple v {1.0, -2.0, 3.0, -4.0};
using w_t = decltype(xd);
kumi::tuple wv{ w_t{1.5, 1, 2, 3}, w_t{4, 5, 6, 7}, w_t{8, 9, 10, 11} };
auto t = kumi::tuple{1.5,4.0,8.0};
std::cout << "<- xd = " << xd << '\n';
std::cout << "<- x = " << x << '\n';
std::cout << "<- v = " << v << '\n';
std::cout << "<- wv = " << wv << '\n';
std::cout << "-> reverse_horner(xd, 1.0, -2.0, 3.0, -4.0) = " << eve::reverse_horner(xd, 1.0, -2.0, 3.0, -4.0) << '\n';
std::cout << "-> reverse_horner(0.5, 1, b, 3, -4) = " << eve::reverse_horner(0.5, 1, b, 3, -4) << '\n';
std::cout << "-> reverse_horner(x, 1, -2, 3, -4) = " << eve::reverse_horner(xd, 1, -2, 3, -4) << '\n';
std::cout << "-> reverse_horner(xd, v) = " << eve::reverse_horner(xd, eve::coefficients(v)) << '\n';
std::cout << "-> reverse_horner(xd, t) = " << eve::reverse_horner(xd, eve::coefficients(t)) << '\n';
std::cout << "-> reverse_horner(x, t) = " << eve::reverse_horner(x, eve::coefficients(t)) << '\n';
std::cout << "-> reverse_horner(x, wv) = " << eve::reverse_horner(x, eve::coefficients(wv)) << '\n';
std::cout << "-> reverse_horner(0.5f, wv) = " << eve::reverse_horner(0.5, eve::coefficients(wv)) << '\n';
std::cout << "-> reverse_horner(xd, wv) = " << eve::reverse_horner(xd, eve::coefficients(wv)) << '\n';
std::cout << "-> reverse_horner(2.0, t) = " << eve::reverse_horner(2.0, eve::coefficients(t)) << '\n';
std::cout << "-> reverse_horner(2.0, 1.5,4.0,8.0) = " << eve::reverse_horner(2.0, 1.5,4.0,8.0) << '\n';
std::cout << "-> reverse_horner = " << eve::reverse_horner(w_t(2.0), 1.5,4.0,8.0) << '\n';
}

◆ tchebsum

auto eve::tchebsum = functor<tchebsum_t>
inlineconstexpr

Implement the evaluation of tchebytchev polynomials with coefficients in increasing or decreasing power order.

If \((c_i)_{0\le i\le n-1}\) denotes the coefficients of the polynomial by increasing power order, the Tchebsum scheme evaluates : \(\qquad\displaystyle p(x) = c_0/2+\sum_1^n c_n T_n(x))\)

Header file

#include <eve/module/math.hpp>

Callable Signatures

namespace eve
{
// Regular overloads
constexpr auto tchebsum(floating_value auto x, value auto ...ci) noexcept; // 1
constexpr auto tchebsum(floating_value auto x, eve::coefficients auto tci) noexcept; // 2
// Lanes masking
constexpr auto tchebsum[conditional_expr auto c](/*any of the above overloads*/) noexcept; // 3
constexpr auto tchebsum[logical_value auto m](/*any of the above overloads*/) noexcept; // 3
// Semantic options
constexpr auto tchebsum[pedantic](/*any of the above overloads*/) noexcept; // 4
constexpr auto tchebsum[kahan](/*any of the above overloads*/) noexcept; // 5
constexpr auto tchebsum[widen](/*any of the above overloads*/) noexcept; // 6
constexpr auto tchebsum[increasing](/*any of the above overloads*/) noexcept; // 1
constexpr auto tchebsum[decreasing](/*any of the above overloads*/) noexcept; // 7
}
constexpr auto tchebsum
Implement the evaluation of tchebytchev polynomials with coefficients in increasing or decreasing pow...
Definition tchebsum.hpp:120

Parameters

Return value

If \((c_i)_{0\le i\le n-1}\) denotes the Tchebytchev coefficients of the polynomial The Tchebsum scheme evaluates : \(\qquad\displaystyle p(x) = c_0/2+\sum_1^n c_n T_n(x))\)

  1. The value at x f the polynom based on first kind Tchebytchev function is returned.
  2. Same as the call with the elements of the tuple.
  3. The operation is performed conditionally.
  4. fma[pedantic] instead of fma is used in internal computations.
  5. a Kahan like compensated algorithm is used to enhance accuracy.
  6. the computation is applied to upgraded types values when available.
  7. the order of the given coefficients is reversed
Note
If the coefficients are simd values of cardinal N, this means you simultaneously compute the values of N polynomials.
  • If x is scalar, the polynomials are all computed at the same point
  • If x is simd, the nth polynomial is computed on the nth value of x

External references

Example

// revision 1
#include <eve/module/math.hpp>
#include <eve/module/polynomial.hpp>
#include <iostream>
#include <array>
double tch1(auto t, auto c)
{
double u0 = 0;
double u1 = 0;
double u2 = 0;
auto tt = t+t;
for(int i=c.size()-1; i >= 0 ; --i)
{
u2=u1;
u1=u0;
u0=tt*u1+c[i]-u2;
}
return (u0-u2)/2;
}
double tch2(auto t, auto ... c)
{
double u0 = 0;
double u1 = 0;
double u2 = 0;
auto tt = t+t;
auto clemshaw_step = [&](auto ci){
u2=u1;
u1=u0;
u0 = fma(tt, u1, ci-u2);
return u0;
};
((u0 = clemshaw_step(c)), ...);
return (u0-u2)/2;
}
int main()
{
std::array<double, 4> c{1, 2, 3, 4};
std::array<double, 4> d{4.0, 3.0, 2.0, 1.0};
std::cout << tch1(-2.0, c) << std::endl;
std::cout << eve::tchebsum[eve::increasing](2.0, c)<< std::endl;
std::cout << eve::tchebsum[eve::decreasing](2.0, d)<< std::endl;
std::cout << tch2(2.0, 4.0, 3.0, 2.0, 1.0)<< std::endl;
std::cout << eve::tchebsum[eve::decreasing](2.0, 4.0, 3.0, 2.0, 1.0)<< std::endl;
std::cout << eve::tchebsum(2.0, 1.0, 2.0, 3.0, 4.0)<< std::endl;
eve::wide<double, eve::fixed<4>> xx{-2.0, -0.44, 0.44, 2.0};
std::cout << eve::tchebsum[eve::increasing](xx, c)<< std::endl;
std::cout << eve::tchebsum[eve::decreasing](xx, d)<< std::endl;
std::cout << eve::tchebsum(xx, 1.0, 2.0, 3.0, 4.0)<< std::endl;
}
constexpr auto fma
strict_elementwise_callable computing the fused multiply add of its three parameters.
Definition fma.hpp:100