complex.nim 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2010 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements complex numbers
  10. ## and basic mathematical operations on them.
  11. ##
  12. ## Complex numbers are currently generic over 64-bit or 32-bit floats.
  13. runnableExamples:
  14. from std/math import almostEqual, sqrt
  15. let
  16. z1 = complex(1.0, 2.0)
  17. z2 = complex(3.0, -4.0)
  18. assert almostEqual(z1 + z2, complex(4.0, -2.0))
  19. assert almostEqual(z1 - z2, complex(-2.0, 6.0))
  20. assert almostEqual(z1 * z2, complex(11.0, 2.0))
  21. assert almostEqual(z1 / z2, complex(-0.2, 0.4))
  22. assert almostEqual(abs(z1), sqrt(5.0))
  23. assert almostEqual(conjugate(z1), complex(1.0, -2.0))
  24. let (r, phi) = z1.polar
  25. assert almostEqual(rect(r, phi), z1)
  26. {.push checks: off, line_dir: off, stack_trace: off, debugger: off.}
  27. # the user does not want to trace a part of the standard library!
  28. import std/[math, strformat]
  29. type
  30. Complex*[T: SomeFloat] = object
  31. ## A complex number, consisting of a real and an imaginary part.
  32. re*, im*: T
  33. Complex64* = Complex[float64]
  34. ## Alias for a complex number using 64-bit floats.
  35. Complex32* = Complex[float32]
  36. ## Alias for a complex number using 32-bit floats.
  37. func complex*[T: SomeFloat](re: T; im: T = 0.0): Complex[T] =
  38. ## Returns a `Complex[T]` with real part `re` and imaginary part `im`.
  39. result = Complex[T](re: re, im: im)
  40. func complex32*(re: float32; im: float32 = 0.0): Complex32 =
  41. ## Returns a `Complex32` with real part `re` and imaginary part `im`.
  42. result = Complex32(re: re, im: im)
  43. func complex64*(re: float64; im: float64 = 0.0): Complex64 =
  44. ## Returns a `Complex64` with real part `re` and imaginary part `im`.
  45. result = Complex64(re: re, im: im)
  46. template im*(arg: typedesc[float32]): Complex32 = complex32(0, 1)
  47. ## Returns the imaginary unit (`complex32(0, 1)`).
  48. template im*(arg: typedesc[float64]): Complex64 = complex64(0, 1)
  49. ## Returns the imaginary unit (`complex64(0, 1)`).
  50. template im*(arg: float32): Complex32 = complex32(0, arg)
  51. ## Returns `arg` as an imaginary number (`complex32(0, arg)`).
  52. template im*(arg: float64): Complex64 = complex64(0, arg)
  53. ## Returns `arg` as an imaginary number (`complex64(0, arg)`).
  54. func abs*[T](z: Complex[T]): T =
  55. ## Returns the absolute value of `z`,
  56. ## that is the distance from (0, 0) to `z`.
  57. result = hypot(z.re, z.im)
  58. func abs2*[T](z: Complex[T]): T =
  59. ## Returns the squared absolute value of `z`,
  60. ## that is the squared distance from (0, 0) to `z`.
  61. ## This is more efficient than `abs(z) ^ 2`.
  62. result = z.re * z.re + z.im * z.im
  63. func sgn*[T](z: Complex[T]): Complex[T] =
  64. ## Returns the phase of `z` as a unit complex number,
  65. ## or 0 if `z` is 0.
  66. let a = abs(z)
  67. if a != 0:
  68. result = z / a
  69. else:
  70. result = Complex[T]()
  71. func conjugate*[T](z: Complex[T]): Complex[T] =
  72. ## Returns the complex conjugate of `z` (`complex(z.re, -z.im)`).
  73. result = Complex[T](re: z.re, im: -z.im)
  74. func inv*[T](z: Complex[T]): Complex[T] =
  75. ## Returns the multiplicative inverse of `z` (`1/z`).
  76. result = conjugate(z) / abs2(z)
  77. func `==`*[T](x, y: Complex[T]): bool =
  78. ## Compares two complex numbers for equality.
  79. result = x.re == y.re and x.im == y.im
  80. func `+`*[T](x: T; y: Complex[T]): Complex[T] =
  81. ## Adds a real number to a complex number.
  82. result = Complex[T](re: x + y.re, im: y.im)
  83. func `+`*[T](x: Complex[T]; y: T): Complex[T] =
  84. ## Adds a complex number to a real number.
  85. result = Complex[T](re: x.re + y, im: x.im)
  86. func `+`*[T](x, y: Complex[T]): Complex[T] =
  87. ## Adds two complex numbers.
  88. result = Complex[T](re: x.re + y.re, im: x.im + y.im)
  89. func `-`*[T](z: Complex[T]): Complex[T] =
  90. ## Unary minus for complex numbers.
  91. result = Complex[T](re: -z.re, im: -z.im)
  92. func `-`*[T](x: T; y: Complex[T]): Complex[T] =
  93. ## Subtracts a complex number from a real number.
  94. result = Complex[T](re: x - y.re, im: -y.im)
  95. func `-`*[T](x: Complex[T]; y: T): Complex[T] =
  96. ## Subtracts a real number from a complex number.
  97. result = Complex[T](re: x.re - y, im: x.im)
  98. func `-`*[T](x, y: Complex[T]): Complex[T] =
  99. ## Subtracts two complex numbers.
  100. result = Complex[T](re: x.re - y.re, im: x.im - y.im)
  101. func `*`*[T](x: T; y: Complex[T]): Complex[T] =
  102. ## Multiplies a real number with a complex number.
  103. result = Complex[T](re: x * y.re, im: x * y.im)
  104. func `*`*[T](x: Complex[T]; y: T): Complex[T] =
  105. ## Multiplies a complex number with a real number.
  106. result = Complex[T](re: x.re * y, im: x.im * y)
  107. func `*`*[T](x, y: Complex[T]): Complex[T] =
  108. ## Multiplies two complex numbers.
  109. result = Complex[T](re: x.re * y.re - x.im * y.im,
  110. im: x.im * y.re + x.re * y.im)
  111. func `/`*[T](x: Complex[T]; y: T): Complex[T] =
  112. ## Divides a complex number by a real number.
  113. result = Complex[T](re: x.re / y, im: x.im / y)
  114. func `/`*[T](x: T; y: Complex[T]): Complex[T] =
  115. ## Divides a real number by a complex number.
  116. result = x * inv(y)
  117. func `/`*[T](x, y: Complex[T]): Complex[T] =
  118. ## Divides two complex numbers.
  119. x * conjugate(y) / abs2(y)
  120. func `+=`*[T](x: var Complex[T]; y: Complex[T]) =
  121. ## Adds `y` to `x`.
  122. x.re += y.re
  123. x.im += y.im
  124. func `-=`*[T](x: var Complex[T]; y: Complex[T]) =
  125. ## Subtracts `y` from `x`.
  126. x.re -= y.re
  127. x.im -= y.im
  128. func `*=`*[T](x: var Complex[T]; y: Complex[T]) =
  129. ## Multiplies `x` by `y`.
  130. let im = x.im * y.re + x.re * y.im
  131. x.re = x.re * y.re - x.im * y.im
  132. x.im = im
  133. func `/=`*[T](x: var Complex[T]; y: Complex[T]) =
  134. ## Divides `x` by `y` in place.
  135. x = x / y
  136. func sqrt*[T](z: Complex[T]): Complex[T] =
  137. ## Computes the
  138. ## ([principal](https://en.wikipedia.org/wiki/Square_root#Principal_square_root_of_a_complex_number))
  139. ## square root of a complex number `z`.
  140. var x, y, w, r: T
  141. if z.re == 0.0 and z.im == 0.0:
  142. result = z
  143. else:
  144. x = abs(z.re)
  145. y = abs(z.im)
  146. if x >= y:
  147. r = y / x
  148. w = sqrt(x) * sqrt(0.5 * (1.0 + sqrt(1.0 + r * r)))
  149. else:
  150. r = x / y
  151. w = sqrt(y) * sqrt(0.5 * (r + sqrt(1.0 + r * r)))
  152. if z.re >= 0.0:
  153. result = Complex[T](re: w, im: z.im / (w * 2.0))
  154. else:
  155. result = Complex[T](im: if z.im >= 0.0: w else: -w)
  156. result.re = z.im / (result.im + result.im)
  157. func exp*[T](z: Complex[T]): Complex[T] =
  158. ## Computes the exponential function (`e^z`).
  159. let
  160. rho = exp(z.re)
  161. theta = z.im
  162. result = Complex[T](re: rho * cos(theta), im: rho * sin(theta))
  163. func ln*[T](z: Complex[T]): Complex[T] =
  164. ## Returns the
  165. ## ([principal value](https://en.wikipedia.org/wiki/Complex_logarithm#Principal_value)
  166. ## of the) natural logarithm of `z`.
  167. result = Complex[T](re: ln(abs(z)), im: arctan2(z.im, z.re))
  168. func log10*[T](z: Complex[T]): Complex[T] =
  169. ## Returns the logarithm base 10 of `z`.
  170. ##
  171. ## **See also:**
  172. ## * `ln func<#ln,Complex[T]>`_
  173. result = ln(z) / ln(10.0)
  174. func log2*[T](z: Complex[T]): Complex[T] =
  175. ## Returns the logarithm base 2 of `z`.
  176. ##
  177. ## **See also:**
  178. ## * `ln func<#ln,Complex[T]>`_
  179. result = ln(z) / ln(2.0)
  180. func pow*[T](x, y: Complex[T]): Complex[T] =
  181. ## `x` raised to the power of `y`.
  182. if x.re == 0.0 and x.im == 0.0:
  183. if y.re == 0.0 and y.im == 0.0:
  184. result = Complex[T](re: 1.0, im: 0.0)
  185. else:
  186. result = Complex[T](re: 0.0, im: 0.0)
  187. elif y.im == 0.0:
  188. if y.re == 1.0:
  189. result = x
  190. elif y.re == -1.0:
  191. result = T(1.0) / x
  192. elif y.re == 2.0:
  193. result = x * x
  194. elif y.re == 0.5:
  195. result = sqrt(x)
  196. elif x.im == 0.0:
  197. # Revert to real pow when both base and exponent are real
  198. result = Complex[T](re: pow(x.re, y.re), im: 0.0)
  199. else:
  200. # Special case when the exponent is real
  201. let
  202. rho = abs(x)
  203. theta = arctan2(x.im, x.re)
  204. s = pow(rho, y.re)
  205. r = y.re * theta
  206. result = Complex[T](re: s * cos(r), im: s * sin(r))
  207. elif x.im == 0.0 and x.re == E:
  208. # Special case Euler's formula
  209. result = exp(y)
  210. else:
  211. let
  212. rho = abs(x)
  213. theta = arctan2(x.im, x.re)
  214. s = pow(rho, y.re) * exp(-y.im * theta)
  215. r = y.re * theta + y.im * ln(rho)
  216. result = Complex[T](re: s * cos(r), im: s * sin(r))
  217. func pow*[T](x: Complex[T]; y: T): Complex[T] =
  218. ## The complex number `x` raised to the power of the real number `y`.
  219. pow(x, complex[T](y))
  220. func sin*[T](z: Complex[T]): Complex[T] =
  221. ## Returns the sine of `z`.
  222. result = Complex[T](re: sin(z.re) * cosh(z.im), im: cos(z.re) * sinh(z.im))
  223. func arcsin*[T](z: Complex[T]): Complex[T] =
  224. ## Returns the inverse sine of `z`.
  225. result = -im(T) * ln(im(T) * z + sqrt(T(1.0) - z*z))
  226. func cos*[T](z: Complex[T]): Complex[T] =
  227. ## Returns the cosine of `z`.
  228. result = Complex[T](re: cos(z.re) * cosh(z.im),
  229. im: -sin(z.re) * sinh(z.im)
  230. )
  231. func arccos*[T](z: Complex[T]): Complex[T] =
  232. ## Returns the inverse cosine of `z`.
  233. result = -im(T) * ln(z + sqrt(z*z - T(1.0)))
  234. func tan*[T](z: Complex[T]): Complex[T] =
  235. ## Returns the tangent of `z`.
  236. result = sin(z) / cos(z)
  237. func arctan*[T](z: Complex[T]): Complex[T] =
  238. ## Returns the inverse tangent of `z`.
  239. result = T(0.5)*im(T) * (ln(T(1.0) - im(T)*z) - ln(T(1.0) + im(T)*z))
  240. func cot*[T](z: Complex[T]): Complex[T] =
  241. ## Returns the cotangent of `z`.
  242. result = cos(z)/sin(z)
  243. func arccot*[T](z: Complex[T]): Complex[T] =
  244. ## Returns the inverse cotangent of `z`.
  245. result = T(0.5)*im(T) * (ln(T(1.0) - im(T)/z) - ln(T(1.0) + im(T)/z))
  246. func sec*[T](z: Complex[T]): Complex[T] =
  247. ## Returns the secant of `z`.
  248. result = T(1.0) / cos(z)
  249. func arcsec*[T](z: Complex[T]): Complex[T] =
  250. ## Returns the inverse secant of `z`.
  251. result = -im(T) * ln(im(T) * sqrt(1.0 - 1.0/(z*z)) + T(1.0)/z)
  252. func csc*[T](z: Complex[T]): Complex[T] =
  253. ## Returns the cosecant of `z`.
  254. result = T(1.0) / sin(z)
  255. func arccsc*[T](z: Complex[T]): Complex[T] =
  256. ## Returns the inverse cosecant of `z`.
  257. result = -im(T) * ln(sqrt(T(1.0) - T(1.0)/(z*z)) + im(T)/z)
  258. func sinh*[T](z: Complex[T]): Complex[T] =
  259. ## Returns the hyperbolic sine of `z`.
  260. result = T(0.5) * (exp(z) - exp(-z))
  261. func arcsinh*[T](z: Complex[T]): Complex[T] =
  262. ## Returns the inverse hyperbolic sine of `z`.
  263. result = ln(z + sqrt(z*z + 1.0))
  264. func cosh*[T](z: Complex[T]): Complex[T] =
  265. ## Returns the hyperbolic cosine of `z`.
  266. result = T(0.5) * (exp(z) + exp(-z))
  267. func arccosh*[T](z: Complex[T]): Complex[T] =
  268. ## Returns the inverse hyperbolic cosine of `z`.
  269. result = ln(z + sqrt(z*z - T(1.0)))
  270. func tanh*[T](z: Complex[T]): Complex[T] =
  271. ## Returns the hyperbolic tangent of `z`.
  272. result = sinh(z) / cosh(z)
  273. func arctanh*[T](z: Complex[T]): Complex[T] =
  274. ## Returns the inverse hyperbolic tangent of `z`.
  275. result = T(0.5) * (ln((T(1.0)+z) / (T(1.0)-z)))
  276. func coth*[T](z: Complex[T]): Complex[T] =
  277. ## Returns the hyperbolic cotangent of `z`.
  278. result = cosh(z) / sinh(z)
  279. func arccoth*[T](z: Complex[T]): Complex[T] =
  280. ## Returns the inverse hyperbolic cotangent of `z`.
  281. result = T(0.5) * (ln(T(1.0) + T(1.0)/z) - ln(T(1.0) - T(1.0)/z))
  282. func sech*[T](z: Complex[T]): Complex[T] =
  283. ## Returns the hyperbolic secant of `z`.
  284. result = T(2.0) / (exp(z) + exp(-z))
  285. func arcsech*[T](z: Complex[T]): Complex[T] =
  286. ## Returns the inverse hyperbolic secant of `z`.
  287. result = ln(1.0/z + sqrt(T(1.0)/z+T(1.0)) * sqrt(T(1.0)/z-T(1.0)))
  288. func csch*[T](z: Complex[T]): Complex[T] =
  289. ## Returns the hyperbolic cosecant of `z`.
  290. result = T(2.0) / (exp(z) - exp(-z))
  291. func arccsch*[T](z: Complex[T]): Complex[T] =
  292. ## Returns the inverse hyperbolic cosecant of `z`.
  293. result = ln(T(1.0)/z + sqrt(T(1.0)/(z*z) + T(1.0)))
  294. func phase*[T](z: Complex[T]): T =
  295. ## Returns the phase (or argument) of `z`, that is the angle in polar representation.
  296. ##
  297. ## | `result = arctan2(z.im, z.re)`
  298. arctan2(z.im, z.re)
  299. func polar*[T](z: Complex[T]): tuple[r, phi: T] =
  300. ## Returns `z` in polar coordinates.
  301. ##
  302. ## | `result.r = abs(z)`
  303. ## | `result.phi = phase(z)`
  304. ##
  305. ## **See also:**
  306. ## * `rect func<#rect,T,T>`_ for the inverse operation
  307. (r: abs(z), phi: phase(z))
  308. func rect*[T](r, phi: T): Complex[T] =
  309. ## Returns the complex number with polar coordinates `r` and `phi`.
  310. ##
  311. ## | `result.re = r * cos(phi)`
  312. ## | `result.im = r * sin(phi)`
  313. ##
  314. ## **See also:**
  315. ## * `polar func<#polar,Complex[T]>`_ for the inverse operation
  316. complex(r * cos(phi), r * sin(phi))
  317. func almostEqual*[T: SomeFloat](x, y: Complex[T]; unitsInLastPlace: Natural = 4): bool =
  318. ## Checks if two complex values are almost equal, using the
  319. ## [machine epsilon](https://en.wikipedia.org/wiki/Machine_epsilon).
  320. ##
  321. ## Two complex values are considered almost equal if their real and imaginary
  322. ## components are almost equal.
  323. ##
  324. ## `unitsInLastPlace` is the max number of
  325. ## [units in the last place](https://en.wikipedia.org/wiki/Unit_in_the_last_place)
  326. ## difference tolerated when comparing two numbers. The larger the value, the
  327. ## more error is allowed. A `0` value means that two numbers must be exactly the
  328. ## same to be considered equal.
  329. ##
  330. ## The machine epsilon has to be scaled to the magnitude of the values used
  331. ## and multiplied by the desired precision in ULPs unless the difference is
  332. ## subnormal.
  333. almostEqual(x.re, y.re, unitsInLastPlace = unitsInLastPlace) and
  334. almostEqual(x.im, y.im, unitsInLastPlace = unitsInLastPlace)
  335. func `$`*(z: Complex): string =
  336. ## Returns `z`'s string representation as `"(re, im)"`.
  337. runnableExamples:
  338. doAssert $complex(1.0, 2.0) == "(1.0, 2.0)"
  339. result = "(" & $z.re & ", " & $z.im & ")"
  340. proc formatValueAsTuple(result: var string; value: Complex; specifier: string) =
  341. ## Format implementation for `Complex` representing the value as a (real, imaginary) tuple.
  342. result.add "("
  343. formatValue(result, value.re, specifier)
  344. result.add ", "
  345. formatValue(result, value.im, specifier)
  346. result.add ")"
  347. proc formatValueAsComplexNumber(result: var string; value: Complex; specifier: string) =
  348. ## Format implementation for `Complex` representing the value as a (RE+IMj) number
  349. ## By default, the real and imaginary parts are formatted using the general ('g') format
  350. let specifier = if specifier.contains({'e', 'E', 'f', 'F', 'g', 'G'}):
  351. specifier.replace("j")
  352. else:
  353. specifier.replace('j', 'g')
  354. result.add "("
  355. formatValue(result, value.re, specifier)
  356. if value.im >= 0 and not specifier.contains({'+', '-'}):
  357. result.add "+"
  358. formatValue(result, value.im, specifier)
  359. result.add "j)"
  360. proc formatValue*(result: var string; value: Complex; specifier: string) =
  361. ## Standard format implementation for `Complex`. It makes little
  362. ## sense to call this directly, but it is required to exist
  363. ## by the `&` macro.
  364. ## For complex numbers, we add a specific 'j' specifier, which formats
  365. ## the value as (A+Bj) like in mathematics.
  366. if specifier.len == 0:
  367. result.add $value
  368. elif 'j' in specifier:
  369. formatValueAsComplexNumber(result, value, specifier)
  370. else:
  371. formatValueAsTuple(result, value, specifier)
  372. {.pop.}