// Complex hyperbolic cosine // // DESCRIPTION: // // ccosh(z) = cosh x cos y + i sinh x sin y . // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // IEEE -10,+10 30000 2.9e-16 8.1e-17 // Cosh returns the hyperbolic cosine of x. public static System.Numerics.Complex128 Cosh(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (re == 0L && (math.IsInf(im, 0L) || math.IsNaN(im))) { return(complex(math.NaN(), re * math.Copysign(0L, im))); } else if (math.IsInf(re, 0L)) { if (im == 0L) { return(complex(math.Inf(1L), im * math.Copysign(0L, re))); } else if (math.IsInf(im, 0L) || math.IsNaN(im)) { return(complex(math.Inf(1L), math.NaN())); } else if (im == 0L && math.IsNaN(re)) { return(complex(math.NaN(), im)); } } } var(s, c) = math.Sincos(imag(x)); var(sh, ch) = sinhcosh(real(x)); return(complex(c * ch, s * sh)); }
// Polar returns the absolute value r and phase θ of x, // such that x = r * e**θi. // The phase is in the range [-Pi, Pi]. public static (double, double) Polar(System.Numerics.Complex128 x) { double r = default; double θ = default; return(Abs(x), Phase(x)); }
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex circular sine // // DESCRIPTION: // // If // z = x + iy, // // then // // w = sin x cosh y + i cos x sinh y. // // csin(z) = -i csinh(iz). // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 8400 5.3e-17 1.3e-17 // IEEE -10,+10 30000 3.8e-16 1.0e-16 // Also tested by csin(casin(z)) = z. // Sin returns the sine of x. public static System.Numerics.Complex128 Sin(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (im == 0L && (math.IsInf(re, 0L) || math.IsNaN(re))) { return(complex(math.NaN(), im)); } else if (math.IsInf(im, 0L)) { if (re == 0L) { return(x); } else if (math.IsInf(re, 0L) || math.IsNaN(re)) { return(complex(math.NaN(), im)); } else if (re == 0L && math.IsNaN(im)) { return(x); } } } var(s, c) = math.Sincos(real(x)); var(sh, ch) = sinhcosh(imag(x)); return(complex(s * ch, c * sh)); }
// IsInf reports whether either real(x) or imag(x) is an infinity. public static bool IsInf(System.Numerics.Complex128 x) { if (math.IsInf(real(x), 0L) || math.IsInf(imag(x), 0L)) { return(true); } return(false); }
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex circular arc sine // // DESCRIPTION: // // Inverse complex sine: // 2 // w = -i clog( iz + csqrt( 1 - z ) ). // // casin(z) = -i casinh(iz) // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 10100 2.1e-15 3.4e-16 // IEEE -10,+10 30000 2.2e-14 2.7e-15 // Larger relative error can be observed for z near zero. // Also tested by csin(casin(z)) = z. // Asin returns the inverse sine of x. public static System.Numerics.Complex128 Asin(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (im == 0L && math.Abs(re) <= 1L) { return(complex(math.Asin(re), im)); } else if (re == 0L && math.Abs(im) <= 1L) { return(complex(re, math.Asinh(im))); } else if (math.IsNaN(im)) { if (re == 0L) { return(complex(re, math.NaN())); } else if (math.IsInf(re, 0L)) { return(complex(math.NaN(), re)); } else { return(NaN()); } } else if (math.IsInf(im, 0L)) { if (math.IsNaN(re)) { return(x); } else if (math.IsInf(re, 0L)) { return(complex(math.Copysign(math.Pi / 4L, re), im)); } else { return(complex(math.Copysign(0L, re), im)); } } else if (math.IsInf(re, 0L)) { return(complex(math.Copysign(math.Pi / 2L, re), math.Copysign(re, im))); } } var ct = complex(-imag(x), real(x)); // i * x var xx = x * x; var x1 = complex(1L - real(xx), -imag(xx)); // 1 - x*x var x2 = Sqrt(x1); // x2 = sqrt(1 - x*x) var w = Log(ct + x2); return(complex(imag(w), -real(w))); // -i * w }
// Asinh returns the inverse hyperbolic sine of x. public static System.Numerics.Complex128 Asinh(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (im == 0L && math.Abs(re) <= 1L) { return(complex(math.Asinh(re), im)); } else if (re == 0L && math.Abs(im) <= 1L) { return(complex(re, math.Asin(im))); } else if (math.IsInf(re, 0L)) { if (math.IsInf(im, 0L)) { return(complex(re, math.Copysign(math.Pi / 4L, im))); } else if (math.IsNaN(im)) { return(x); } else { return(complex(re, math.Copysign(0.0F, im))); } } else if (math.IsNaN(re)) { if (im == 0L) { return(x); } else if (math.IsInf(im, 0L)) { return(complex(im, re)); } else { return(NaN()); } } else if (math.IsInf(im, 0L)) { return(complex(math.Copysign(im, re), math.Copysign(math.Pi / 2L, im))); } } var xx = x * x; var x1 = complex(1L + real(xx), imag(xx)); // 1 + x*x return(Log(x + Sqrt(x1))); // log(x + sqrt(1 + x*x)) }
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex circular tangent // // DESCRIPTION: // // If // z = x + iy, // // then // // sin 2x + i sinh 2y // w = --------------------. // cos 2x + cosh 2y // // On the real axis the denominator is zero at odd multiples // of PI/2. The denominator is evaluated by its Taylor // series near these points. // // ctan(z) = -i ctanh(iz). // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 5200 7.1e-17 1.6e-17 // IEEE -10,+10 30000 7.2e-16 1.2e-16 // Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. // Tan returns the tangent of x. public static System.Numerics.Complex128 Tan(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (math.IsInf(im, 0L)) { if (math.IsInf(re, 0L) || math.IsNaN(re)) { return(complex(math.Copysign(0L, re), math.Copysign(1L, im))); } } return(complex(math.Copysign(0L, math.Sin(2L * re)), math.Copysign(1L, im)));
private static System.Numerics.Complex128 complex128div(System.Numerics.Complex128 n, System.Numerics.Complex128 m) { double e = default; double f = default; // complex(e, f) = n/m // Algorithm for robust complex division as described in // Robert L. Smith: Algorithm 116: Complex division. Commun. ACM 5(8): 435 (1962). // complex(e, f) = n/m // Algorithm for robust complex division as described in // Robert L. Smith: Algorithm 116: Complex division. Commun. ACM 5(8): 435 (1962). if (abs(real(m)) >= abs(imag(m))) { var ratio = imag(m) / real(m); var denom = real(m) + ratio * imag(m); e = (real(n) + imag(n) * ratio) / denom; f = (imag(n) - real(n) * ratio) / denom; } else { ratio = real(m) / imag(m); denom = imag(m) + ratio * real(m); e = (real(n) * ratio + imag(n)) / denom; f = (imag(n) * ratio - real(n)) / denom; } if (isNaN(e) && isNaN(f)) { // Correct final result to infinities and zeros if applicable. // Matches C99: ISO/IEC 9899:1999 - G.5.1 Multiplicative operators. var a = real(n); var b = imag(n); var c = real(m); var d = imag(m); if (m == 0L && (!isNaN(a) || !isNaN(b))) { e = copysign(inf, c) * a; } f = copysign(inf, c) * b; else if ((isInf(a) || isInf(b)) && isFinite(c) && isFinite(d)) { a = inf2one(a); } b = inf2one(b); e = inf * (a * c + b * d); f = inf * (b * c - a * d);
// FormatComplex converts the complex number c to a string of the // form (a+bi) where a and b are the real and imaginary parts, // formatted according to the format fmt and precision prec. // // The format fmt and precision prec have the same meaning as in FormatFloat. // It rounds the result assuming that the original was obtained from a complex // value of bitSize bits, which must be 64 for complex64 and 128 for complex128. public static @string FormatComplex(System.Numerics.Complex128 c, byte fmt, long prec, long bitSize) => func((_, panic, __) => { if (bitSize != 64L && bitSize != 128L) { panic("invalid bitSize"); } bitSize >>= 1L; // complex64 uses float32 internally // Check if imaginary part has a sign. If not, add one. var im = FormatFloat(imag(c), fmt, prec, bitSize); if (im[0L] != '+' && im[0L] != '-') { im = "+" + im; } return("(" + FormatFloat(real(c), fmt, prec, bitSize) + im + "i)"); });
// Acosh returns the inverse hyperbolic cosine of x. public static System.Numerics.Complex128 Acosh(System.Numerics.Complex128 x) { if (x == 0L) { return(complex(0L, math.Copysign(math.Pi / 2L, imag(x)))); } var w = Acos(x); if (imag(w) <= 0L) { return(complex(-imag(w), real(w))); // i * w } return(complex(imag(w), -real(w))); // -i * w }
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex exponential function // // DESCRIPTION: // // Returns the complex exponential of the complex argument z. // // If // z = x + iy, // r = exp(x), // then // w = r cos y + i r sin y. // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 8700 3.7e-17 1.1e-17 // IEEE -10,+10 30000 3.0e-16 8.7e-17 // Exp returns e**x, the base-e exponential of x. public static System.Numerics.Complex128 Exp(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (math.IsInf(re, 0L)) { if (re > 0L && im == 0L) { return(x); } else if (math.IsInf(im, 0L) || math.IsNaN(im)) { if (re < 0L) { return(complex(0L, math.Copysign(0L, im))); } else { return(complex(math.Inf(1.0F), math.NaN())); } } else if (math.IsNaN(re)) { if (im == 0L) { return(complex(math.NaN(), im)); } } } } var r = math.Exp(real(x)); var(s, c) = math.Sincos(imag(x)); return(complex(r * c, r * s)); }
// Complex circular arc tangent // // DESCRIPTION: // // If // z = x + iy, // // then // 1 ( 2x ) // Re w = - arctan(-----------) + k PI // 2 ( 2 2) // (1 - x - y ) // // ( 2 2) // 1 (x + (y+1) ) // Im w = - log(------------) // 4 ( 2 2) // (x + (y-1) ) // // Where k is an arbitrary integer. // // catan(z) = -i catanh(iz). // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 5900 1.3e-16 7.8e-18 // IEEE -10,+10 30000 2.3e-15 8.5e-17 // The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, // had peak relative error 1.5e-16, rms relative error // 2.9e-17. See also clog(). // Atan returns the inverse tangent of x. public static System.Numerics.Complex128 Atan(System.Numerics.Complex128 x) { { var re = real(x); var im = imag(x); if (im == 0L) { return(complex(math.Atan(re), im)); } else if (re == 0L && math.Abs(im) <= 1L) { return(complex(re, math.Atanh(im))); } else if (math.IsInf(im, 0L) || math.IsInf(re, 0L)) { if (math.IsNaN(re)) { return(complex(math.NaN(), math.Copysign(0L, im))); } } return(complex(math.Copysign(math.Pi / 2L, re), math.Copysign(0L, im)));
// Log10 returns the decimal logarithm of x. public static System.Numerics.Complex128 Log10(System.Numerics.Complex128 x) { var z = Log(x); return(complex(math.Log10E * real(z), math.Log10E * imag(z))); }
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex natural logarithm // // DESCRIPTION: // // Returns complex logarithm to the base e (2.718...) of // the complex argument z. // // If // z = x + iy, r = sqrt( x**2 + y**2 ), // then // w = log(r) + i arctan(y/x). // // The arctangent ranges from -PI to +PI. // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 7000 8.5e-17 1.9e-17 // IEEE -10,+10 30000 5.0e-15 1.1e-16 // // Larger relative error can be observed for z near 1 +i0. // In IEEE arithmetic the peak absolute error is 5.2e-16, rms // absolute error 1.0e-16. // Log returns the natural logarithm of x. public static System.Numerics.Complex128 Log(System.Numerics.Complex128 x) { return(complex(math.Log(Abs(x)), Phase(x))); }
public complex128(System.Numerics.Complex128 value) => m_value = value;
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex square root // // DESCRIPTION: // // If z = x + iy, r = |z|, then // // 1/2 // Re w = [ (r + x)/2 ] , // // 1/2 // Im w = [ (r - x)/2 ] . // // Cancellation error in r-x or r+x is avoided by using the // identity 2 Re w Im w = y. // // Note that -w is also a square root of z. The root chosen // is always in the right half plane and Im w has the same sign as y. // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 25000 3.2e-17 9.6e-18 // IEEE -10,+10 1,000,000 2.9e-16 6.1e-17 // Sqrt returns the square root of x. // The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x). public static System.Numerics.Complex128 Sqrt(System.Numerics.Complex128 x) { if (imag(x) == 0L) { // Ensure that imag(r) has the same sign as imag(x) for imag(x) == signed zero. if (real(x) == 0L) { return(complex(0L, imag(x))); } if (real(x) < 0L) { return(complex(0L, math.Copysign(math.Sqrt(-real(x)), imag(x)))); } return(complex(math.Sqrt(real(x)), imag(x))); } else if (math.IsInf(imag(x), 0L)) { return(complex(math.Inf(1.0F), imag(x))); } if (real(x) == 0L) { if (imag(x) < 0L) { var r = math.Sqrt(-0.5F * imag(x)); return(complex(r, -r)); } r = math.Sqrt(0.5F * imag(x)); return(complex(r, r)); } var a = real(x); var b = imag(x); double scale = default; // Rescale to avoid internal overflow or underflow. if (math.Abs(a) > 4L || math.Abs(b) > 4L) { a *= 0.25F; b *= 0.25F; scale = 2L; } else { a *= 1.8014398509481984e16F; // 2**54 b *= 1.8014398509481984e16F; scale = 7.450580596923828125e-9F; // 2**-27 } r = math.Hypot(a, b); double t = default; if (a > 0L) { t = math.Sqrt(0.5F * r + 0.5F * a); r = scale * math.Abs((0.5F * b) / t); t *= scale; } else { r = math.Sqrt(0.5F * r - 0.5F * a); t = scale * math.Abs((0.5F * b) / r); r *= scale; } if (b < 0L) { return(complex(t, -r)); } return(complex(t, r)); }
// Complex circular arc cosine // // DESCRIPTION: // // w = arccos z = PI/2 - arcsin z. // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // DEC -10,+10 5200 1.6e-15 2.8e-16 // IEEE -10,+10 30000 1.8e-14 2.2e-15 // Acos returns the inverse cosine of x. public static System.Numerics.Complex128 Acos(System.Numerics.Complex128 x) { var w = Asin(x); return(complex(math.Pi / 2L - real(w), -imag(w))); }
// Abs returns the absolute value (also called the modulus) of x. public static double Abs(System.Numerics.Complex128 x) { return(math.Hypot(real(x), imag(x))); }
// Phase returns the phase (also called the argument) of x. // The returned value is in the range [-Pi, Pi]. public static double Phase(System.Numerics.Complex128 x) { return(math.Atan2(imag(x), real(x))); }
private static void argcomplex(complex64 x, System.Numerics.Complex128 y) ;
// Conj returns the complex conjugate of x. public static System.Numerics.Complex128 Conj(System.Numerics.Complex128 x) { return(complex(real(x), -imag(x))); }
// The original C code, the long comment, and the constants // below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. // The go code is a simplified version of the original C. // // Cephes Math Library Release 2.8: June, 2000 // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier // // The readme file at http://netlib.sandia.gov/cephes/ says: // Some software in this archive may be from the book _Methods and // Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster // International, 1989) or from the Cephes Mathematical Library, a // commercial product. In either event, it is copyrighted by the author. // What you see here may be used freely but it comes with no support or // guarantee. // // The two known misprints in the book are repaired here in the // source listings for the gamma function and the incomplete beta // integral. // // Stephen L. Moshier // [email protected] // Complex power function // // DESCRIPTION: // // Raises complex A to the complex Zth power. // Definition is per AMS55 # 4.2.8, // analytically equivalent to cpow(a,z) = cexp(z clog(a)). // // ACCURACY: // // Relative error: // arithmetic domain # trials peak rms // IEEE -10,+10 30000 9.4e-15 1.5e-15 // Pow returns x**y, the base-x exponential of y. // For generalized compatibility with math.Pow: // Pow(0, ±0) returns 1+0i // Pow(0, c) for real(c)<0 returns Inf+0i if imag(c) is zero, otherwise Inf+Inf i. public static System.Numerics.Complex128 Pow(System.Numerics.Complex128 x, System.Numerics.Complex128 y) => func((_, panic, __) =>
public NumberNode(NodeType NodeType = default, Pos Pos = default, ref ptr <Tree> tr = default, bool IsInt = default, bool IsUint = default, bool IsFloat = default, bool IsComplex = default, long Int64 = default, ulong Uint64 = default, double Float64 = default, System.Numerics.Complex128 Complex128 = default, @string Text = default) { this.NodeType = NodeType; this.Pos = Pos; this.tr = tr; this.IsInt = IsInt; this.IsUint = IsUint; this.IsFloat = IsFloat; this.IsComplex = IsComplex; this.Int64 = Int64; this.Uint64 = Uint64; this.Float64 = Float64; this.Complex128 = Complex128; this.Text = Text; }