Advertisement
Guest User

Untitled

a guest
Aug 28th, 2015
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.82 KB | None | 0 0
  1. using System;
  2.  
  3. namespace Equamatics
  4. {
  5. /// <summary>
  6. /// Represents a Complex Number.
  7. /// x + iy
  8. /// </summary>
  9. public struct Complex
  10. {
  11. #region Fields
  12. double _Real, _Imaginary;
  13.  
  14. public const double FormattingEpsilon = 1e-10;
  15. #endregion
  16.  
  17. #region Constructors
  18. /// <summary>
  19. /// Creates a Complex Number.
  20. /// </summary>
  21. /// <param name="Real">The Real Part.</param>
  22. /// <param name="Imaginary">The Imaginary Part.</param>
  23. public Complex(double Real = 0, double Imaginary = 0) { _Real = Real; _Imaginary = Imaginary; }
  24.  
  25. /// <summary>
  26. /// Polar form Constructor. r(cosɵ + isinɵ).
  27. /// where 'r' is the Magnitude and 'ɵ' is the Phase.
  28. /// </summary>
  29. /// <param name="Modulus">The Magnitude of the Complex Vector in Argand Plane.</param>
  30. /// <param name="Phase">The Inclination of the Complex Vector with the Possitive direction of x-axis.</param>
  31. public Complex Polar(double Magnitude, double Phase)
  32. {
  33. return new Complex(Magnitude * Math.Cos(Phase), Magnitude * Math.Sin(Phase));
  34. }
  35. #endregion
  36.  
  37. #region Formatting
  38. /// <summary>
  39. /// Reads a Complex Number from a String.
  40. /// </summary>
  41. public static Complex Parse(string Input)
  42. {
  43. Input = Input.Replace(" ", "");
  44.  
  45. double Real = 0;
  46. double Imaginary = 0;
  47.  
  48. string[] Temp = Input.Replace("-", "+-").Split("+".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  49.  
  50. try
  51. {
  52. foreach (string Item in Temp)
  53. {
  54. if (Item == "-i") --Imaginary;
  55. else if (Item == "i") ++Imaginary;
  56. else if (Item.Contains("i")) Imaginary += double.Parse(Item.Replace("i", ""));
  57. else Real += double.Parse(Item);
  58. }
  59. }
  60. catch { throw new FormatException(); }
  61.  
  62. return new Complex(Real, Imaginary);
  63. }
  64.  
  65. /// <summary>
  66. /// Returns a String Representation of the Complex Number.
  67. /// </summary>
  68. /// <returns>A String representing the Complex Number.</returns>
  69. public override string ToString()
  70. {
  71. //Trim Real Part
  72. try { if (Math.Abs(Real) < FormattingEpsilon) Real = 0; }
  73. catch { }
  74.  
  75. // Trim Imaginary Part
  76. try { if (Math.Abs(Imaginary) < FormattingEpsilon) Imaginary = 0; }
  77. catch { }
  78.  
  79. if (this == 0) return "0";
  80. else if (this == Iota) return "i";
  81. else if (this == -Iota) return "-i";
  82.  
  83. else if (IsPurelyImaginary) return Imaginary.ToString() + "i";
  84.  
  85. else if (IsReal) return Real.ToString();
  86. else if (Math.Abs(Imaginary - 1) < FormattingEpsilon) return Real.ToString() + " + i";
  87. else if (Math.Abs(Imaginary + 1) < FormattingEpsilon) return Real.ToString() + " - i";
  88.  
  89. return Real.ToString() + (Imaginary > 0 ? " + " : " - ") + Math.Abs(Imaginary).ToString() + "i";
  90. }
  91. #endregion
  92.  
  93. #region Predefined Numbers
  94. /// <summary>
  95. /// The Imaginary Unit. (i)
  96. /// </summary>
  97. public static Complex Iota { get { return new Complex(0, 1); } }
  98.  
  99. /// <summary>
  100. /// Cube Root of Unity. (ω)
  101. /// </summary>
  102. public static Complex Omega { get { return new Complex((-0.5), (Math.Sqrt(3) / 2)); } }
  103.  
  104. /// <summary>
  105. /// Not a Number.
  106. /// </summary>
  107. public static Complex NaN { get { return new Complex(Double.NaN, Double.NaN); } }
  108. #endregion
  109.  
  110. #region Properties
  111. /// <summary> Real Part. </summary>
  112. public double Real { get { return _Real; } set { _Real = value; } }
  113.  
  114. /// <summary> Imaginary Part. </summary>
  115. public double Imaginary { get { return _Imaginary; } set { _Imaginary = value; } }
  116.  
  117. /// <summary> Magnitude of the Complex Number. </summary>
  118. public double Modulus
  119. {
  120. get
  121. {
  122. Complex A = new Complex(Math.Abs(Real), Math.Abs(Imaginary));
  123.  
  124. if (A.Real < A.Imaginary) return A.Imaginary * Math.Sqrt(1 + Math.Pow(A.Real / A.Imaginary, 2));
  125. else if (A.Real > A.Imaginary) return A.Real * Math.Sqrt(1 + Math.Pow(A.Imaginary / A.Real, 2));
  126. else return A.Real * Math.Sqrt(2);
  127. }
  128. }
  129.  
  130. public static Complex Sqrt(Complex Z)
  131. {
  132. return new Complex(Math.Sqrt((Z.Modulus + Z.Real) / 2),
  133. (Z.Imaginary < 0 ? -1 : 1) * Math.Sqrt((Z.Modulus - Z.Real) / 2));
  134. }
  135.  
  136. /// <summary> Is a Real Number. </summary>
  137. public bool IsReal { get { return Imaginary == 0; } }
  138.  
  139. /// <summary> Is Purely Imaginary. No Real Part. </summary>
  140. public bool IsPurelyImaginary { get { return Real == 0; } }
  141.  
  142. /// <summary>
  143. /// The Inclination of the Complex Number Vector with the Possitive direction of the X-Axis.
  144. /// </summary>
  145. public double Phase
  146. {
  147. get
  148. {
  149. double Alpha = Math.Atan2(Imaginary, Real);
  150.  
  151. if (this == 0) return Double.NaN;
  152. else if (IsReal) return Real > 0 ? 0 : Math.PI;
  153. else if (IsPurelyImaginary) return Imaginary > 0 ? Math.PI / 2 : -Math.PI / 2;
  154. else if (Real > 0 && Imaginary > 0) return Alpha;
  155. else if (Real < 0 && Imaginary > 0) return Math.PI - Alpha;
  156. else if (Real < 0 && Imaginary < 0) return Alpha - Math.PI;
  157. else if (Real > 0 && Imaginary < 0) return -Alpha;
  158. else return Alpha;
  159. }
  160. }
  161.  
  162. public Complex Conjugate { get { return new Complex(Real, -Imaginary); } }
  163.  
  164. public bool IsNaN { get { return Double.IsNaN(this.Real) || Double.IsNaN(this.Imaginary); } }
  165.  
  166. /// <summary> Is an Imaginary Number. </summary>
  167. public bool IsImaginary { get { return !IsReal; } }
  168.  
  169. #endregion
  170.  
  171. #region Logarithmic
  172.  
  173. /// If the non-zero complex number z is expressed in polar coordinates as z = r * e^(i*t)
  174. /// with r > 0 and t is between -pi and pi, then log(z) = ln(r) + i*t, where ln(r) is the
  175. /// usual natural logarithm of a real number.
  176. public static Complex Log(Complex Z)
  177. {
  178. return new Complex(Math.Log(Z.Modulus), Z.Phase);
  179. }
  180.  
  181. public static Complex operator ^(Complex Z1, Complex Z2) { return Pow(Z1, Z2); }
  182.  
  183. public static Complex Log10(Complex Z)
  184. {
  185. const double log10 = 2.3025850929940459;
  186.  
  187. Complex temp = Log(Z);
  188.  
  189. temp.Real /= log10;
  190. temp.Imaginary /= log10;
  191.  
  192. return temp;
  193. }
  194.  
  195.  
  196. // Needs to be Verified.
  197. public static Complex Log(Complex Z, double Base)
  198. {
  199. double logBase = Math.Log(Base);
  200.  
  201. Complex temp = Log(Z);
  202.  
  203. temp.Real /= logBase;
  204. temp.Imaginary /= logBase;
  205.  
  206. return temp;
  207. }
  208.  
  209.  
  210. /// exp(z) = exp(a) * (cos(b) + i*sin(b)).
  211. public static Complex Exp(Complex Z)
  212. {
  213. double Modulus = Math.Exp(Z.Real);
  214. return new Complex(Modulus * Math.Cos(Z.Imaginary), Modulus * Math.Sin(Z.Imaginary));
  215. }
  216.  
  217.  
  218. public static Complex Pow(Complex Z, Complex Index)
  219. {
  220. return Exp(Index * Log(Z));
  221. }
  222. #endregion
  223.  
  224. #region Trigonometric
  225.  
  226. #region Basic
  227. /// sin(z) = ( exp(i*z) - exp(-i*z) ) / (2*i).
  228. public static Complex Sin(Complex Z)
  229. {
  230. Complex Z1 = Exp(new Complex(-Z.Imaginary, Z.Real));
  231. Complex Z2 = Exp(new Complex(Z.Imaginary, -Z.Real));
  232.  
  233. return new Complex(0.5 * (Z1.Imaginary - Z2.Imaginary), 0.5 * (Z2.Real - Z1.Real));
  234. }
  235.  
  236. /// cos(z) = ( exp(i*z) + exp(-i*z) ) / 2.
  237. public static Complex Cos(Complex Z)
  238. {
  239. Complex Z1 = Exp(new Complex(-Z.Imaginary, Z.Real));
  240. Complex Z2 = Exp(new Complex(Z.Imaginary, -Z.Real));
  241.  
  242. return new Complex(0.5 * (Z1.Real + Z2.Real), 0.5 * (Z1.Imaginary + Z2.Imaginary));
  243. }
  244.  
  245. public static Complex Tan(Complex Z)
  246. {
  247. return (Sin(Z) / Cos(Z));
  248. }
  249. #endregion
  250.  
  251. #region Inverse
  252.  
  253. public static Complex Asin(Complex Z)
  254. {
  255. // asin(z) = -i ln (i z + sqrt (1 - z^2))
  256. Complex z1 = new Complex(1.0, 0.0);
  257. Complex zi = new Complex(0.0, -1.0);
  258. Complex w = zi * Log(zi * Z + Sqrt(z1 - (Z ^ 2)));
  259. w = -w;
  260. return w;
  261. }
  262.  
  263. public static Complex Acos(Complex Z)
  264. {
  265. // acos(z) = -i ln (z + i sqrt (1 - z^2))
  266. Complex z1 = new Complex(1.0, 0.0);
  267. Complex zi = new Complex(0.0, -1.0);
  268. Complex w = zi * Log(Z + zi * Sqrt(z1 - (Z ^ 2)));
  269. w = -w;
  270. return w;
  271. }
  272.  
  273. public static Complex Atan(Complex Z)
  274. {
  275. // atan(z) = -i ln ((1 + i z) / (1 - i z)) / 2
  276. Complex zi = new Complex(0.0, -1.0);
  277. Complex z1 = new Complex(1.0, 0.0);
  278. Complex z2 = new Complex(2.0, 0.0);
  279. Complex w = zi * Log((z1 + zi * Z) / (z1 - zi * Z)) / z2;
  280. w = -w;
  281. return w;
  282. }
  283. #endregion
  284.  
  285. #region Hyperbolic
  286.  
  287. /// cosh(z) = ( exp(z) + exp(-z) ) / 2.
  288. public static Complex Cosh(Complex Z)
  289. {
  290. Complex Z1 = Exp(Z);
  291. Complex Z2 = Exp(-Z);
  292.  
  293. return new Complex(0.5 * (Z1.Real + Z2.Real), 0.5 * (Z1.Imaginary + Z2.Imaginary));
  294. }
  295.  
  296. /// sinh(z) = ( exp(z) - exp(-z) ) / 2.
  297. public static Complex Sinh(Complex Z)
  298. {
  299. Complex Z1 = Exp(Z);
  300. Complex Z2 = Exp(-Z);
  301.  
  302. return new Complex(0.5 * (Z1.Real - Z2.Real), 0.5 * (Z1.Imaginary - Z2.Imaginary));
  303. }
  304.  
  305. public static Complex Tanh(Complex Z)
  306. {
  307. return Sinh(Z) / Cosh(Z);
  308. }
  309. #endregion
  310.  
  311. #endregion
  312.  
  313. #region Operator Overloading
  314.  
  315. #region Arithmetic Operators
  316. public static Complex operator +(Complex Z1, Complex Z2)
  317. {
  318. return new Complex(Z1.Real + Z2.Real, Z1.Imaginary + Z2.Imaginary);
  319. }
  320.  
  321. public static Complex operator -(Complex Z1, Complex Z2) { return Z1 + (-Z2); }
  322.  
  323. public static Complex operator *(Complex Z1, Complex Z2)
  324. {
  325. double REAL = Z1.Real * Z2.Real - Z1.Imaginary * Z2.Imaginary;
  326. double IMAG = Z1.Real * Z2.Imaginary + Z1.Imaginary * Z2.Real;
  327. return new Complex(REAL, IMAG);
  328. }
  329.  
  330. public static Complex operator /(Complex Z1, Complex Z2)
  331. {
  332. double r = 0;
  333. double d = 0;
  334.  
  335. if (Z2 == 0) return new Complex(Double.MaxValue, Double.MaxValue);
  336.  
  337. if ((Math.Abs(Z2.Real) < Math.Abs(Z2.Imaginary)))
  338. {
  339. r = Z2.Real / Z2.Imaginary;
  340. d = Z2.Imaginary + r * Z2.Real;
  341. return new Complex((Z1.Real * r + Z1.Imaginary) / d, (Z1.Imaginary * r - Z1.Real) / d);
  342. }
  343.  
  344. r = Z2.Imaginary / Z2.Real;
  345. d = Z2.Real + r * Z2.Imaginary;
  346. return new Complex((Z1.Real + Z1.Imaginary * r) / d, (Z1.Imaginary - Z1.Real * r) / d);
  347. }
  348.  
  349. public static Complex operator -(Complex Z) { return new Complex(-Z.Real, -Z.Imaginary); }
  350. #endregion
  351.  
  352. #region Logical Operators
  353. public static bool operator ==(Complex Z1, Complex Z2) { return ((Z1.Real == Z2.Real) && (Z1.Imaginary == Z2.Imaginary)); }
  354.  
  355. public static bool operator !=(Complex Z1, Complex Z2) { return !(Z1 == Z2); }
  356. #endregion
  357.  
  358. #endregion
  359.  
  360. public static implicit operator Complex(double Z) { return new Complex(Z); }
  361. }
  362. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement