Complex Number class written in C# (works in Unity)


SUBMITTED BY: Guest

DATE: May 3, 2014, 9:46 a.m.

FORMAT: C#

SIZE: 12.4 kB

HITS: 642

  1. using System;
  2. using System.Diagnostics;
  3. /*
  4. * This is a complex number class I wrote to use in unity (since Unity uses MonoDevelop)
  5. * If you like my work, and found use in it,
  6. * or want to encourage more useful classes in C#.
  7. * Please donate ^^
  8. * Bitcoin Address: 1LdyAQHXdFVqzGzah45sGKhsQ8wDE6jyci
  9. * Good luck and enjoy.
  10. *
  11. */
  12. namespace Assets.Scripts
  13. {
  14. public struct Complex
  15. {
  16. private double _realNumber;
  17. private double _imaginaryNumber;
  18. private static readonly Random _random = new Random();
  19. public Double RealNumber
  20. {
  21. get { return _realNumber; }
  22. set { _realNumber = value; }
  23. }
  24. public Double ImaginaryNumber
  25. {
  26. get { return _imaginaryNumber; }
  27. set { _imaginaryNumber = value; }
  28. }
  29. public Complex(double real, double imaginary)
  30. {
  31. _realNumber = real;
  32. _imaginaryNumber = imaginary;
  33. }
  34. public Complex(Complex z)
  35. {
  36. _realNumber = z._realNumber;
  37. _imaginaryNumber = z._imaginaryNumber;
  38. }
  39. public void ComplexNumber(double real, double imaginary)
  40. {
  41. _realNumber = real;
  42. _imaginaryNumber = imaginary;
  43. }
  44. public static Complex Random()
  45. {
  46. var z = new Complex
  47. {
  48. RealNumber = _random.NextDouble(),
  49. ImaginaryNumber = _random.NextDouble()
  50. };
  51. return z;
  52. }
  53. public static Complex Random(Double lowNumber)
  54. {
  55. return Random(lowNumber, 0);
  56. }
  57. public static Complex Random(Double lowNumber, Double highNumber)
  58. {
  59. var z = new Complex();
  60. var range = highNumber - lowNumber;
  61. z.RealNumber = lowNumber + range*_random.NextDouble();
  62. z.ImaginaryNumber = lowNumber + range*_random.NextDouble();
  63. return z;
  64. }
  65. public static Complex operator +(Complex z1, Complex z2)
  66. {
  67. return new Complex(z1.RealNumber + z2.RealNumber, z1.ImaginaryNumber + z2.ImaginaryNumber);
  68. }
  69. public static Complex operator -(Complex z1, Complex z2)
  70. {
  71. return new Complex(z1.RealNumber - z2.RealNumber, z1.ImaginaryNumber - z2.ImaginaryNumber);
  72. }
  73. public static Complex operator -(Complex z)
  74. {
  75. z.RealNumber = -z.RealNumber;
  76. z.ImaginaryNumber = -z.ImaginaryNumber;
  77. return z;
  78. }
  79. public static Complex operator *(Complex z1, Complex z2)
  80. {
  81. return new Complex(
  82. z1.RealNumber * z2.RealNumber - z1.ImaginaryNumber *z2.ImaginaryNumber,
  83. z1.RealNumber * z2.ImaginaryNumber + z2.ImaginaryNumber * z2.RealNumber
  84. );
  85. }
  86. static public Complex operator *(Complex z, double dval)
  87. {
  88. var z2 = new Complex
  89. {
  90. RealNumber = (z.RealNumber*dval),
  91. ImaginaryNumber = (z.ImaginaryNumber*dval)
  92. };
  93. return z2;
  94. }
  95. static public Complex operator *( double dval, Complex z)
  96. {
  97. var z2 = new Complex
  98. {
  99. RealNumber = (z.RealNumber * dval),
  100. ImaginaryNumber = (z.ImaginaryNumber * dval)
  101. };
  102. return z2;
  103. }
  104. public static Complex operator /(Complex z1, Complex z2)
  105. {
  106. var value = z2.RealNumber*z2.RealNumber + z2.ImaginaryNumber*z2.ImaginaryNumber;
  107. return new Complex(
  108. (z1.RealNumber * z2.RealNumber + z1.ImaginaryNumber * z2.ImaginaryNumber)/value,
  109. (z1.ImaginaryNumber * z2.RealNumber + z1.RealNumber * z2.ImaginaryNumber)/value
  110. );
  111. }
  112. static public Complex operator /(Complex z, double dval)
  113. {
  114. var z2 = new Complex
  115. {
  116. RealNumber = z.RealNumber/dval,
  117. ImaginaryNumber = z.ImaginaryNumber/dval
  118. };
  119. return z2;
  120. }
  121. public static bool operator ==(Complex z1, Complex z2)
  122. {
  123. return (z1.RealNumber == z2.RealNumber && z1.ImaginaryNumber == z2.ImaginaryNumber);
  124. }
  125. public static bool operator !=(Complex z1, Complex z2)
  126. {
  127. return !(z1 == z2);
  128. }
  129. public Complex Conjugate
  130. {
  131. get { return new Complex(_realNumber, -_imaginaryNumber); }
  132. }
  133. public double Norm
  134. {
  135. get { return Math.Sqrt(_realNumber * _realNumber + _imaginaryNumber * _imaginaryNumber); }
  136. }
  137. public double AbsoluteSquare
  138. {
  139. get { return (this * Conjugate).RealNumber; }
  140. }
  141. public double Modulus
  142. {
  143. get { return Math.Sqrt(_realNumber * _realNumber + _imaginaryNumber * _imaginaryNumber); }
  144. }
  145. public double Argument
  146. {
  147. get { return Math.Atan2(_imaginaryNumber, _realNumber); }
  148. }
  149. public static Complex Polar(double modulus, double argument)
  150. {
  151. return new Complex(
  152. modulus * Math.Cos(argument),
  153. modulus * Math.Sin(argument));
  154. }
  155. public static Complex Exp(Complex z)
  156. {
  157. var value = Math.Exp(z.RealNumber);
  158. return new Complex(
  159. value * Math.Cos(z.ImaginaryNumber),
  160. value * Math.Sin(z.ImaginaryNumber));
  161. }
  162. public static Complex Log(Complex z)
  163. {
  164. return new Complex(Math.Log(z.Modulus), z.Argument);
  165. }
  166. public static Complex Pow(Complex baseNumber, Complex index)
  167. {
  168. return Exp(index * Log(baseNumber));
  169. }
  170. public static Complex Sqrt(Complex z)
  171. {
  172. var value = Math.Sqrt(z.RealNumber * z.RealNumber + z.ImaginaryNumber * z.ImaginaryNumber) + z.RealNumber;
  173. return new Complex(
  174. Math.Sqrt(0.5 * value),
  175. Math.Sqrt(0.5 / value) * z.ImaginaryNumber);
  176. }
  177. public static Complex Recip(Complex z)
  178. {
  179. if (z.RealNumber == 0.0 && z.ImaginaryNumber == 0.0)
  180. {
  181. Console.WriteLine("multiplicative inverse (reciprocal) not defined for complex zero");
  182. return z;
  183. }
  184. var zr = new Complex(1.0, 0.0)
  185. {
  186. RealNumber = z.RealNumber/(z.RealNumber*z.RealNumber + z.ImaginaryNumber*z.ImaginaryNumber),
  187. ImaginaryNumber = -z.ImaginaryNumber/(z.RealNumber*z.RealNumber + z.ImaginaryNumber*z.ImaginaryNumber)
  188. };
  189. return zr;
  190. }
  191. public Complex SetPolar(double mod, double arg)
  192. {
  193. var z = new Complex();
  194. var t = arg;
  195. z.RealNumber = mod * Math.Cos(t);
  196. z.ImaginaryNumber = mod * Math.Sin(t);
  197. return z;
  198. }
  199. public static Complex NthRoot(Complex z, long n, long k)
  200. {
  201. var mod = z.Modulus;
  202. var arg = z.Argument;
  203. var lmod = Math.Log(mod);
  204. var rlmod = lmod / n;
  205. var rmod = Math.Exp(rlmod);
  206. var zrn = new Complex();
  207. var t = arg / n + 2 * k * Math.PI / n;
  208. zrn.RealNumber = rmod * Math.Cos(t);
  209. zrn.ImaginaryNumber = rmod * Math.Sin(t);
  210. return zrn;
  211. }
  212. public static Complex Cos(Complex z)
  213. {
  214. var z1 = Exp(new Complex(-z.ImaginaryNumber, z.RealNumber));
  215. var z2 = Exp(new Complex(z.ImaginaryNumber, -z.RealNumber));
  216. return new Complex(0.5 * (z1.RealNumber + z2.RealNumber),
  217. 0.5 * (z1.ImaginaryNumber+ z2.ImaginaryNumber));
  218. }
  219. public static Complex Cosh(Complex z)
  220. {
  221. Complex z1 = Exp(z);
  222. Complex z2 = Exp(new Complex(-z.RealNumber, -z.ImaginaryNumber));
  223. return new Complex(0.5 * (z1.RealNumber + z2.RealNumber),
  224. 0.5 * (z1.ImaginaryNumber + z2.ImaginaryNumber));
  225. }
  226. public static Complex Sin(Complex z)
  227. {
  228. Complex z1 = Exp(new Complex(-z.ImaginaryNumber, z.RealNumber));
  229. Complex z2 = Exp(new Complex(z.ImaginaryNumber, -z.RealNumber));
  230. return new Complex(0.5 * (z1.ImaginaryNumber - z2.ImaginaryNumber), 0.5 * (z2.RealNumber - z1.RealNumber));
  231. }
  232. public static Complex Sinh(Complex z)
  233. {
  234. Complex z1 = Exp(z);
  235. Complex z2 = Exp(new Complex(-z.RealNumber, -z.ImaginaryNumber));
  236. return new Complex(0.5 * (z1.RealNumber - z2.RealNumber),
  237. 0.5 * (z1.ImaginaryNumber - z2.ImaginaryNumber));
  238. }
  239. public static Complex Tan(Complex z)
  240. {
  241. return Sin(z) / Cos(z);
  242. }
  243. public static Complex Tanh(Complex z)
  244. {
  245. return Sinh(z) / Cosh(z);
  246. }
  247. public static Complex Log10(Complex z)
  248. {
  249. const double log10 = 2.3025850929940459;
  250. Complex value = Log(z);
  251. value.RealNumber /= log10;
  252. value.ImaginaryNumber /= log10;
  253. return value;
  254. }
  255. public override string ToString()
  256. {
  257. return (String.Format("( {0}, {1} )", RealNumber, ImaginaryNumber));
  258. }
  259. public override int GetHashCode()
  260. {
  261. unchecked
  262. {
  263. return (_realNumber.GetHashCode()*397) ^ _imaginaryNumber.GetHashCode();
  264. }
  265. }
  266. public void Show()
  267. {
  268. Console.WriteLine(ToString());
  269. }
  270. public void ShowPolar()
  271. {
  272. Console.WriteLine("{0} * e^(i * {1})", Modulus, Argument);
  273. }
  274. public string Polar()
  275. {
  276. var z = new Complex(this);
  277. var s = z.Modulus + " * e^(i * " + z.Argument + ")";
  278. return s;
  279. }
  280. public void Dump()
  281. {
  282. Debug.WriteLine(ToString());
  283. }
  284. public void DumpPolar()
  285. {
  286. Debug.WriteLine(string.Format("{0} * e^(i * {1})", Modulus, Argument));
  287. }
  288. private double Truncate(double dval, int ndigs)
  289. {
  290. // MBP rounding algorithm
  291. // ndigs = number of decimal digits
  292. double rndfac = Math.Pow(10, ndigs);
  293. dval *= rndfac;
  294. dval = Math.Round(dval);
  295. dval /= rndfac;
  296. return dval;
  297. }
  298. public Complex Round(int ndigs)
  299. {
  300. var z = new Complex(this);
  301. z.RealNumber = Truncate(z.RealNumber, ndigs);
  302. z.ImaginaryNumber = Truncate(z.ImaginaryNumber, ndigs);
  303. return z;
  304. }
  305. public bool Equals(Complex other)
  306. {
  307. return _realNumber.Equals(other._realNumber) && _imaginaryNumber.Equals(other._imaginaryNumber);
  308. }
  309. public override bool Equals(object obj)
  310. {
  311. if (ReferenceEquals(null, obj)) return false;
  312. return obj is Complex && Equals((Complex)obj);
  313. }
  314. }
  315. }

comments powered by Disqus