|
|
|
@ -14,6 +14,7 @@ namespace MathNet.Numerics |
|
|
|
{ |
|
|
|
#region AiryAi
|
|
|
|
|
|
|
|
// Returns Ai(z)
|
|
|
|
public Complex Cairy(Complex z) |
|
|
|
{ |
|
|
|
int id = 0; |
|
|
|
@ -29,6 +30,44 @@ namespace MathNet.Numerics |
|
|
|
return new Complex(air, aii); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(zta) * Ai(z) where zta = (2/3) * z * Sqrt(z)
|
|
|
|
public Complex ScaledCairy(Complex z) |
|
|
|
{ |
|
|
|
int id = 0; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double air = double.NaN; |
|
|
|
double aii = double.NaN; |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zairy(z.Real, z.Imaginary, id, kode, ref air, ref aii, ref nz, ref ierr); |
|
|
|
return new Complex(air, aii); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(zta) * Ai(z) where zta = (2/3) * z * Sqrt(z)
|
|
|
|
public double ScaledCairy(double z) |
|
|
|
{ |
|
|
|
if (z < 0) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
int id = 0; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double air = double.NaN; |
|
|
|
double aii = double.NaN; |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zairy(z, 0.0, id, kode, ref air, ref aii, ref nz, ref ierr); |
|
|
|
return air; |
|
|
|
} |
|
|
|
|
|
|
|
// Returns d/dz Ai(z)
|
|
|
|
public Complex CairyPrime(Complex z) |
|
|
|
{ |
|
|
|
int id = 1; |
|
|
|
@ -44,10 +83,48 @@ namespace MathNet.Numerics |
|
|
|
return new Complex(air, aii); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(zta) * d/dz Ai(z) where zta = (2/3) * z * Sqrt(z)
|
|
|
|
public Complex ScaledCairyPrime(Complex z) |
|
|
|
{ |
|
|
|
int id = 1; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double air = double.NaN; |
|
|
|
double aii = double.NaN; |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zairy(z.Real, z.Imaginary, id, kode, ref air, ref aii, ref nz, ref ierr); |
|
|
|
return new Complex(air, aii); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(zta) * d/dz Ai(z) where zta = (2/3) * z * Sqrt(z)
|
|
|
|
public double ScaledCairyPrime(double z) |
|
|
|
{ |
|
|
|
if (z < 0) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
int id = 1; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double air = double.NaN; |
|
|
|
double aii = double.NaN; |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zairy(z, 0.0, id, kode, ref air, ref aii, ref nz, ref ierr); |
|
|
|
return air; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region AiryBi
|
|
|
|
|
|
|
|
// Returns Bi(z)
|
|
|
|
public Complex Cbiry(Complex z) |
|
|
|
{ |
|
|
|
int id = 0; |
|
|
|
@ -63,6 +140,23 @@ namespace MathNet.Numerics |
|
|
|
return new Complex(bir, bii); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(-axzta) * Bi(z) where zta = (2 / 3) * z * Sqrt(z) and axzta = Abs(zta.Real)
|
|
|
|
public Complex ScaledCbiry(Complex z) |
|
|
|
{ |
|
|
|
int id = 0; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double bir = double.NaN; |
|
|
|
double bii = double.NaN; |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zbiry(z.Real, z.Imaginary, id, kode, ref bir, ref bii, ref nz, ref ierr); |
|
|
|
return new Complex(bir, bii); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns d/dz Bi(z)
|
|
|
|
public Complex CbiryPrime(Complex z) |
|
|
|
{ |
|
|
|
int id = 1; |
|
|
|
@ -78,10 +172,27 @@ namespace MathNet.Numerics |
|
|
|
return new Complex(bipr, bipi); |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(-axzta) * d/dz Bi(z) where zta = (2 / 3) * z * Sqrt(z) and axzta = Abs(zta.Real)
|
|
|
|
public Complex ScaledCbiryPrime(Complex z) |
|
|
|
{ |
|
|
|
int id = 1; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double bipr = double.NaN; |
|
|
|
double bipi = double.NaN; |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zbiry(z.Real, z.Imaginary, id, kode, ref bipr, ref bipi, ref nz, ref ierr); |
|
|
|
return new Complex(bipr, bipi); |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region BesselJ
|
|
|
|
|
|
|
|
// Return J(v, z)
|
|
|
|
public Complex Cbesj(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
@ -115,7 +226,7 @@ namespace MathNet.Numerics |
|
|
|
if (ierr == 2) |
|
|
|
{ |
|
|
|
//overflow
|
|
|
|
cyj = CbesjScaled(v, z); |
|
|
|
cyj = ScaledCbesj(v, z); |
|
|
|
cyj = new Complex(cyj.Real * double.PositiveInfinity, cyj.Imaginary * double.PositiveInfinity); |
|
|
|
} |
|
|
|
|
|
|
|
@ -145,7 +256,19 @@ namespace MathNet.Numerics |
|
|
|
return cyj; |
|
|
|
} |
|
|
|
|
|
|
|
private Complex CbesjScaled(double v, Complex z) |
|
|
|
// Return J(v, z)
|
|
|
|
public double Cbesj(double v, double z) |
|
|
|
{ |
|
|
|
if (z < 0 && v != (int)v) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
return Cbesj(v, new Complex(z, 0)).Real; |
|
|
|
} |
|
|
|
|
|
|
|
// Return Exp(-Abs(y)) * J(v, z) where y = z.Imaginary
|
|
|
|
public Complex ScaledCbesj(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
{ |
|
|
|
@ -201,10 +324,22 @@ namespace MathNet.Numerics |
|
|
|
return cyj; |
|
|
|
} |
|
|
|
|
|
|
|
// Return Exp(-Abs(y)) * J(v, z) where y = z.Imaginary
|
|
|
|
public double ScaledCbesj(double v, double z) |
|
|
|
{ |
|
|
|
if (z < 0 && v != (int)v) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
return ScaledCbesj(v, new Complex(z, 0)).Real; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region BesselY
|
|
|
|
|
|
|
|
// Return Y(v, z)
|
|
|
|
public Complex Cbesy(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
@ -279,7 +414,8 @@ namespace MathNet.Numerics |
|
|
|
return cyy; |
|
|
|
} |
|
|
|
|
|
|
|
public double CbesyReal(double v, double x) |
|
|
|
// Return Y(v, z)
|
|
|
|
public double Cbesy(double v, double x) |
|
|
|
{ |
|
|
|
if (x < 0.0) |
|
|
|
{ |
|
|
|
@ -290,10 +426,87 @@ namespace MathNet.Numerics |
|
|
|
return Cbesy(v, z).Real; |
|
|
|
} |
|
|
|
|
|
|
|
// Return Exp(-Abs(y)) * Y(v, z) where y = z.Imaginary
|
|
|
|
public Complex ScaledCbesy(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
{ |
|
|
|
return new Complex(double.NaN, double.NaN); |
|
|
|
} |
|
|
|
|
|
|
|
int sign = 1; |
|
|
|
if (v < 0) |
|
|
|
{ |
|
|
|
v = -v; |
|
|
|
sign = -1; |
|
|
|
} |
|
|
|
|
|
|
|
int n = 1; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double[] cyyr = new double[n]; |
|
|
|
double[] cyyi = new double[n]; |
|
|
|
double[] cwrkr = new double[n]; |
|
|
|
double[] cwrki = new double[n]; |
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
cyyr[i] = double.NaN; |
|
|
|
cyyi[i] = double.NaN; |
|
|
|
cwrkr[i] = double.NaN; |
|
|
|
cwrki[i] = double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zbesy(z.Real, z.Imaginary, v, kode, n, cyyr, cyyi, ref nz, cwrkr, cwrki, ref ierr); |
|
|
|
Complex cyy = new Complex(cyyr[0], cyyi[0]); |
|
|
|
|
|
|
|
if (ierr == 2) |
|
|
|
{ |
|
|
|
if (z.Real >= 0 && z.Imaginary == 0) |
|
|
|
{ |
|
|
|
//overflow
|
|
|
|
cyy = new Complex(double.PositiveInfinity, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (sign == -1) |
|
|
|
{ |
|
|
|
if (!ReflectJY(ref cyy, v)) |
|
|
|
{ |
|
|
|
double[] cyjr = new double[n]; |
|
|
|
double[] cyji = new double[n]; |
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
cyjr[i] = double.NaN; |
|
|
|
cyji[i] = double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
amos.zbesj(z.Real, z.Imaginary, v, kode, n, cyjr, cyji, ref nz, ref ierr); |
|
|
|
Complex cyj = new Complex(cyjr[0], cyji[0]); |
|
|
|
cyy = RotateJY(cyy, cyj, -v); |
|
|
|
} |
|
|
|
} |
|
|
|
return cyy; |
|
|
|
} |
|
|
|
|
|
|
|
// Return Exp(-Abs(y)) * Y(v, z) where y = z.Imaginary
|
|
|
|
public double ScaledCbesy(double v, double x) |
|
|
|
{ |
|
|
|
if (x < 0) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
return ScaledCbesy(v, new Complex(x, 0)).Real; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region BesselI
|
|
|
|
|
|
|
|
// Returns I(v, z)
|
|
|
|
public Complex Cbesi(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
@ -337,7 +550,7 @@ namespace MathNet.Numerics |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
cyi = CbesiScaled(v * sign, z); |
|
|
|
cyi = ScaledCbesi(v * sign, z); |
|
|
|
cyi = new Complex(cyi.Real * double.PositiveInfinity, cyi.Imaginary * double.PositiveInfinity); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -358,7 +571,8 @@ namespace MathNet.Numerics |
|
|
|
return cyi; |
|
|
|
} |
|
|
|
|
|
|
|
private Complex CbesiScaled(double v, Complex z) |
|
|
|
// Return Exp(-Abs(x)) * I(v, z) where x = z.Real
|
|
|
|
public Complex ScaledCbesi(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
{ |
|
|
|
@ -412,10 +626,22 @@ namespace MathNet.Numerics |
|
|
|
return cyi; |
|
|
|
} |
|
|
|
|
|
|
|
// Return Exp(-Abs(x)) * I(v, z) where x = z.Real
|
|
|
|
public double ScaledCbesi(double v, double x) |
|
|
|
{ |
|
|
|
if (v != Math.Floor(v) && x < 0) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
return ScaledCbesi(v, new Complex(x, 0)).Real; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region BesselK
|
|
|
|
|
|
|
|
// Returns K(v, z)
|
|
|
|
public Complex Cbesk(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
@ -463,8 +689,9 @@ namespace MathNet.Numerics |
|
|
|
|
|
|
|
return cyk; |
|
|
|
} |
|
|
|
|
|
|
|
public double CbeskReal(double v, double z) |
|
|
|
|
|
|
|
// Returns K(v, z)
|
|
|
|
public double Cbesk(double v, double z) |
|
|
|
{ |
|
|
|
if (z < 0) |
|
|
|
{ |
|
|
|
@ -489,10 +716,73 @@ namespace MathNet.Numerics |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// returns Exp(z) * K(v, z)
|
|
|
|
public Complex ScaledCbesk(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
{ |
|
|
|
return new Complex(double.NaN, double.NaN); |
|
|
|
} |
|
|
|
|
|
|
|
if (v < 0) |
|
|
|
{ |
|
|
|
//K_v == K_{-v} even for non-integer v
|
|
|
|
v = -v; |
|
|
|
} |
|
|
|
|
|
|
|
int n = 1; |
|
|
|
int kode = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double[] cykr = new double[n]; |
|
|
|
double[] cyki = new double[n]; |
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
cykr[i] = double.NaN; |
|
|
|
cyki[i] = double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
|
|
|
|
amos.zbesk(z.Real, z.Imaginary, v, kode, n, cykr, cyki, ref nz, ref ierr); |
|
|
|
Complex cyk = new Complex(cykr[0], cyki[0]); |
|
|
|
|
|
|
|
if (ierr == 2) |
|
|
|
{ |
|
|
|
if (z.Real >= 0 && z.Imaginary == 0) |
|
|
|
{ |
|
|
|
//overflow
|
|
|
|
cyk = new Complex(double.PositiveInfinity, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return cyk; |
|
|
|
} |
|
|
|
|
|
|
|
// returns Exp(z) * K(v, z)
|
|
|
|
public double ScaledCbesk(double v, double z) |
|
|
|
{ |
|
|
|
if (z < 0) |
|
|
|
{ |
|
|
|
return double.NaN; |
|
|
|
} |
|
|
|
else if (z == 0) |
|
|
|
{ |
|
|
|
return double.PositiveInfinity; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Complex w = new Complex(z, 0); |
|
|
|
return ScaledCbesk(v, w).Real; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region HankelH1
|
|
|
|
|
|
|
|
// Returns H1(v, z)
|
|
|
|
public Complex Cbesh1(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
@ -533,10 +823,52 @@ namespace MathNet.Numerics |
|
|
|
return cyh; |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(-z * j) * H1(n, z) where j = Sqrt(-1)
|
|
|
|
public Complex ScaledCbesh1(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
{ |
|
|
|
return new Complex(double.NaN, double.NaN); ; |
|
|
|
} |
|
|
|
|
|
|
|
int n = 1; |
|
|
|
int kode = 2; |
|
|
|
int m = 1; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double[] cyhr = new double[n]; |
|
|
|
double[] cyhi = new double[n]; |
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
cyhr[i] = double.NaN; |
|
|
|
cyhi[i] = double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
int sign = 1; |
|
|
|
if (v < 0) |
|
|
|
{ |
|
|
|
v = -v; |
|
|
|
sign = -1; |
|
|
|
} |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zbesh(z.Real, z.Imaginary, v, kode, m, n, cyhr, cyhi, ref nz, ref ierr); |
|
|
|
Complex cyh = new Complex(cyhr[0], cyhi[0]); |
|
|
|
|
|
|
|
if (sign == -1) |
|
|
|
{ |
|
|
|
cyh = Rotate(cyh, v); |
|
|
|
} |
|
|
|
|
|
|
|
return cyh; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region HankelH2
|
|
|
|
|
|
|
|
// Returns H2(v, z)
|
|
|
|
public Complex Cbesh2(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
@ -581,6 +913,51 @@ namespace MathNet.Numerics |
|
|
|
return cyh; |
|
|
|
} |
|
|
|
|
|
|
|
// Returns Exp(z * j) * H2(n, z) where j = Sqrt(-1)
|
|
|
|
public Complex ScaledCbesh2(double v, Complex z) |
|
|
|
{ |
|
|
|
if (double.IsNaN(v) || double.IsNaN(z.Real) || double.IsNaN(z.Imaginary)) |
|
|
|
{ |
|
|
|
return new Complex(double.NaN, double.NaN); |
|
|
|
} |
|
|
|
|
|
|
|
if (v == 0 && z.Real == 0 && z.Imaginary == 0) |
|
|
|
{ |
|
|
|
return new Complex(double.NaN, double.NaN); // ComplexInfinity
|
|
|
|
} |
|
|
|
|
|
|
|
int n = 1; |
|
|
|
int kode = 2; |
|
|
|
int m = 2; |
|
|
|
int nz = 0; |
|
|
|
int ierr = 0; |
|
|
|
|
|
|
|
double[] cyhr = new double[n]; |
|
|
|
double[] cyhi = new double[n]; |
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
cyhr[i] = double.NaN; |
|
|
|
cyhi[i] = double.NaN; |
|
|
|
} |
|
|
|
|
|
|
|
int sign = 1; |
|
|
|
if (v < 0) |
|
|
|
{ |
|
|
|
v = -v; |
|
|
|
sign = -1; |
|
|
|
} |
|
|
|
|
|
|
|
var amos = new AmosHelper(); |
|
|
|
amos.zbesh(z.Real, z.Imaginary, v, kode, m, n, cyhr, cyhi, ref nz, ref ierr); |
|
|
|
Complex cyh = new Complex(cyhr[0], cyhi[0]); |
|
|
|
|
|
|
|
if (sign == -1) |
|
|
|
{ |
|
|
|
cyh = Rotate(cyh, -v); |
|
|
|
} |
|
|
|
return cyh; |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region utilities
|
|
|
|
|