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