using System; namespace PDE { /// /// Implementacja liczb zespolonych dla platformy .NET /// (c) Jacek Matulewski 2005 (1.07.2005) /// public struct Complex { public double Real,Imag; //pola public Complex(double real,double imag) //konstrukror { this.Real=real; this.Imag=imag; } #region Metody public void Conj() { Imag=-Imag; } public override string ToString() //metoda { return "("+Real.ToString()+","+Imag.ToString()+")"; } public string ToStringI() //metoda { string s=Real.ToString(); if (Imag>=0) s+="+i"; else s+="-i"; s+=Math.Abs(Imag); return s; } public override bool Equals(object obj) { if (obj is Complex) { Complex z=(Complex)obj; return (this.Real==z.Real && this.Imag==z.Imag); } else return false; } public override int GetHashCode() { return Real.GetHashCode()^Imag.GetHashCode(); } #endregion #region Wlasnosci public double Norm //wlasnosc tylko do odczytu { get { return Real*Real+Imag*Imag; } } public double Radius //wlasnosc tylko do odczytu { get { return Math.Sqrt(Norm); } set { double phi=Phase; Real=value*System.Math.Cos(phi); Imag=value*System.Math.Sin(phi); } } public double Phase { get { //zmieniam zakres z -Pi:Pi na 0:2Pi double phi=Math.Atan2(Imag,Real); if (phi<0) phi+=2*Math.PI; return phi; } set { double r=Radius; Real=r*System.Math.Cos(value); Imag=r*System.Math.Sin(value); } } public static Complex I //statyczna wlasnosc tylko do odczytu { get { return new Complex(0,1); } } #endregion public string ToStringPolar() { return "R="+Radius+", Phi="+Phase+" ("+180*Phase/Math.PI+" stopni)"; } //alternatywny "konstruktor" public static Complex CreateFromPolar(double radius,double phase) { return new Complex(radius*System.Math.Cos(phase),radius*System.Math.Sin(phase)); } #region Funkcje matematyczne (metody statyczne) public static Complex Conj(Complex z) { z.Conj(); return z; } public static double Abs(Complex z) { return z.Radius; } public static double Arg(Complex z) { return z.Phase; } public static Complex Cis(double phase) { return CreateFromPolar(1,phase); } public static Complex Exp(Complex z) { return Math.Exp(z.Real)*CreateFromPolar(1,z.Imag); } public static Complex Cosh(Complex z) { return 0.5*(Exp(z)+Exp(-z)); } public static Complex Sinh(Complex z) { return 0.5*(Exp(z)-Exp(-z)); } public static Complex Tanh(Complex z) { return Sinh(z)/Cosh(z); } public static Complex Cos(Complex z) { Complex i=Complex.I; return 0.5*(Exp(i*z)+Exp(-i*z)); } public static Complex Sin(Complex z) { Complex i=Complex.I; return 0.5*(-i)*(Exp(i*z)-Exp(-i*z)); } public static Complex Tan(Complex z) { return Sin(z)/Cos(z); } public static Complex Sqrt(Complex z) { return Math.Sqrt(z.Norm)*(new Complex(Math.Cos(0.5*z.Phase),Math.Sin(0.5*z.Phase))); } public static Complex Log(Complex z) { return new Complex(Math.Log(z.Radius),z.Phase); } public static Complex Log10(Complex z) { return Log(z)/Math.Log(10); } public static Complex Acos(Complex z) { Complex i=Complex.I; return -i*Log(z+i*Sqrt(1-z*z)); } public static Complex Asin(Complex z) { Complex i=Complex.I; return -i*Log(i*z+Sqrt(1-z*z)); } public static Complex Atan(Complex z) { Complex i=Complex.I; return -0.5*i*Log((1+i*z)/(1-i*z)); } static public Complex Pow(Complex z,double exponent) { return Exp(exponent*Log(z)); } #endregion #region Operatory //operatory arytmetyczne public static Complex operator -(Complex z) { return new Complex(-z.Real,-z.Imag); } public static Complex operator +(Complex z1,Complex z2) { return new Complex(z1.Real+z2.Real,z1.Imag+z2.Imag); } public static Complex operator -(Complex z1,Complex z2) { return new Complex(z1.Real-z2.Real,z1.Imag-z2.Imag); } public static Complex operator *(Complex z1,Complex z2) { return new Complex(z1.Real*z2.Real-z1.Imag*z2.Imag,z1.Real*z2.Imag+z1.Imag*z2.Real); } public static Complex operator /(Complex z1,Complex z2) { if (z2.Norm==0) throw new Exception("Dzielenie liczby zespolonej przez zero"); z1*=Conj(z2); z1.Real/=z2.Norm; z1.Imag/=z2.Norm; return z1; } //operatory logiczne public static bool operator==(Complex z1,Complex z2) { return ((z1.Real==z2.Real) && (z1.Imag==z2.Imag)); } public static bool operator!=(Complex z1,Complex z2) { return !(z1==z2); } //konwersja z Complex na double public static explicit operator double(Complex z) { if (z.Imag==0) return z.Real; else throw new Exception("Konwersja liczby zespolonej na rzeczywistą jest niemożliwa (część urojona różna od zera)"); } //konwersja z double na Complex public static implicit operator Complex(double real) { return new Complex(real,0); } #endregion } }