示例#1
0
        //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));
        }
示例#2
0
        public static string __str__(CodeContext /*!*/ context, Complex x)
        {
            if (x.Real != 0)
            {
                if (x.Imaginary() < 0 || DoubleOps.IsNegativeZero(x.Imaginary()))
                {
                    return("(" + FormatComplexValue(context, x.Real) + FormatComplexValue(context, x.Imaginary()) + "j)");
                }
                else   /* x.Imaginary() is NaN or >= +0.0 */
                {
                    return("(" + FormatComplexValue(context, x.Real) + "+" + FormatComplexValue(context, x.Imaginary()) + "j)");
                }
            }

            return(FormatComplexValue(context, x.Imaginary()) + "j");
        }
示例#3
0
 public static int __hash__(Complex x)
 {
     if (x.Imaginary() == 0)
     {
         return(DoubleOps.__hash__(x.Real));
     }
     return(x.GetHashCode());
 }
示例#4
0
        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));
        }
示例#5
0
        public static string __str__(CodeContext /*!*/ context, Complex x)
        {
            string j = (double.IsInfinity(x.Imaginary()) || double.IsNaN(x.Imaginary())) ? "*j" : "j";

            if (x.Real != 0)
            {
                if (x.Imaginary() < 0 || DoubleOps.IsNegativeZero(x.Imaginary()))
                {
                    return("(" + FormatComplexValue(context, x.Real) + FormatComplexValue(context, x.Imaginary()) + j + ")");
                }
                else   /* x.Imaginary() is NaN or >= +0.0 */
                {
                    return("(" + FormatComplexValue(context, x.Real) + "+" + FormatComplexValue(context, x.Imaginary()) + j + ")");
                }
            }

            return(FormatComplexValue(context, x.Imaginary()) + j);
        }
示例#6
0
        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));
        }
示例#7
0
        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));
        }
示例#8
0
        //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)));
        }
示例#9
0
        //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));
        }
示例#10
0
        public static Complex op_Power(Complex x, Complex y)
        {
            if (x.IsZero())
            {
                if (y.Real < 0.0 || y.Imaginary() != 0.0)
                {
                    throw PythonOps.ZeroDivisionError("0.0 to a negative or complex power");
                }
                return(y.IsZero() ? Complex.One : Complex.Zero);
            }

#if FEATURE_NUMERICS
            // Special case for higher precision with real integer powers
            // TODO: A similar check may get added to CLR 4 upon resolution of Dev10 bug 863171,
            // in which case this code should go away.
            if (y.Imaginary == 0.0)
            {
                int power = (int)y.Real;
                if (power >= 0 && y.Real == power)
                {
                    Complex res = Complex.One;
                    if (power == 0)
                    {
                        return(res);
                    }
                    Complex factor = x;
                    while (power != 0)
                    {
                        if ((power & 1) != 0)
                        {
                            res = res * factor;
                        }
                        factor  = factor * factor;
                        power >>= 1;
                    }
                    return(res);
                }
            }
#endif

            return(x.Pow(y));
        }
示例#11
0
        public static object __new__(
            CodeContext context,
            PythonType cls,
            [DefaultParameterValue(null)] object real,
            [DefaultParameterValue(null)] object imag
            )
        {
            Complex real2, imag2;

            real2 = imag2 = new Complex();

            if (real == null && imag == null && cls == TypeCache.Complex)
            {
                throw PythonOps.TypeError("argument must be a string or a number");
            }

            if (imag != null)
            {
                if (real is string)
                {
                    throw PythonOps.TypeError("complex() can't take second arg if first is a string");
                }
                if (imag is string)
                {
                    throw PythonOps.TypeError("complex() second arg can't be a string");
                }
                imag2 = Converter.ConvertToComplex(imag);
            }

            if (real != null)
            {
                if (real is string)
                {
                    real2 = LiteralParser.ParseComplex((string)real);
                }
                else if (real is Extensible <string> )
                {
                    real2 = LiteralParser.ParseComplex(((Extensible <string>)real).Value);
                }
                else if (real is Complex)
                {
                    if (imag == null && cls == TypeCache.Complex)
                    {
                        return(real);
                    }
                    else
                    {
                        real2 = (Complex)real;
                    }
                }
                else
                {
                    real2 = Converter.ConvertToComplex(real);
                }
            }

            double real3 = real2.Real - imag2.Imaginary();
            double imag3 = real2.Imaginary() + imag2.Real;

            if (cls == TypeCache.Complex)
            {
                return(new Complex(real3, imag3));
            }
            else
            {
                return(cls.CreateInstance(context, real3, imag3));
            }
        }
示例#12
0
        public static double Abs(Complex x)
        {
            double res = x.Abs();

            if (double.IsInfinity(res) && !double.IsInfinity(x.Real) && !double.IsInfinity(x.Imaginary()))
            {
                throw PythonOps.OverflowError("absolute value too large");
            }

            return(res);
        }
示例#13
0
        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));
        }
示例#14
0
 public static double Getimag(Complex self)
 {
     return(self.Imaginary());
 }
示例#15
0
 private void WriteComplex(Complex val)
 {
     _bytes.Add((byte)'x');
     WriteDoubleString(val.Real);
     WriteDoubleString(val.Imaginary());
 }
示例#16
0
 private void WriteComplex (Complex val) {
     _bytes.Add ((byte)'x');
     WriteDoubleString (val.Real);
     WriteDoubleString (val.Imaginary ());
 }
示例#17
0
        public static double Abs(Complex x)
        {
#if CLR2
            double res = x.Abs();
#else
            // TODO: remove after CodePlex 26224 and MS internal 861649 are resolved
            double res = MathUtils.Hypot(x.Real, x.Imaginary);
#endif

            if (double.IsInfinity(res) && !double.IsInfinity(x.Real) && !double.IsInfinity(x.Imaginary()))
            {
                throw PythonOps.OverflowError("absolute value too large");
            }

            return(res);
        }
示例#18
0
 private static bool IsNaN(Complex num)
 {
     return(double.IsNaN(num.Real) || double.IsNaN(num.Imaginary()));
 }