コード例 #1
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //atan(x) = i/2*ln( (i+x)/ (i-x))
        public static Complex atan(object x)
        {
            Complex num = GetComplexNum(x);
            Complex i   = Complex.ImaginaryOne;

            return(i * 0.5 * (log(i + num) - log(i - num)));
        }
コード例 #2
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //asin(x) = -i*ln( i*x + (1-x*x)^1/2)
        public static Complex asin(object x)
        {
            Complex num = GetComplexNum(x);

            double a    = MathUtils.Hypot(num.Real + 1.0, num.Imaginary());
            double b    = MathUtils.Hypot(num.Real - 1.0, num.Imaginary());
            double c    = 0.5 * (a + b);
            double real = Math.Asin(0.5 * (a - b));
            double imag = Math.Log(c + Math.Sqrt(c + 1) * Math.Sqrt(c - 1));

            return(new Complex(real, num.Imaginary() >= 0 ? imag : -imag));
        }
コード例 #3
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        private static double GetAngle(Complex num)
        {
            if (IsNaN(num))
            {
                return(double.NaN);
            }

            if (double.IsPositiveInfinity(num.Real))
            {
                if (double.IsPositiveInfinity(num.Imaginary()))
                {
                    return(Math.PI * 0.25);
                }
                else if (double.IsNegativeInfinity(num.Imaginary()))
                {
                    return(Math.PI * -0.25);
                }
                else
                {
                    return(0.0);
                }
            }

            if (double.IsNegativeInfinity(num.Real))
            {
                if (double.IsPositiveInfinity(num.Imaginary()))
                {
                    return(Math.PI * 0.75);
                }
                else if (double.IsNegativeInfinity(num.Imaginary()))
                {
                    return(Math.PI * -0.75);
                }
                else
                {
                    return(DoubleOps.Sign(num.Imaginary()) * Math.PI);
                }
            }

            if (num.Real == 0.0)
            {
                if (num.Imaginary() != 0.0)
                {
                    return(Math.PI * 0.5 * Math.Sign(num.Imaginary()));
                }
                else
                {
                    return((DoubleOps.IsPositiveZero(num.Real) ? 0.0 : Math.PI) * DoubleOps.Sign(num.Imaginary()));
                }
            }

            return(Math.Atan2(num.Imaginary(), num.Real));
        }
コード例 #4
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static PythonTuple polar(object x)
        {
            Complex num = GetComplexNum(x);

            double[] res = new double[] { num.Abs(), GetAngle(num) };

            // check for overflow
            if (double.IsInfinity(res[0]) && !IsInfinity(num))
            {
                throw PythonOps.OverflowError("math range error");
            }

            return(new PythonTuple(res));
        }
コード例 #5
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //asin(x) = ln( x + (x*x +1)^1/2)
        public static Complex asinh(object x)
        {
            Complex num = GetComplexNum(x);

            if (num.IsZero())
            {
                // preserve -0.0 imag component
                return(MathUtils.MakeImaginary(num.Imaginary()));
            }

            Complex recip = 1 / num;

            return(log(num) + log(1 + sqrt(recip * recip + 1)));
        }
コード例 #6
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //ln(re^iO) = ln(r) + iO
        public static Complex log(object x)
        {
            Complex num = GetComplexNum(x);

            if (num.IsZero())
            {
                throw PythonOps.ValueError("math domain error");
            }

            double r, theta;

            r     = num.Abs();
            theta = GetAngle(num);

            return(new Complex(Math.Log(r), theta));
        }
コード例 #7
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static Complex tanh(object x)
        {
            Complex num = GetComplexNum(x);

            // limit as num.Real -> Infinity
            if (double.IsPositiveInfinity(num.Real))
            {
                return(Complex.One);
            }

            // limit as num.Real -> -Infinity
            if (double.IsNegativeInfinity(num.Real))
            {
                return(new Complex(-1.0, 0.0));
            }

            return(sinh(num) / cosh(num));
        }
コード例 #8
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static Complex tan(object x)
        {
            Complex num = GetComplexNum(x);

            // limit as num.Imaginary() -> Infinity
            if (double.IsPositiveInfinity(num.Imaginary()))
            {
                return(Complex.ImaginaryOne);
            }

            // limit as num.Imaginary() -> -Infinity
            if (double.IsNegativeInfinity(num.Imaginary()))
            {
                return(new Complex(0.0, -1.0));
            }

            return(sin(num) / cos(num));
        }
コード例 #9
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static Complex sqrt(object x)
        {
            Complex num = GetComplexNum(x);

            if (num.Imaginary() == 0.0)
            {
                if (num.Real >= 0.0)
                {
                    return(MathUtils.MakeReal(Math.Sqrt(num.Real)));
                }
                else
                {
                    return(MathUtils.MakeImaginary(Math.Sqrt(-num.Real)));
                }
            }

            double c    = num.Abs() + num.Real;
            double real = Math.Sqrt(0.5 * c);
            double imag = num.Imaginary() / Math.Sqrt(2 * c);

            return(new Complex(real, imag));
        }
コード例 #10
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //sin(a+ ib) = sina*coshb + i*cosa*sinhb
        public static Complex sin(object x)
        {
            Complex num = GetComplexNum(x);

            // magnitude is always NaN
            if (double.IsNaN(num.Imaginary()))
            {
                return(new Complex(double.NaN, double.NaN));
            }

            // can't take sin or cos of +/-Infinity
            if (double.IsInfinity(num.Real))
            {
                throw PythonOps.ValueError("math domain error");
            }

            double real, imag;

            real = Math.Sin(num.Real) * Math.Cosh(num.Imaginary());
            imag = Math.Cos(num.Real) * Math.Sinh(num.Imaginary());

            return(new Complex(real, imag));
        }
