Loading [MathJax]/extensions/tex2jax.js
kyosu v0.1.0
Complex Without Complexes
 
All Classes Namespaces Functions Variables Typedefs Modules Pages Concepts
Loading...
Searching...
No Matches

◆ hypergeometric

kyosu::hypergeometric = eve::functor<hypergeometric_t>
inlineconstexpr

Computes the hypergeometric function \({}_pF_q(a_1, \dots, a_p; b_1,\dots, b_p; z)\) for \( 0 \le p, q \le 2\).

Defined in Header

#include <kyosu/functions.hpp>

Callable Signatures

namespace kyosu
{
//regular call
constexpr auto hypergeometric(auto z, auto a, auto b) noexcept; // 1;
// Semantic modifyiers
constexpr auto hypergeometric[regularized](auto z, auto a, auto b) noexcept; // 2
}
constexpr auto hypergeometric
Computes the hypergeometric function for .
Definition: hypergeometric.hpp:119
Main KYOSU namespace.
Definition: cinf.hpp:13

Parameters

  • a: homogeneous kumi tuple of size p
  • b: homogeneous kumi tuple of size q
  • z: Value to process.

Return value

  1. Returns the value at z of the hypergeometric function \({}_pF_q(a_1, \dots, a_p; b_1,\dots, b_p; z) = \sum_{k = 0}^\infty \frac{(a_1)_k\dots (a_p]_k}{(b_1)_k\dots (b_q]_k}\frac{z^k}{k!}\).
    • if \(p < q + 1\): the series converges absolutely for \(z\in \mathbb{C}\), but can be very hard to compute accurately
    • if \(p = q + 1\): the series converges absolutely for \(|z| < 1\) and diverges for \(|z| > 1\),
    • if \(p > q + 1\): the series converges only for \(z = 0\) unless the summation stops, an \(a_i\) or \(b_i\) being a non positive flint and the polynomial is so defined everywhere.
  2. With the regularized option the result is divided by the product of the \(\Gamma(b_i)\) extended to the elements of the b tuple.

Up to now the only implemented functions are for size of a and b tuples running from 0 to 2.

Note
hypergeometric functons are a kind of jungle. As KYOSU and EVE only use standard floating types as base of computations, overflows or lack of precision along large computation or huge values can degrade the accuracy. Moreover:
  • These fonctions always return complex outputs even if entries are all real ones.
  • The uses of float-based inputs and computations are ok, but discouraged as overflows or lack of precision are much greater than double-based ones.
  • receiving a fnan ouput generally means than the computation did not end well.
  • receiving a cinf ouput generally means than the function is not defined here and that point is a singularity.

External references

