...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
#include <boost/math/special_functions/jacobi_theta.hpp>
namespace boost { namespace math { template <class T, class U> calculated-result-type jacobi_theta2(T x, U q); template <class T, class U, class Policy> calculated-result-type jacobi_theta2(T x, U q, const Policy&); template <class T, class U> calculated-result-type jacobi_theta2tau(T x, U tau); template <class T, class U, class Policy> calculated-result-type jacobi_theta2tau(T x, U tau, const Policy&); }} // namespaces
The functions calculate the value of second Jacobi Theta function, parameterized either in terms of the nome q:
Or in terms of an imaginary τ:
The nome q is restricted to the domain (0, 1), returning the result of domain_error otherwise. The following graph shows the theta function at various values of q:
The final Policy argument is optional and can be used to control the behaviour of the function: how it handles errors, what level of precision to use etc. Refer to the policy documentation for more details.
The following ULPs plot is representative, fixing q=0.5 and varying x from 0 to 2π:
The envelope represents the function's condition number. Note that relative accuracy degenerates periodically near θ2=0.
Fixing x=0.4 and varying q, the ULPs plot looks like:
Accuracy tends to degenerate near q=1 (small τ).
The q parameterization is implemented using the τ parameterization, where τ=-log(q)/π.
If τ is greater than or equal to 1, the summation above is used as-is. However if τ < 1, the following identity DLMF 20.7.31 is used, defining τ'=-1/τ:
This transformation of variables ensures that the function will always converge in a small number of iterations.