Dear all,
I have a question. I am a new Root User and I have to implement a code where I need to calculate complex function on complex number. How can I define a complex function in Root? I have tried with TComplex with something like
TF1 *fp = new TF1 (“fp”, “cos(x)+x**TComplex::I()”, 0., 10.);
or
fa1=new TF1(“fa1”, “TComplex(cos(x),x)”, 0, 10);
but it didn’t work. There are rapid method or I need to write a new code?
Thank you,
Eleonora
[code]#include
#include
#include
std::complex MyFunc(double x) // cos(x) + x^i (note: x >= 0)
{
std::complex v(0.0);
if (x == 0.0) return std::complex(1.0, 0.0);
if (x < 0.0) std::cout << “Error : ‘x’ MUST NOT be negative!” << std::endl;
else v = std::complex( std::cos(x) + std::cos(std::log(x)),
std::sin(std::log(x)) );
return v;
}[/code]
Hi,
Thank you very much for the reply. For know if I have understand, in this way you have used a mathematical identity
cos(x)+ix=cos(x)+cos(log(x))+isin(log(x))= cos(x)+exp(i^log(x))?
and so I can use only x>=0 because of the log, right?
In your original post, in the “fp” function, I can see “xTComplex::I()", that is "xi”, that is “x^i”.
Hi,
Sorry, in copy and paste I have posted the wrong function!
Thank you for the reply!
Eleonora
[code]#include
#include
std::complex MyFunc(double x) // cos(x) + x*i
{ return std::complex( std::cos(x), x ); }[/code]
Probably a stupid question. What if I want the same function but on complex number? I have tried
std::complex MyFunc3(complex x)
{ return std::complex( std::cos(x), x ); }
but it doesn’t work: “Symbol null is not defined in current scope”…
[code]#include
std::complex MyFunc(std::complex x) // cos(x) + x*i
{ return std::cos(x) + x * std::complex(0.0, 1.0); }[/code]
See also:
- Complex numbers library - header reference @ cplusplus.com
- C numerics library - header reference @ cplusplus.com
I need to definite the Hankel function, that can be written with the Bessel function JBessel and the Neuman function yNeuman:
h1_n(x)=j_n(x)+i*y_n(x),
so h1 is my complex function.
I have written code in different way but I can’t find the right mode.
In this case I have tried only with the first component,
std::complex Hankel0(std::complex x)
{
gSystem->Load(“libMathMore”);
TF1* jBessel0= new TF1(“J_0”, “ROOT::Math::sph_bessel(0,x)”, 0, 10);
TF1* yBessel0= new TF1(“J_0”, “ROOT::Math::sph_neumann(0,x)”, 0, 10);
return jBessel0 + yBessel0* std::complex(0.0, 1.0);
}
but it didn’t work. Where I am wrong? Thank you for the patience
Create a “Hankel0.cxx” file: [code]#include “Math/SpecFunc.h”
#include
#include
// sph_bessel(0, x) + i * sph_neumann(0, x)
std::complex Hankel0(double x) // note: x > 0
{
std::complex v(0.0);
if (x <= 0.0) std::cout << “Error : ‘x’ MUST be positive!” << std::endl;
else v = std::complex( ROOT::Math::sph_bessel(0, x),
ROOT::Math::sph_neumann(0, x) );
return v;
}[/code] and then try:
root [0] #include
root [1] gSystem->Load(“libMathMore”);
root [2] .L Hankel0.cxx++
root [3] std::cout << Hankel0(1.0) << std::endl;
See also:
ROOT Mathematical Libraries - Special functions
Hi,
I have defined the PsiBessel jBessel*x function that works on real numbers
double psiBessel0(double x)
{return ROOT::Math::sph_bessel(0, x)*x;}
but I need also a PsiBessel that works on complex number, so I defined
std::complex psiBessel0C(std::complex x)
{return ROOT::Math::sph_bessel(0, x)* x * std::complex(0.0, 1.0);}
but It didn’t work and I don’t understand why.
And when you check the description of the “ROOT::Math::sph_bessel”, can you find any function prototype that accepts “complex” variables (and/or returns “complex” results)?
I find this
spherical Bessel functions of the first kind
double sph_bessel(unsigned n, double x)
{
return gsl_sf_bessel_jl(n, x);
}
So you think that maybe this function in root is defined only on real numbers?
Thank for the link: I have checked, I need the Spherical Bessel of the first and second kind, so I can write also the Spherical Hankel of the first kind. Sorry for my ignorance but I known very little of root or C++: so these in ROOT::Math are defined on double so I can use them only on real number., and If I need to use them on complex I have to define the function (for example using the spherical definition of orders 0 … 3 expressed in elementary functions), Right?
I would try to proceed this way.
One needs to take care of some “pathological” cases when Re(x) and/or Im(x) are equal to 0 (for example one needs to identify terms in form “sin(some_real_value)/some_real_value” and “1/some_real_value”, which need to be taken care of -> you could also rewrite all equations using explicit separation of their “real” and “imaginary” parts, perform calculations on two “real values” and then “combine” the results into a single “complex” number).
Maybe Lorenzo has any better idea.
[code]#include
#include
#include
double SinXOverX(const double x) // = sin(x) / x
{
if (std::fabs(x) < 1e-7) return 1.0 - x * x / 6.0;
return std::sin(x) / x;
}
double CosXOverX(const double x) // = cos(x) / x
{
if (std::fabs(x) < 1e-7) {
if (std::fabs(x) < 1e-300) {
std::cout << “CosXOverX : calculations went amok?” << std::endl;
if (x < 0.0) return -1e300;
return 1e300;
}
return 1.0 / x - x / 2.0;
}
return std::cos(x) / x;
}
// Spherical Bessel Function of the First Kind (order 0)
// http://mathworld.wolfram.com/SphericalBesselFunctionoftheFirstKind.html
std::complex SBesselF0(std::complex x) // = sin(x) / x
{
if (x.imag() == 0.0) return std::complex(SinXOverX(x.real()), 0.0);
return std::sin(x) / x;
}
// PsiSBesselF0 = x * SBesselF0(x)
std::complex PsiSBesselF0(std::complex x) // = sin(x)
{
return std::sin(x);
}
// Spherical Bessel Function of the Second Kind (order 0)
// http://mathworld.wolfram.com/SphericalBesselFunctionoftheSecondKind.html
std::complex SBesselS0(std::complex x) // = - cos(x) / x
{
if (x.imag() == 0.0) return std::complex(-CosXOverX(x.real()), 0.0);
return (-std::cos(x) / x);
}
// PsiSBesselS0 = x * SBesselS0(x)
std::complex PsiSBesselS0(std::complex x) // = - cos(x)
{
return (-std::cos(x));
}
// Spherical Hankel Function of the First Kind (order 0)
// http://mathworld.wolfram.com/SphericalHankelFunctionoftheFirstKind.html
std::complex SHankelF0(std::complex x) // = -i * exp(i * x) / x
{
static const std::complex I(0.0, 1.0);
if (x.imag() == 0.0) return std::complex( SinXOverX(x.real()),
-CosXOverX(x.real()) );
return std::conj(I) * std::exp(I * x) / x;
}
// PsiSHankelF0 = x * SHankelF0(x)
std::complex PsiSHankelF0(std::complex x) // = -i * exp(i * x)
{
static const std::complex I(0.0, 1.0);
return std::conj(I) * std::exp(I * x);
}[/code]