...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-typejacobi_theta4(T x, U q); template <class T, class U, class Policy>calculated-result-typejacobi_theta4(T x, U q, const Policy&); template <class T, class U>calculated-result-typejacobi_theta4tau(T x, U tau); template <class T, class U, class Policy>calculated-result-typejacobi_theta4tau(T x, U tau, const Policy&); template <class T, class U>calculated-result-typejacobi_theta4m1(T x, U q); template <class T, class U, class Policy>calculated-result-typejacobi_theta4m1(T x, U q, const Policy&); template <class T, class U>calculated-result-typejacobi_theta4m1tau(T x, U tau); template <class T, class U, class Policy>calculated-result-typejacobi_theta4m1tau(T x, U tau, const Policy&); }} // namespaces

The functions calculate the value of fourth 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.

A second quartet of functions (functions containing `m1`

)
compute one less than the value of the fourth theta function. These versions
of the functions provide increased accuracy when the result is close to unity.

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
θ_{4}=1.

Fixing *x*=5 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.33 is used, defining τ'=-1/τ:

This transformation of variables ensures that the function will always converge in a small number of iterations.