@@ -389,6 +389,12 @@ defmodule Complex do
389
389
@ spec add ( t | number | non_finite_number , t | number | non_finite_number ) ::
390
390
t | number | non_finite_number
391
391
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
+
392
398
def add ( :nan , _ ) , do: :nan
393
399
def add ( _ , :nan ) , do: :nan
394
400
@@ -431,6 +437,12 @@ defmodule Complex do
431
437
@ spec subtract ( t | number | non_finite_number , t | number | non_finite_number ) ::
432
438
t | number | non_finite_number
433
439
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
+
434
446
def subtract ( :nan , _ ) , do: :nan
435
447
def subtract ( _ , :nan ) , do: :nan
436
448
def subtract ( :infinity , :infinity ) , do: :nan
@@ -472,12 +484,22 @@ defmodule Complex do
472
484
%Complex{im: 6.0, re: 3.0}
473
485
474
486
iex> Complex.multiply(-2, Complex.new(:infinity, :neg_infinity))
475
- %Complex{im: :infinity , re: :neg_infinity }
487
+ %Complex{im: :nan , re: :nan }
476
488
477
489
"""
478
490
@ spec multiply ( t | number | non_finite_number , t | number | non_finite_number ) ::
479
491
t | number | non_finite_number
480
492
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
+
481
503
def multiply ( :infinity , right ) when is_number ( right ) and right > 0 , do: :infinity
482
504
def multiply ( :infinity , right ) when right == 0 , do: :nan
483
505
def multiply ( :infinity , right ) when is_number ( right ) and right < 0 , do: :neg_infinity
@@ -500,28 +522,6 @@ defmodule Complex do
500
522
def multiply ( :infinity , :neg_infinity ) , do: :neg_infinity
501
523
def multiply ( :infinity , :infinity ) , do: :infinity
502
524
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
-
525
525
def multiply ( left , right ) when is_number ( left ) and is_number ( right ) , do: left * right
526
526
527
527
def multiply ( left , right ) do
@@ -569,33 +569,43 @@ defmodule Complex do
569
569
def divide ( x , y ) when is_non_finite_number ( x ) and is_non_finite_number ( y ) , do: :nan
570
570
def divide ( x , y ) when is_non_finite_number ( x ) and is_number ( y ) and y >= 0 , do: x
571
571
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
574
574
def divide ( :infinity , y ) when is_number ( y ) and y < 0 , do: :neg_infinity
575
575
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
578
578
579
579
def divide ( x , y ) when is_number ( x ) and is_number ( y ) , do: x / y
580
580
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
+
581
600
def divide ( x , y ) do
582
601
% Complex { re: r1 , im: i1 } = as_complex ( x )
583
602
% Complex { re: r2 , im: i2 } = as_complex ( y )
584
603
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 ) )
596
607
597
- new ( divide ( num_re , den ) , divide ( num_im , den ) )
598
- end
608
+ new ( divide ( num_re , den ) , divide ( num_im , den ) )
599
609
end
600
610
601
611
@ doc """
@@ -939,13 +949,49 @@ defmodule Complex do
939
949
def log10 ( z )
940
950
941
951
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
+
943
957
def log10 ( :nan ) , do: :nan
944
958
def log10 ( n ) when is_number ( n ) and n == 0 , do: :neg_infinity
945
959
def log10 ( n ) when is_number ( n ) and n < 0 , do: :nan
946
960
947
961
def log10 ( n ) when is_number ( n ) , do: :math . log10 ( n )
948
962
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
+
949
995
def log10 ( z = % Complex { } ) do
950
996
divide ( log ( z ) , new ( :math . log ( 10.0 ) , 0.0 ) )
951
997
end
@@ -975,6 +1021,38 @@ defmodule Complex do
975
1021
976
1022
def log2 ( n ) when is_number ( n ) , do: :math . log2 ( n )
977
1023
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
+
978
1056
def log2 ( z = % Complex { } ) do
979
1057
divide ( log ( z ) , new ( :math . log ( 2.0 ) , 0.0 ) )
980
1058
end
@@ -996,6 +1074,18 @@ defmodule Complex do
996
1074
@ spec pow ( t | non_finite_number | number , t | non_finite_number | number ) ::
997
1075
t | non_finite_number | number
998
1076
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 )
999
1089
def pow ( :nan , _ ) , do: :nan
1000
1090
def pow ( _ , :nan ) , do: :nan
1001
1091
@@ -1015,9 +1105,8 @@ defmodule Complex do
1015
1105
def pow ( :neg_infinity , y ) when is_number ( y ) and y < 0 , do: 0
1016
1106
1017
1107
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
1019
1108
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 )
1021
1110
def pow ( _ , :neg_infinity ) , do: 0
1022
1111
def pow ( _ , :infinity ) , do: :infinity
1023
1112
@@ -1308,14 +1397,16 @@ defmodule Complex do
1308
1397
def atan2 ( :infinity , :infinity ) , do: :math . pi ( ) / 4
1309
1398
def atan2 ( :infinity , :neg_infinity ) , do: 3 * :math . pi ( ) / 4
1310
1399
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
1312
1401
def atan2 ( :neg_infinity , :infinity ) , do: - :math . pi ( ) / 4
1313
1402
def atan2 ( :neg_infinity , :neg_infinity ) , do: - 3 * :math . pi ( ) / 4
1314
1403
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 ( )
1319
1410
1320
1411
def atan2 ( b , a ) do
1321
1412
a = as_complex ( a )
@@ -1416,7 +1507,7 @@ defmodule Complex do
1416
1507
### Examples
1417
1508
1418
1509
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}
1420
1511
1421
1512
iex> Complex.sec(Complex.asec(Complex.new(2,3)))
1422
1513
%Complex{im: 2.9999999999999982, re: 1.9999999999999987}
0 commit comments