Implementation notes

  • \({}_0F_0(z, \{\}, \{\})\) is merely \(e^z\).
  • \({}_1F_0(z, \{a\}, \{\}\) is merely \( (1-z)^{-a}\)
  • \({}_0F_1(z, \{\}, \{b\})\), \({}_0F_2(z, \{\}, \{b_0, b_1\})\), \({}_1F_1(z, \{a\}, \{b\})\), \({}_1F_2(z, \{a\}, \{b_0, b_1\})\) and \({}_2F_2(z, \{a_0, a_1\}, \{b_0, b_1\})\) are always computed using the standard serie definition, it implies that their results are only correct for small values of |z|.
  • The serie defining \({}_2F_0(z, \{a_0, a_1\}, \{\})\) is generally never convergent (but at zero) except when a component of a is a nonpositive integer.
  • Implementation of \({}_2F_1(z, \{a_0, a_1\}, \{b\})\) which is the proper hypergeometric function is mainly inspired by the article : Fast computation of the Gauss hypergeometric function with all its parameters complex with application to the Poschl-Teller-Ginocchio potential wave functions by N. Michel and M.V. Stoitsov, adapted to perform SIMD calls

Example

#include <kyosu/kyosu.hpp>
#include <eve/wide.hpp>
#include <iostream>
#include <iomanip>
int main()
{
auto I = kyosu::complex(0.0, 1.0);
std::cout << "hypergeometric(2.0, kumi::tuple{}, kumi::tuple{1.5}) "<< kyosu::hypergeometric(2.0, kumi::tuple{}, kumi::tuple{1.5}) << std::endl;
std::cout << "hypergeometric(2.0, kumi::tuple{}, kumi::tuple{I}) "<< kyosu::hypergeometric(2.0, kumi::tuple{}, kumi::tuple{I}) << std::endl;
std::cout << "hypergeometric(2.0, kumi::tuple{1.5}, kumi::tuple{}) "<< kyosu::hypergeometric(2.0, kumi::tuple{1.5}, kumi::tuple{}) << std::endl;
std::cout << "hypergeometric(-4.0,kumi::tuple{1.0}, kumi::tuple{}) "<< kyosu::hypergeometric(-4.0,kumi::tuple{1.0}, kumi::tuple{}) << std::endl;
std::cout << "hypergeometric(2.0, kumi::tuple{1.5}, kumi::tuple{2.0}) "<< kyosu::hypergeometric(2.0, kumi::tuple{1.5}, kumi::tuple{2.0}) << std::endl;
std::cout << "hypergeometric(-4.0,kumi::tuple{1.0}, kumi::tuple{I}) "<< kyosu::hypergeometric(-4.0,kumi::tuple{1.0}, kumi::tuple{I}) << std::endl;
std::cout << "hypergeometric(2.0, kumi::tuple{1.4, -3.0}, kumi::tuple{}) "<< kyosu::hypergeometric(2.0, kumi::tuple{1.4, -3.0}, kumi::tuple{}) << std::endl;
std::cout << "hypergeometric(2.0, kumi::tuple{1.4, 1.0}, kumi::tuple{2.0}) "<< kyosu::hypergeometric(2.0, kumi::tuple{1.4, 1.0}, kumi::tuple{2.0})<< std::endl;
std::cout << "hypergeometric(2.0, kumi::tuple{1.4}, kumi::tuple{2.5,-1.6}) "<< kyosu::hypergeometric(2.0,kumi::tuple{1.4}, kumi::tuple{2.5,-1.6}) << std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{}, kumi::tuple{1.5}) "<< kyosu::hypergeometric[kyosu::regularized](2.0, kumi::tuple{}, kumi::tuple{1.5}) << std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{}, kumi::tuple{I}) "<< kyosu::hypergeometric[kyosu::regularized](2.0, kumi::tuple{}, kumi::tuple{I}) << std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{1.5}, kumi::tuple{}) "<< kyosu::hypergeometric[kyosu::regularized](2.0, kumi::tuple{1.5}, kumi::tuple{}) << std::endl;
std::cout << "hypergeometric[regularized](-4.0,kumi::tuple{1.0}, kumi::tuple{}) "<< kyosu::hypergeometric[kyosu::regularized](-4.0,kumi::tuple{1.0}, kumi::tuple{}) << std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{1.5}, kumi::tuple{2.0}) "<< kyosu::hypergeometric[kyosu::regularized](2.0, kumi::tuple{1.5}, kumi::tuple{2.0}) << std::endl;
std::cout << "hypergeometric[regularized](-4.0,kumi::tuple{1.0}, kumi::tuple{I}) "<< kyosu::hypergeometric[kyosu::regularized](-4.0,kumi::tuple{1.0}, kumi::tuple{I}) << std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{1.4, -3.0}, kumi::tuple{}) "<< kyosu::hypergeometric[kyosu::regularized](2.0, kumi::tuple{1.4, -3.0}, kumi::tuple{}) << std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{1.4, 1.0}, kumi::tuple{2.0}) "<< kyosu::hypergeometric[kyosu::regularized](2.0, kumi::tuple{1.4, 1.0}, kumi::tuple{2.0})<< std::endl;
std::cout << "hypergeometric[regularized](2.0, kumi::tuple{1.4}, kumi::tuple{2.5,-1.6}) "<< kyosu::hypergeometric[kyosu::regularized](2.0,kumi::tuple{1.4}, kumi::tuple{2.5,-1.6}) << std::endl;
std::cout << "hypergeometric[regularized](0.5, kumi::tuple{-5.0, 2.5}, kumi::tuple{-3.0}) "<< kyosu::hypergeometric[kyosu::regularized](0.5,kumi::tuple{-5.0, 2.5}, kumi::tuple{-3.0}) << std::endl;
return 0;
}
constexpr auto complex
Constructs a kyosu::complex_t instance.
Definition: to_complex.hpp:75