@@ -389,6 +389,12 @@ defmodule Complex do
389389 @ spec add ( t | number | non_finite_number , t | number | non_finite_number ) ::
390390 t | number | non_finite_number
391391
392+ def add ( z , % Complex { re: re , im: im } ) when z in [ :infinity , :neg_infinity , :nan ] ,
393+ do: Complex . new ( add ( z , re ) , im )
394+
395+ def add ( % Complex { re: re , im: im } , z ) when z in [ :infinity , :neg_infinity , :nan ] ,
396+ do: Complex . new ( add ( z , re ) , im )
397+
392398 def add ( :nan , _ ) , do: :nan
393399 def add ( _ , :nan ) , do: :nan
394400
@@ -431,6 +437,12 @@ defmodule Complex do
431437 @ spec subtract ( t | number | non_finite_number , t | number | non_finite_number ) ::
432438 t | number | non_finite_number
433439
440+ def subtract ( z , % Complex { re: re , im: im } ) when z in [ :infinity , :neg_infinity , :nan ] ,
441+ do: Complex . new ( subtract ( z , re ) , negate ( im ) )
442+
443+ def subtract ( % Complex { re: re , im: im } , z ) when z in [ :infinity , :neg_infinity , :nan ] ,
444+ do: Complex . new ( subtract ( re , z ) , im )
445+
434446 def subtract ( :nan , _ ) , do: :nan
435447 def subtract ( _ , :nan ) , do: :nan
436448 def subtract ( :infinity , :infinity ) , do: :nan
@@ -472,12 +484,22 @@ defmodule Complex do
472484 %Complex{im: 6.0, re: 3.0}
473485
474486 iex> Complex.multiply(-2, Complex.new(:infinity, :neg_infinity))
475- %Complex{im: :infinity , re: :neg_infinity }
487+ %Complex{im: :nan , re: :nan }
476488
477489 """
478490 @ spec multiply ( t | number | non_finite_number , t | number | non_finite_number ) ::
479491 t | number | non_finite_number
480492
493+ def multiply ( x , c = % Complex { re: _re , im: _im } ) when is_non_finite_number ( x ) or is_number ( x ) do
494+ z = new ( x , 0 )
495+ multiply ( z , c )
496+ end
497+
498+ def multiply ( c = % Complex { re: _re , im: _im } , x ) when is_non_finite_number ( x ) or is_number ( x ) do
499+ z = new ( x , 0 )
500+ multiply ( c , z )
501+ end
502+
481503 def multiply ( :infinity , right ) when is_number ( right ) and right > 0 , do: :infinity
482504 def multiply ( :infinity , right ) when right == 0 , do: :nan
483505 def multiply ( :infinity , right ) when is_number ( right ) and right < 0 , do: :neg_infinity
@@ -500,28 +522,6 @@ defmodule Complex do
500522 def multiply ( :infinity , :neg_infinity ) , do: :neg_infinity
501523 def multiply ( :infinity , :infinity ) , do: :infinity
502524
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
508- new ( multiply ( re , x ) , multiply ( im , x ) )
509- end
510-
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-
525525 def multiply ( left , right ) when is_number ( left ) and is_number ( right ) , do: left * right
526526
527527 def multiply ( left , right ) do
@@ -569,33 +569,43 @@ defmodule Complex do
569569 def divide ( x , y ) when is_non_finite_number ( x ) and is_non_finite_number ( y ) , do: :nan
570570 def divide ( x , y ) when is_non_finite_number ( x ) and is_number ( y ) and y >= 0 , do: x
571571 def divide ( x , y ) when x == 0 and y == 0 , do: :nan
572- def divide ( :nan , _ ) , do: :nan
573- def divide ( _ , :nan ) , do: :nan
572+ def divide ( :nan , a ) when is_number ( a ) , do: :nan
573+ def divide ( a , :nan ) when is_number ( a ) , do: :nan
574574 def divide ( :infinity , y ) when is_number ( y ) and y < 0 , do: :neg_infinity
575575 def divide ( :neg_infinity , y ) when is_number ( y ) and y < 0 , do: :infinity
576- def divide ( _ , :infinity ) , do: 0
577- def divide ( _ , :neg_infinity ) , do: 0
576+ def divide ( a , :infinity ) when is_number ( a ) , do: 0
577+ def divide ( a , :neg_infinity ) when is_number ( a ) , do: 0
578578
579579 def divide ( x , y ) when is_number ( x ) and is_number ( y ) , do: x / y
580580
581+ def divide ( n , b ) when is_number ( n ) and b in [ :infinity , :neg_infinity ] do
582+ 0
583+ end
584+
585+ def divide ( n , % Complex { re: re_r , im: im_r } )
586+ when is_number ( n ) and re_r in [ :infinity , :neg_infinity ] and im_r == 0 do
587+ new ( 0 , 0 )
588+ end
589+
590+ def divide ( % Complex { re: re , im: im } , b )
591+ when is_number ( re ) and is_number ( im ) and b in [ :infinity , :neg_infinity ] do
592+ new ( 0 , 0 )
593+ end
594+
595+ def divide ( % Complex { re: re , im: im } , % Complex { re: re_r , im: im_r } )
596+ when is_number ( re ) and is_number ( im ) and re_r in [ :infinity , :neg_infinity ] and im_r == 0 do
597+ new ( 0 , 0 )
598+ end
599+
581600 def divide ( x , y ) do
582601 % Complex { re: r1 , im: i1 } = as_complex ( x )
583602 % Complex { re: r2 , im: i2 } = as_complex ( y )
584603
585- cond do
586- i2 == 0 ->
587- new ( divide ( r1 , r2 ) , divide ( i1 , r2 ) )
588-
589- r2 == 0 ->
590- new ( divide ( i1 , i2 ) , negate ( divide ( r1 , i2 ) ) )
591-
592- true ->
593- num_re = add ( multiply ( r1 , r2 ) , multiply ( i1 , i2 ) )
594- num_im = subtract ( multiply ( i1 , r2 ) , multiply ( r1 , i2 ) )
595- den = add ( square ( r2 ) , square ( i2 ) )
604+ num_re = add ( multiply ( r1 , r2 ) , multiply ( i1 , i2 ) )
605+ num_im = subtract ( multiply ( i1 , r2 ) , multiply ( r1 , i2 ) )
606+ den = add ( square ( r2 ) , square ( i2 ) )
596607
597- new ( divide ( num_re , den ) , divide ( num_im , den ) )
598- end
608+ new ( divide ( num_re , den ) , divide ( num_im , den ) )
599609 end
600610
601611 @ doc """
@@ -939,13 +949,49 @@ defmodule Complex do
939949 def log10 ( z )
940950
941951 def log10 ( :infinity ) , do: :infinity
942- def log10 ( :neg_infinity ) , do: divide ( log ( :neg_infinity ) , :math . log ( 10 ) )
952+
953+ def log10 ( :neg_infinity ) do
954+ new ( :infinity , :math . pi ( ) / :math . log ( 10 ) )
955+ end
956+
943957 def log10 ( :nan ) , do: :nan
944958 def log10 ( n ) when is_number ( n ) and n == 0 , do: :neg_infinity
945959 def log10 ( n ) when is_number ( n ) and n < 0 , do: :nan
946960
947961 def log10 ( n ) when is_number ( n ) , do: :math . log10 ( n )
948962
963+ def log10 ( % Complex { re: :infinity , im: im } ) when is_number ( im ) do
964+ new ( :infinity , 0 )
965+ end
966+
967+ def log10 ( % Complex { re: :neg_infinity , im: im } ) when is_number ( im ) do
968+ new ( :infinity , :math . pi ( ) / :math . log ( 10 ) )
969+ end
970+
971+ def log10 ( % Complex { im: :infinity , re: re } ) when is_number ( re ) do
972+ new ( :infinity , :math . pi ( ) / ( 2 * :math . log ( 10 ) ) )
973+ end
974+
975+ def log10 ( % Complex { im: :neg_infinity , re: re } ) when is_number ( re ) do
976+ new ( :infinity , - :math . pi ( ) / ( 2 * :math . log ( 10 ) ) )
977+ end
978+
979+ def log10 ( % Complex { re: :infinity , im: :infinity } ) do
980+ new ( :infinity , :math . pi ( ) / ( 4 * :math . log ( 10 ) ) )
981+ end
982+
983+ def log10 ( % Complex { re: :infinity , im: :neg_infinity } ) do
984+ new ( :infinity , - :math . pi ( ) / ( 4 * :math . log ( 10 ) ) )
985+ end
986+
987+ def log10 ( % Complex { re: :neg_infinity , im: :neg_infinity } ) do
988+ new ( :infinity , - 3 * :math . pi ( ) / ( 4 * :math . log ( 10 ) ) )
989+ end
990+
991+ def log10 ( % Complex { re: :neg_infinity , im: :infinity } ) do
992+ new ( :infinity , 3 * :math . pi ( ) / ( 4 * :math . log ( 10 ) ) )
993+ end
994+
949995 def log10 ( z = % Complex { } ) do
950996 divide ( log ( z ) , new ( :math . log ( 10.0 ) , 0.0 ) )
951997 end
@@ -975,6 +1021,38 @@ defmodule Complex do
9751021
9761022 def log2 ( n ) when is_number ( n ) , do: :math . log2 ( n )
9771023
1024+ def log2 ( % Complex { re: :infinity , im: im } ) when is_number ( im ) do
1025+ new ( :infinity , 0 )
1026+ end
1027+
1028+ def log2 ( % Complex { re: :neg_infinity , im: im } ) when is_number ( im ) do
1029+ new ( :infinity , :math . pi ( ) / :math . log ( 2 ) )
1030+ end
1031+
1032+ def log2 ( % Complex { im: :infinity , re: re } ) when is_number ( re ) do
1033+ new ( :infinity , :math . pi ( ) / ( 2 * :math . log ( 2 ) ) )
1034+ end
1035+
1036+ def log2 ( % Complex { im: :neg_infinity , re: re } ) when is_number ( re ) do
1037+ new ( :infinity , - :math . pi ( ) / ( 2 * :math . log ( 2 ) ) )
1038+ end
1039+
1040+ def log2 ( % Complex { re: :infinity , im: :infinity } ) do
1041+ new ( :infinity , :math . pi ( ) / ( 4 * :math . log ( 2 ) ) )
1042+ end
1043+
1044+ def log2 ( % Complex { re: :infinity , im: :neg_infinity } ) do
1045+ new ( :infinity , - :math . pi ( ) / ( 4 * :math . log ( 2 ) ) )
1046+ end
1047+
1048+ def log2 ( % Complex { re: :neg_infinity , im: :neg_infinity } ) do
1049+ new ( :infinity , - 3 * :math . pi ( ) / ( 4 * :math . log ( 2 ) ) )
1050+ end
1051+
1052+ def log2 ( % Complex { re: :neg_infinity , im: :infinity } ) do
1053+ new ( :infinity , 3 * :math . pi ( ) / ( 4 * :math . log ( 2 ) ) )
1054+ end
1055+
9781056 def log2 ( z = % Complex { } ) do
9791057 divide ( log ( z ) , new ( :math . log ( 2.0 ) , 0.0 ) )
9801058 end
@@ -996,6 +1074,18 @@ defmodule Complex do
9961074 @ spec pow ( t | non_finite_number | number , t | non_finite_number | number ) ::
9971075 t | non_finite_number | number
9981076
1077+ def pow ( % Complex { re: re , im: im } , :infinity ) when re == 0 and im == 0 , do: new ( 0 , 0 )
1078+
1079+ def pow ( % Complex { re: re , im: im } , % Complex { re: :infinity , im: im_r } )
1080+ when re == 0 and im == 0 and im_r == 0 ,
1081+ do: new ( 0 , 0 )
1082+
1083+ def pow ( z , % Complex { } ) when is_non_finite_number ( z ) , do: new ( :nan , :nan )
1084+ def pow ( % Complex { } , z ) when is_non_finite_number ( z ) , do: new ( :nan , :nan )
1085+ def pow ( % Complex { re: z } , _ ) when is_non_finite_number ( z ) , do: new ( :nan , :nan )
1086+ def pow ( % Complex { im: z } , _ ) when is_non_finite_number ( z ) , do: new ( :nan , :nan )
1087+ def pow ( _ , % Complex { re: z } ) when is_non_finite_number ( z ) , do: new ( :nan , :nan )
1088+ def pow ( _ , % Complex { im: z } ) when is_non_finite_number ( z ) , do: new ( :nan , :nan )
9991089 def pow ( :nan , _ ) , do: :nan
10001090 def pow ( _ , :nan ) , do: :nan
10011091
@@ -1015,9 +1105,8 @@ defmodule Complex do
10151105 def pow ( :neg_infinity , y ) when is_number ( y ) and y < 0 , do: 0
10161106
10171107 def pow ( x , :infinity ) when x == 0 , do: 0
1018- def pow ( % Complex { re: re , im: im } , :infinity ) when re == 0 and im == 0 , do: 0
10191108 def pow ( x , :neg_infinity ) when x == 0 , do: :infinity
1020- def pow ( % Complex { re: re , im: im } , :neg_infinity ) when re == 0 and im == 0 , do: :infinity
1109+ def pow ( % Complex { re: re , im: im } , :neg_infinity ) when re == 0 and im == 0 , do: new ( :infinity , 0 )
10211110 def pow ( _ , :neg_infinity ) , do: 0
10221111 def pow ( _ , :infinity ) , do: :infinity
10231112
@@ -1308,14 +1397,16 @@ defmodule Complex do
13081397 def atan2 ( :infinity , :infinity ) , do: :math . pi ( ) / 4
13091398 def atan2 ( :infinity , :neg_infinity ) , do: 3 * :math . pi ( ) / 4
13101399 def atan2 ( :infinity , :nan ) , do: :nan
1311- def atan2 ( :infinity , _ ) , do: :math . pi ( ) / 2
1400+ def atan2 ( :infinity , a ) when is_number ( a ) , do: :math . pi ( ) / 2
13121401 def atan2 ( :neg_infinity , :infinity ) , do: - :math . pi ( ) / 4
13131402 def atan2 ( :neg_infinity , :neg_infinity ) , do: - 3 * :math . pi ( ) / 4
13141403 def atan2 ( :neg_infinity , :nan ) , do: :nan
1315- def atan2 ( :neg_infinity , _ ) , do: - :math . pi ( ) / 2
1316- def atan2 ( :nan , _ ) , do: :nan
1317- def atan2 ( _ , :infinity ) , do: 0
1318- def atan2 ( _ , :neg_infinity ) , do: :math . pi ( )
1404+ def atan2 ( :neg_infinity , a ) when is_number ( a ) , do: - :math . pi ( ) / 2
1405+ def atan2 ( :nan , a ) when is_number ( a ) or is_non_finite_number ( a ) , do: :nan
1406+ def atan2 ( a , :nan ) when is_number ( a ) or is_non_finite_number ( a ) , do: :nan
1407+ def atan2 ( :nan , :nan ) , do: :nan
1408+ def atan2 ( a , :infinity ) when is_number ( a ) , do: 0
1409+ def atan2 ( a , :neg_infinity ) when is_number ( a ) , do: :math . pi ( )
13191410
13201411 def atan2 ( b , a ) do
13211412 a = as_complex ( a )
@@ -1416,7 +1507,7 @@ defmodule Complex do
14161507 ### Examples
14171508
14181509 iex> Complex.asec(Complex.from_polar(2,:math.pi))
1419- %Complex{im: 0.0, re: 2.0943951023931957}
1510+ %Complex{im: - 0.0, re: 2.0943951023931957}
14201511
14211512 iex> Complex.sec(Complex.asec(Complex.new(2,3)))
14221513 %Complex{im: 2.9999999999999982, re: 1.9999999999999987}
0 commit comments