5
$\begingroup$

I googled about some code on the complex polygamma function especially C++ code, but can't find anything. Does anyone know where to find such code?

The complex digamma function does exist but not the complex polygamma function.

$\endgroup$
1
  • $\begingroup$ Boost has a special functions module. The documentation does not specifically mention if it supports complex arguments, but the signature is: template <class T> calculated-result-type polygamma(int n, T z); which leads me to believe that z could be complex. boost.org/doc/libs/1_75_0/libs/math/doc/html/math_toolkit/… $\endgroup$
    – Charlie S
    Commented Dec 17, 2020 at 18:57

2 Answers 2

10
$\begingroup$

I implemented a complex polygamma function in the Julia standard library (https://github.com/JuliaLang/julia/pull/7125). It is possible to call this from C++ by linking to the libjulia library.

The easiest way to do this is to call Julia's @cfunction construct to get a C/C++ function pointer to the compiled function. Then you can call it normally like any other C++ function.

In particular (1) download and install Julia, (2) launch Julia and use its package manager to add SpecialFunctions (to install the Julia SpecialFunctions.jl package that now contains my polygamma code), (3) compile your C++ code linked with libjulia. For example, the following C++ program loads Julia and gets a C++ function pointer polygamma to call the Julia polygamma function on std::complex<double>:

#include <julia.h>
JULIA_DEFINE_FAST_TLS() // only define this once, in an executable (not in a shared library) if you want fast code.

#include <complex>
typedef std::complex<double> (*polygamma_ptr)(int m, std::complex<double> z);
polygamma_ptr polygamma = NULL;

#include <iostream>

int main(int argc, char *argv[])
{
    jl_init();

    // get a C function pointer to the Julia polygamma function compiled for
    // (int, complex<double>) arguments:
    jl_eval_string("import SpecialFunctions");
    jl_value_t *ret = jl_eval_string("@cfunction(SpecialFunctions.polygamma, ComplexF64, (Cint, ComplexF64))");
    polygamma = (polygamma_ptr) jl_unbox_voidpointer(ret);

    // example: call polygamma(3, 1.7+4.2i) and output it.
    std::cout << "polygamma(3, 1.7+4.2i) = " << polygamma(3, std::complex<double>(1.7, 4.2)) << "\n";

    jl_atexit_hook(0);
    return 0;
}

The output is polygamma(3, 1.7+4.2i) = (-0.0184344,0.0162077).

$\endgroup$
2
  • $\begingroup$ is there any template how to incorporate these special functions in C++? I have looked into the manual and also some questions related to it in stackexchange but no answer. $\endgroup$
    – BabaYaga
    Commented Dec 16, 2020 at 13:57
  • 1
    $\begingroup$ The easiest way is to call Julia and use it's @cfunction construct to get a C/C++ function pointer to the compiled function. Then you can call it normally like any other C++ function. $\endgroup$
    – SGJ
    Commented Dec 17, 2020 at 17:54
5
$\begingroup$

Looking at what the python scipy library does for its special functions, the polygamma is found by returning the digamma if the zeroth derivative is requested, otherwise return $(-1)^{n+1}\Gamma(n+1)\zeta(n+1,z)$ where $\Gamma$ is the gamma function and $\zeta$ the two argument Riemann zeta function. Assuming that this identity holds for the complex numbers, it may explain why you can't find any explicit code.

In fact to add a reference, this is also the method used in the gnu implementation of libstdc++, see here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.