@@ -173,13 +173,22 @@ defmodule Complex do
173173
174174 iex> Complex.parse("Inf-NaNi")
175175 {%Complex{im: :nan, re: :infinity}, ""}
176+
177+ iex> Complex.parse("Inf")
178+ {%Complex{im: 0.0, re: :infinity}, ""}
176179 """
177180 @ spec parse ( String . t ( ) ) :: { t , String . t ( ) } | :error
178181 def parse ( str ) do
179182 with { real_part , sign_multiplier , tail } <- parse_real ( str ) ,
180183 { imag_part , tail } <- parse_imag ( tail ) do
181184 { new ( real_part , multiply ( sign_multiplier , imag_part ) ) , tail }
182185 else
186+ { :imag_non_finite , { imag_part , tail } } ->
187+ { new ( 0 , imag_part ) , tail }
188+
189+ { :real_non_finite , { real_part , tail } } ->
190+ { new ( real_part , 0 ) , tail }
191+
183192 _ ->
184193 case parse_imag ( str ) do
185194 :error -> :error
@@ -201,6 +210,14 @@ defmodule Complex do
201210 defp parse_real ( "+NaN-" <> tail ) , do: { :nan , - 1 , tail }
202211 defp parse_real ( "-NaN-" <> tail ) , do: { :nan , - 1 , tail }
203212
213+ defp parse_real ( "Infi" <> tail ) , do: { :imag_non_finite , { :infinity , tail } }
214+ defp parse_real ( "-Infi" <> tail ) , do: { :imag_non_finite , { :neg_infinity , tail } }
215+ defp parse_real ( "NaNi" <> tail ) , do: { :imag_non_finite , { :nan , tail } }
216+
217+ defp parse_real ( "Inf" <> tail ) , do: { :real_non_finite , { :infinity , tail } }
218+ defp parse_real ( "-Inf" <> tail ) , do: { :real_non_finite , { :neg_infinity , tail } }
219+ defp parse_real ( "NaN" <> tail ) , do: { :real_non_finite , { :nan , tail } }
220+
204221 defp parse_real ( str ) do
205222 case Float . parse ( str ) do
206223 { val , ".+" <> tail } -> { val , 1 , tail }
@@ -291,9 +308,14 @@ defmodule Complex do
291308 def phase ( :infinity ) , do: 0
292309 def phase ( :neg_infinity ) , do: :math . pi ( )
293310
294- def phase ( % Complex { re: :nan , im: im } ) when im == 0 , do: :nan
295- def phase ( % Complex { re: :infinity , im: im } ) when im == 0 , do: 0
296- def phase ( % Complex { re: :neg_infinity , im: im } ) when im == 0 , do: :math . pi ( )
311+ def phase ( % Complex { re: :nan , im: im } ) when is_number ( im ) , do: :nan
312+ def phase ( % Complex { re: :infinity , im: im } ) when is_number ( im ) , do: 0
313+ def phase ( % Complex { re: :neg_infinity , im: im } ) when is_number ( im ) , do: :math . pi ( )
314+
315+ def phase ( % Complex { re: :infinity , im: :infinity } ) , do: :math . pi ( ) / 4
316+ def phase ( % Complex { re: :infinity , im: :neg_infinity } ) , do: - :math . pi ( ) / 4
317+ def phase ( % Complex { re: :neg_infinity , im: :infinity } ) , do: 3 * :math . pi ( ) / 4
318+ def phase ( % Complex { re: :neg_infinity , im: :neg_infinity } ) , do: 5 * :math . pi ( ) / 4
297319
298320 def phase ( % Complex { re: :infinity } ) , do: :nan
299321 def phase ( % Complex { re: :neg_infinity } ) , do: :nan
@@ -449,6 +471,9 @@ defmodule Complex do
449471 iex> Complex.multiply(3, Complex.new(1, 2))
450472 %Complex{im: 6.0, re: 3.0}
451473
474+ iex> Complex.multiply(-2, Complex.new(:infinity, :neg_infinity))
475+ %Complex{im: :infinity, re: :neg_infinity}
476+
452477 """
453478 @ spec multiply ( t | number | non_finite_number , t | number | non_finite_number ) ::
454479 t | number | non_finite_number
@@ -475,10 +500,28 @@ defmodule Complex do
475500 def multiply ( :infinity , :neg_infinity ) , do: :neg_infinity
476501 def multiply ( :infinity , :infinity ) , do: :infinity
477502
478- def multiply ( x , % Complex { re: re , im: im } ) when is_non_finite_number ( x ) do
503+ def multiply ( x , % Complex { re: re , im: im } ) when is_non_finite_number ( x ) or is_number ( x ) do
504+ new ( multiply ( re , x ) , multiply ( im , x ) )
505+ end
506+
507+ def multiply ( % Complex { re: re , im: im } , x ) when is_non_finite_number ( x ) or is_number ( x ) do
479508 new ( multiply ( re , x ) , multiply ( im , x ) )
480509 end
481510
511+ def multiply ( % Complex { re: re_l , im: im_l } , % Complex { re: re_r , im: im_r } ) when im_r == 0 do
512+ new ( multiply ( re_r , re_l ) , multiply ( re_r , im_l ) )
513+ end
514+
515+ def multiply ( % Complex { re: re_l , im: im_l } , % Complex { re: re_r , im: im_r } ) when re_r == 0 do
516+ re_result =
517+ case multiply ( im_l , im_r ) do
518+ result when result == 0 -> 0
519+ result -> negate ( result )
520+ end
521+
522+ new ( re_result , multiply ( re_l , im_r ) )
523+ end
524+
482525 def multiply ( left , right ) when is_number ( left ) and is_number ( right ) , do: left * right
483526
484527 def multiply ( left , right ) do
@@ -946,11 +989,11 @@ defmodule Complex do
946989 divide ( new ( 1.0 , 0.0 ) , x )
947990
948991 true ->
949- rho = :math . sqrt ( x . re * x . re + x . im * x . im )
950- theta = :math . atan2 ( x . im , x . re )
951- s = :math . pow ( rho , y . re ) * :math . exp ( - y . im * theta )
952- r = y . re * theta + y . im * :math . log ( rho )
953- new ( s * :math . cos ( r ) , s * :math . sin ( r ) )
992+ rho = abs ( x )
993+ theta = phase ( x )
994+ s = multiply ( power ( rho , y . re ) , exp ( multiply ( negate ( y . im ) , theta ) ) )
995+ r = add ( multiply ( y . re , theta ) , multiply ( y . im , ln ( rho ) ) )
996+ new ( multiply ( s , cos ( r ) ) , multiply ( s , sin ( r ) ) )
954997 end
955998 end
956999
0 commit comments