/src/lib/numeric/complex_general.e

http://github.com/tybor/Liberty · Specman e · 260 lines · 174 code · 30 blank · 56 comment · 0 complexity · 530cc265ee86ad9e380a59b998a0eae0 MD5 · raw file

  1. -- This file is part of a Liberty Eiffel library.
  2. -- See the full copyright at the end.
  3. --
  4. expanded class COMPLEX_GENERAL[A_SIZE -> FLOAT]
  5. --
  6. -- Common ancestor of all complex types: COMPLEX_32, COMPLEX_64, ...
  7. --
  8. insert
  9. NUMERIC
  10. rename sign as real_sign
  11. redefine out, fill_tagged_out_memory
  12. end
  13. MATH_CONSTANTS
  14. -- to get Pi
  15. undefine is_equal, out, fill_tagged_out_memory
  16. end
  17. EXCEPTIONS
  18. undefine is_equal, out, fill_tagged_out_memory
  19. end
  20. feature {ANY}
  21. set_i
  22. -- Set Current to the imaginary unit
  23. do
  24. real := real.zero
  25. imaginary := imaginary.one
  26. end
  27. set, set_cartesian (a_real_part, an_imaginary_part: A_SIZE)
  28. do
  29. real := a_real_part
  30. imaginary := an_imaginary_part
  31. end
  32. set_polar (a_modulus, a_phase: A_SIZE)
  33. do
  34. real := a_modulus * a_phase.cos
  35. imaginary := a_modulus * a_phase.sin
  36. not_yet_implemented
  37. end
  38. feature {ANY}
  39. infix "+" (other: like Current): like Current
  40. do
  41. Result.set(real + other.real, imaginary + other.imaginary)
  42. end
  43. infix "-" (other: like Current): like Current
  44. do
  45. Result.set(real - other.real, imaginary - other.imaginary)
  46. end
  47. infix "*" (other: like Current): like Current
  48. do
  49. Result.set(real * other.real - imaginary * other.imaginary, imaginary * other.real + real * other.imaginary)
  50. end
  51. infix "/" (other: like Current): like Current
  52. local
  53. den: A_SIZE
  54. do
  55. den := other.squared_modulus
  56. Result.set(real * other.real - imaginary * other.imaginary, imaginary * other.real + real * other.imaginary)
  57. end
  58. infix "^" (e: INTEGER): like Current
  59. local
  60. ci, ni: INTEGER
  61. do
  62. -- current index and index of the next iteration
  63. from
  64. Result := Current
  65. ci := 1
  66. ni := 2
  67. until
  68. ni > e
  69. loop
  70. Result := Result * Result
  71. ci := ni
  72. ni := ni * 2
  73. end
  74. from
  75. until
  76. ci = e
  77. loop
  78. Result := Result * Current
  79. ci := ci + 1
  80. end
  81. end
  82. prefix "+": like Current
  83. do
  84. Result := Current
  85. end
  86. prefix "-": like Current
  87. do
  88. Result.set(-real, -imaginary)
  89. end
  90. divisible (other: like Current): BOOLEAN
  91. do
  92. Result := other /= zero
  93. end
  94. hash_code: INTEGER
  95. do
  96. Result := (real + imaginary).hash_code
  97. -- Note: it is debatable if such an hash code implementation is actually useful.
  98. end
  99. real_sign: INTEGER_8
  100. do
  101. Result := real.sign
  102. end
  103. sign: like Current
  104. require
  105. not is_zero
  106. local
  107. coeff: A_SIZE
  108. do
  109. -- See http://en.wikipedia.org/wiki/Sign_function sign is NOT an INTEGER_8 for a complex but like Current!
  110. -- It could be naively implemented with
  111. Result.set_polar(coeff.one, phase)
  112. -- but it may be implemented in a better way.
  113. end
  114. is_zero: BOOLEAN
  115. do
  116. Result := real ~= real.zero and imaginary ~= real.zero
  117. end
  118. zero: like Current
  119. do
  120. Result.set(real.zero, imaginary.zero)
  121. end
  122. one: like Current
  123. do
  124. Result.set(real.one, imaginary.zero)
  125. end
  126. i: like Current
  127. -- Imaginary unit
  128. do
  129. Result.set_i
  130. end
  131. is_equal (other: like Current): BOOLEAN
  132. do
  133. Result := real = other.real and then imaginary = other.imaginary
  134. end
  135. is_near_equal, infix "~=" (other: like Current): BOOLEAN
  136. do
  137. debug
  138. print(&Current + " ~= " + &other + "%N")
  139. end
  140. Result := real ~= other.real and imaginary ~= other.imaginary
  141. end
  142. conjugate: like Current
  143. do
  144. Result.set(real, -imaginary)
  145. end
  146. feature {ANY} -- Cartesian representation
  147. real, imaginary: A_SIZE
  148. feature {ANY} -- Polar representation
  149. modulus: A_SIZE
  150. do
  151. Result := squared_modulus.sqrt
  152. ensure
  153. non_negative: Result.sign /= -1
  154. end
  155. phase: A_SIZE
  156. require
  157. not is_zero
  158. do
  159. not_yet_implemented
  160. -- Pi is not converted automatically to A_SIZE
  161. -- inspect real.sign
  162. -- when 1 then Result := imaginary.atan2(real) -- same as (imaginary/real).atan
  163. -- when -1 then
  164. -- if imaginary.sign = -1 then Result := imaginary.atan2(real) + Pi
  165. -- else Result := imaginary.atan2(real) - Pi
  166. -- end
  167. -- else
  168. -- inspect imaginary.sign
  169. -- when 1 then Result := Pi/2.0
  170. -- when -1 then Result := -Pi/2.0
  171. -- when 0 then raise_exception(Precondition)
  172. -- end
  173. -- end
  174. end
  175. squared_modulus: A_SIZE
  176. do
  177. Result := real * real + imaginary * imaginary
  178. -- Note: NUMERIC does not have infix "^" (an_exponent: INTEGER): like Current...
  179. ensure
  180. non_negative: Result.sign /= -1
  181. end
  182. feature {ANY} -- Object Printing:
  183. out: STRING
  184. -- do
  185. -- Result := "("
  186. -- real.append_in(Result)
  187. -- Result.append(once ", ")
  188. -- imaginary.append_in(Result)
  189. -- Result.append_character(')')
  190. local
  191. real_digits, imaginary_digits: INTEGER
  192. do
  193. -- This is a far and large heuristic way to compute significant decimal digits of floating point number
  194. real_digits := real.mantissa_bits.to_integer_32 // 3
  195. imaginary_digits := imaginary.mantissa_bits.to_integer_32 // 3
  196. create Result.with_capacity(real_digits + imaginary_digits + 6)
  197. Result.append(once "(")
  198. real.append_in_scientific(Result, real_digits)
  199. Result.append(once ", ")
  200. imaginary.append_in_scientific(Result, imaginary_digits)
  201. Result.append(once ")")
  202. end
  203. fill_tagged_out_memory
  204. do
  205. tagged_out_memory.append("real, ")
  206. real.fill_tagged_out_memory
  207. tagged_out_memory.append(" imaginary, ")
  208. imaginary.fill_tagged_out_memory
  209. end
  210. end -- class COMPLEX_GENERAL
  211. --
  212. -- Copyright (C) 2011-2017: by all the people cited in the AUTHORS file.
  213. --
  214. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  215. -- of this software and associated documentation files (the "Software"), to deal
  216. -- in the Software without restriction, including without limitation the rights
  217. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  218. -- copies of the Software, and to permit persons to whom the Software is
  219. -- furnished to do so, subject to the following conditions:
  220. --
  221. -- The above copyright notice and this permission notice shall be included in
  222. -- all copies or substantial portions of the Software.
  223. --
  224. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  225. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  226. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  227. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  228. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  229. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  230. -- THE SOFTWARE.