网上演练
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
12 KiB

#if NET20 || NET30 || NET35 || !NET_4_6
// Complex.cs: Complex number support
// Author:
// Miguel de Icaza (miguel@gnome.org)
// Marek Safar (marek.safar@gmail.com)
// Jb Evain (jbevain@novell.com)
// Copyright 2009, 2010 Novell, Inc.
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace System.Numerics
{
public struct Complex : IEquatable<Complex>, IFormattable
{
public static readonly Complex ImaginaryOne = new Complex(0, 1);
public static readonly Complex One = new Complex(1, 0);
public static readonly Complex Zero = new Complex(0, 0);
private readonly double _imaginary;
private readonly double _real;
public Complex(double real, double imaginary)
{
_imaginary = imaginary;
_real = real;
}
public double Imaginary
{
get { return _imaginary; }
}
public double Magnitude
{
get { return Math.Sqrt((_imaginary * _imaginary) + (_real * _real)); }
}
public double Phase
{
get { return Math.Atan2(_imaginary, _real); }
}
public double Real
{
get { return _real; }
}
private double MagnitudeSquared
{
get { return (_imaginary * _imaginary) + (_real * _real); }
}
public static double Abs(Complex value)
{
return Math.Sqrt((value._imaginary * value._imaginary) + (value._real * value._real));
}
public static Complex Acos(Complex value)
{
return -ImaginaryOne * Log(value + (ImaginaryOne * Sqrt(One - (value * value))));
}
public static Complex Add(Complex left, Complex right)
{
return new Complex
(
left._real + right._real,
left._imaginary + right._imaginary
);
}
public static Complex Asin(Complex value)
{
return -ImaginaryOne * Log((ImaginaryOne * value) + Sqrt(One - (value * value)));
}
public static Complex Atan(Complex value)
{
return (ImaginaryOne / new Complex(2, 0)) * (Log(One - (ImaginaryOne * value)) - Log(One + (ImaginaryOne * value)));
}
public static Complex Conjugate(Complex value)
{
return new Complex(value._real, -value._imaginary);
}
public static Complex Cos(Complex value)
{
return new Complex
(
Math.Cos(value._real) * Math.Cosh(value._imaginary),
-Math.Sin(value._real) * Math.Sinh(value._imaginary)
);
}
public static Complex Cosh(Complex value)
{
return new Complex
(
Math.Cosh(value._real) * Math.Cos(value._imaginary),
-Math.Sinh(value._real) * Math.Sin(value._imaginary)
);
}
public static Complex Divide(Complex dividend, Complex divisor)
{
var divisorMagnitudeSquared = divisor.MagnitudeSquared;
return new Complex
(
((dividend._real * divisor._real) + (dividend._imaginary * divisor._imaginary)) / divisorMagnitudeSquared,
((dividend._imaginary * divisor._real) - (dividend._real * divisor._imaginary)) / divisorMagnitudeSquared
);
}
public static Complex Exp(Complex value)
{
var expReal = Math.Exp(value._real);
return new Complex
(
expReal * Math.Cos(value._imaginary),
expReal * Math.Sin(value._imaginary)
);
}
public static explicit operator Complex(decimal value)
{
return new Complex((double)value, 0);
}
public static explicit operator Complex(BigInteger value)
{
return new Complex((double)value, 0);
}
public static Complex FromPolarCoordinates(double magnitude, double phase)
{
return new Complex
(
magnitude * Math.Cos(phase),
magnitude * Math.Sin(phase)
);
}
public static implicit operator Complex(byte value)
{
return new Complex(value, 0);
}
public static implicit operator Complex(double value)
{
return new Complex(value, 0);
}
public static implicit operator Complex(short value)
{
return new Complex(value, 0);
}
public static implicit operator Complex(int value)
{
return new Complex(value, 0);
}
public static implicit operator Complex(long value)
{
return new Complex(value, 0);
}
//[CLSCompliant(false)]
public static implicit operator Complex(sbyte value)
{
return new Complex(value, 0);
}
public static implicit operator Complex(float value)
{
return new Complex(value, 0);
}
//[CLSCompliant(false)]
public static implicit operator Complex(ushort value)
{
return new Complex(value, 0);
}
//[CLSCompliant(false)]
public static implicit operator Complex(uint value)
{
return new Complex(value, 0);
}
//[CLSCompliant(false)]
public static implicit operator Complex(ulong value)
{
return new Complex(value, 0);
}
public static Complex Log(Complex value)
{
return new Complex
(
Math.Log(Abs(value)),
value.Phase
);
}
public static Complex Log(Complex value, double baseValue)
{
return Log(value) / Log(new Complex(baseValue, 0));
}
public static Complex Log10(Complex value)
{
return Log(value, 10);
}
public static Complex Multiply(Complex left, Complex right)
{
return new Complex
(
(left._real * right._real) - (left._imaginary * right._imaginary),
(left._real * right._imaginary) + (left._imaginary * right._real)
);
}
public static Complex Negate(Complex value)
{
return -value;
}
public static Complex operator -(Complex left, Complex right)
{
return new Complex
(
left._real - right._real,
left._imaginary - right._imaginary
);
}
public static Complex operator -(Complex value)
{
return new Complex(-value._real, -value._imaginary);
}
public static bool operator !=(Complex left, Complex right)
{
return !left._real.Equals(right._real) || !left._imaginary.Equals(right._imaginary);
}
public static Complex operator *(Complex left, Complex right)
{
return new Complex
(
(left._real * right._real) - (left._imaginary * right._imaginary),
(left._real * right._imaginary) + (left._imaginary * right._real)
);
}
public static Complex operator /(Complex left, Complex right)
{
var rsri = (right._real * right._real) + (right._imaginary * right._imaginary);
return new Complex
(
((left._real * right._real) + (left._imaginary * right._imaginary)) / rsri,
((left._imaginary * right._real) - (left._real * right._imaginary)) / rsri
);
}
public static Complex operator +(Complex left, Complex right)
{
return new Complex
(
left._real + right._real,
left._imaginary + right._imaginary
);
}
public static bool operator ==(Complex left, Complex right)
{
return left._real.Equals(right._real) && left._imaginary.Equals(right._imaginary);
}
public static Complex Pow(Complex value, double power)
{
return Pow(value, new Complex(power, 0));
}
public static Complex Pow(Complex value, Complex power)
{
return Exp(Log(value) * power);
}
public static Complex Reciprocal(Complex value)
{
return value == Zero ? value : One / value;
}
public static Complex Sin(Complex value)
{
return new Complex
(
Math.Sin(value._real) * Math.Cosh(value._imaginary),
Math.Cos(value._real) * Math.Sinh(value._imaginary)
);
}
public static Complex Sinh(Complex value)
{
return new Complex
(
Math.Sinh(value._real) * Math.Cos(value._imaginary),
Math.Cosh(value._real) * Math.Sin(value._imaginary)
);
}
public static Complex Sqrt(Complex value)
{
return FromPolarCoordinates(Math.Sqrt(value.Magnitude), value.Phase / 2);
}
public static Complex Subtract(Complex left, Complex right)
{
return new Complex
(
left._real - right._real,
left._imaginary - right._imaginary
);
}
public static Complex Tan(Complex value)
{
return Sin(value) / Cos(value);
}
public static Complex Tanh(Complex value)
{
return Sinh(value) / Cosh(value);
}
public bool Equals(Complex value)
{
return _real.Equals(value._real) && _imaginary.Equals(value._imaginary);
}
public override bool Equals(object obj)
{
if (obj is Complex)
{
var other = (Complex)obj;
return _real.Equals(other._real) && _imaginary.Equals(other._imaginary);
}
return false;
}
public override int GetHashCode()
{
return _real.GetHashCode() ^ _imaginary.GetHashCode();
}
public override string ToString()
{
return string.Format("({0}, {1})", _real, _imaginary);
}
public string ToString(IFormatProvider provider)
{
return string.Format(provider, "({0}, {1})", _real, _imaginary);
}
public string ToString(string format)
{
return string.Format("({0}, {1})", _real.ToString(format), _imaginary.ToString(format));
}
public string ToString(string format, IFormatProvider provider)
{
return string.Format("({0}, {1})", _real.ToString(format, provider), _imaginary.ToString(format, provider));
}
}
}
#endif