コード例 #11
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
 private static bool IsNaN(Complex num)
 {
     return(double.IsNaN(num.Real) || double.IsNaN(num.Imaginary()));
 }
コード例 #12
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static bool isnan(object x)
        {
            Complex num = GetComplexNum(x);

            return(IsNaN(num));
        }
コード例 #13
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static bool isinf(object x)
        {
            Complex num = GetComplexNum(x);

            return(IsInfinity(num));
        }
コード例 #14
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static double phase(object x)
        {
            Complex num = GetComplexNum(x);

            return(GetAngle(num));
        }
コード例 #15
0
ファイル: cmath.cs プロジェクト: jschementi/iron
        private static double GetAngle(Complex num) {
            if (IsNaN(num)) {
                return double.NaN;
            }

            if (double.IsPositiveInfinity(num.Real)) {
                if (double.IsPositiveInfinity(num.Imaginary())) {
                    return Math.PI * 0.25;
                } else if (double.IsNegativeInfinity(num.Imaginary())) {
                    return Math.PI * -0.25;
                } else {
                    return 0.0;
                }
            }

            if (double.IsNegativeInfinity(num.Real)) {
                if (double.IsPositiveInfinity(num.Imaginary())) {
                    return Math.PI * 0.75;
                } else if (double.IsNegativeInfinity(num.Imaginary())) {
                    return Math.PI * -0.75;
                } else {
                    return DoubleOps.Sign(num.Imaginary()) * Math.PI;
                }
            }

            if (num.Real == 0.0) {
                if (num.Imaginary() != 0.0) {
                    return Math.PI * 0.5 * Math.Sign(num.Imaginary());
                } else {
                    return (DoubleOps.IsPositiveZero(num.Real) ? 0.0 : Math.PI) * DoubleOps.Sign(num.Imaginary());
                }
            }

            return Math.Atan2(num.Imaginary(), num.Real);
        }
コード例 #16
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //atanh(x) = (ln(1 +x) - ln(1-x))/2
        public static Complex atanh(object x)
        {
            Complex num = GetComplexNum(x);

            return((log(1 + num) - log(1 - num)) * 0.5);
        }
コード例 #17
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        //acosh(x) = ln( x + (x*x -1)^1/2)
        public static Complex acosh(object x)
        {
            Complex num = GetComplexNum(x);

            return(log(num + sqrt(num + 1) * sqrt(num - 1)));
        }
コード例 #18
0
ファイル: cmath.cs プロジェクト: Siyy/DynamicLanguageRuntime
        public static Complex exp(object x)
        {
            Complex num = GetComplexNum(x);

            // degenerate case: num is real
            if (num.Imaginary() == 0.0)
            {
                if (double.IsPositiveInfinity(num.Real))
                {
                    return(new Complex(double.PositiveInfinity, 0.0));
                }

                double expt = Math.Exp(num.Real);
                if (double.IsInfinity(expt))
                {
                    throw PythonOps.OverflowError("math range error");
                }

                return(new Complex(expt, 0.0));
            }

            // magnitude is always 0
            if (double.IsNegativeInfinity(num.Real))
            {
                return(Complex.Zero);
            }

            // magnitude is always NaN
            if (double.IsNaN(num.Real))
            {
                return(new Complex(double.NaN, double.NaN));
            }

            // angle is always NaN
            if (double.IsNaN(num.Imaginary()))
            {
                return(new Complex(double.IsInfinity(num.Real) ? double.PositiveInfinity : double.NaN, double.NaN));
            }

            // can't take sin or cos of +/-infinity
            if (double.IsInfinity(num.Imaginary()))
            {
                throw PythonOps.ValueError("math domain error");
            }

            // use c*(e^x) = (sign(c))*e^(x+log(abs(c))) for fewer overflows in corner cases
            double real;
            double cosImag = Math.Cos(num.Imaginary());

            if (cosImag > 0.0)
            {
                real = Math.Exp(num.Real + Math.Log(cosImag));
            }
            else if (cosImag < 0.0)
            {
                real = -Math.Exp(num.Real + Math.Log(-cosImag));
            }
            else
            {
                real = 0.0;
            }

            // use c*(e^x) = (sign(c))*e^(x+log(abs(c))) for fewer overflows in corner cases
            double imag;
            double sinImag = Math.Sin(num.Imaginary());

            if (sinImag > 0.0)
            {
                imag = Math.Exp(num.Real + Math.Log(sinImag));
            }
            else if (sinImag < 0.0)
            {
                imag = -Math.Exp(num.Real + Math.Log(-sinImag));
            }
            else
            {
                imag = 0.0;
            }

            // check for overflow
            if ((double.IsInfinity(real) || double.IsInfinity(imag)) && !double.IsInfinity(num.Real))
            {
                throw PythonOps.OverflowError("math range error");
            }

            return(new Complex(real, imag));
        }
コード例 #19
0
ファイル: cmath.cs プロジェクト: jschementi/iron
 private static bool IsNaN(Complex num) {
     return double.IsNaN(num.Real) || double.IsNaN(num.Imaginary());
 }