@@ -577,6 +577,181 @@ PComplex compute(VirtualFrame frame, double real, double imag) {
577
577
}
578
578
}
579
579
580
+ @ Builtin (name = "acosh" , minNumOfPositionalArgs = 1 )
581
+ @ GenerateNodeFactory
582
+ abstract static class AcoshNode extends CmathComplexUnaryBuiltinNode {
583
+
584
+ @ Child private SqrtNode sqrtNode = SqrtNode .create ();
585
+ @ Child private MathModuleBuiltins .AsinhNode realAsinhNode = MathModuleBuiltins .AsinhNode .create ();
586
+
587
+ // @formatter:off
588
+ @ CompilerDirectives .CompilationFinal (dimensions = 2 )
589
+ private static final ComplexConstant [][] SPECIAL_VALUES = {
590
+ {C (INF , -P34 ), C (INF , -P ), C (INF , -P ), C (INF , P ), C (INF , P ), C (INF , P34 ), C (INF , NAN )},
591
+ {C (INF , -P12 ), null , null , null , null , C (INF , P12 ), C (NAN , NAN )},
592
+ {C (INF , -P12 ), null , C (0.0 , -P12 ), C (0.0 , P12 ), null , C (INF , P12 ), C (NAN , NAN )},
593
+ {C (INF , -P12 ), null , C (0.0 , -P12 ), C (0.0 , P12 ), null , C (INF , P12 ), C (NAN , NAN )},
594
+ {C (INF , -P12 ), null , null , null , null , C (INF , P12 ), C (NAN , NAN )},
595
+ {C (INF , -P14 ), C (INF , -0.0 ), C (INF , -0. ), C (INF , 0.0 ), C (INF , 0.0 ), C (INF , P14 ), C (INF , NAN )},
596
+ {C (INF , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (INF , NAN ), C (NAN , NAN )},
597
+ };
598
+ // @formatter:on
599
+
600
+ @ Override
601
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
602
+ PComplex result = specialValue (factory (), SPECIAL_VALUES , real , imag );
603
+ if (result != null ) {
604
+ return result ;
605
+ }
606
+ double rreal ;
607
+ double rimag ;
608
+ if (Math .abs (real ) > LARGE_DOUBLE || Math .abs (imag ) > LARGE_DOUBLE ) {
609
+ rreal = Math .log (Math .hypot (real / 2.0 , imag / 2.0 )) + LN_2 * 2.0 ;
610
+ rimag = Math .atan2 (imag , real );
611
+ } else {
612
+ PComplex s1 = sqrtNode .executeComplex (frame , factory ().createComplex (real - 1.0 , imag ));
613
+ PComplex s2 = sqrtNode .executeComplex (frame , factory ().createComplex (real + 1.0 , imag ));
614
+ rreal = realAsinhNode .executeObject (frame , s1 .getReal () * s2 .getReal () + s1 .getImag () * s2 .getImag ());
615
+ rimag = 2.0 * Math .atan2 (s1 .getImag (), s2 .getReal ());
616
+ }
617
+ return factory ().createComplex (rreal , rimag );
618
+ }
619
+ }
620
+
621
+ @ Builtin (name = "asin" , minNumOfPositionalArgs = 1 )
622
+ @ GenerateNodeFactory
623
+ abstract static class AsinNode extends CmathComplexUnaryBuiltinNode {
624
+
625
+ @ Child private AsinhNode asinhNode = AsinhNode .create ();
626
+
627
+ @ Override
628
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
629
+ PComplex s = asinhNode .executeComplex (frame , factory ().createComplex (-imag , real ));
630
+ return factory ().createComplex (s .getImag (), -s .getReal ());
631
+ }
632
+ }
633
+
634
+ @ Builtin (name = "asinh" , minNumOfPositionalArgs = 1 )
635
+ @ GenerateNodeFactory
636
+ abstract static class AsinhNode extends CmathComplexUnaryBuiltinNode {
637
+
638
+ @ Child private SqrtNode sqrtNode = SqrtNode .create ();
639
+ @ Child private MathModuleBuiltins .AsinhNode realAsinhNode = MathModuleBuiltins .AsinhNode .create ();
640
+
641
+ // @formatter:off
642
+ @ CompilerDirectives .CompilationFinal (dimensions = 2 )
643
+ private static final ComplexConstant [][] SPECIAL_VALUES = {
644
+ {C (-INF , -P14 ), C (-INF , -0.0 ), C (-INF , -0.0 ), C (-INF , 0.0 ), C (-INF , 0.0 ), C (-INF , P14 ), C (-INF , NAN )},
645
+ {C (-INF , -P12 ), null , null , null , null , C (-INF , P12 ), C (NAN , NAN )},
646
+ {C (-INF , -P12 ), null , C (-0.0 , -0.0 ), C (-0.0 , 0.0 ), null , C (-INF , P12 ), C (NAN , NAN )},
647
+ {C (INF , -P12 ), null , C (0.0 , -0.0 ), C (0.0 , 0.0 ), null , C (INF , P12 ), C (NAN , NAN )},
648
+ {C (INF , -P12 ), null , null , null , null , C (INF , P12 ), C (NAN , NAN )},
649
+ {C (INF , -P14 ), C (INF , -0.0 ), C (INF , -0.0 ), C (INF , 0.0 ), C (INF , 0.0 ), C (INF , P14 ), C (INF , NAN )},
650
+ {C (INF , NAN ), C (NAN , NAN ), C (NAN , -0.0 ), C (NAN , 0.0 ), C (NAN , NAN ), C (INF , NAN ), C (NAN , NAN )},
651
+ };
652
+ // @formatter:on
653
+
654
+ @ Override
655
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
656
+ PComplex result = specialValue (factory (), SPECIAL_VALUES , real , imag );
657
+ if (result != null ) {
658
+ return result ;
659
+ }
660
+ double rreal ;
661
+ double rimag ;
662
+ if (Math .abs (real ) > LARGE_DOUBLE || Math .abs (imag ) > LARGE_DOUBLE ) {
663
+ double s = Math .log (Math .hypot (real / 2.0 , imag / 2.0 )) + LN_2 * 2.0 ;
664
+ if (imag >= 0.0 ) {
665
+ rreal = Math .copySign (s , real );
666
+ } else {
667
+ rreal = -Math .copySign (s , -real );
668
+ }
669
+ rimag = Math .atan2 (imag , Math .abs (real ));
670
+ } else {
671
+ PComplex s1 = sqrtNode .executeComplex (frame , factory ().createComplex (1.0 + imag , -real ));
672
+ PComplex s2 = sqrtNode .executeComplex (frame , factory ().createComplex (1.0 - imag , real ));
673
+ rreal = realAsinhNode .executeObject (frame , s1 .getReal () * s2 .getImag () - s2 .getReal () * s1 .getImag ());
674
+ rimag = Math .atan2 (imag , s1 .getReal () * s2 .getReal () - s1 .getImag () * s2 .getImag ());
675
+ }
676
+ return factory ().createComplex (rreal , rimag );
677
+ }
678
+
679
+ static AsinhNode create () {
680
+ return CmathModuleBuiltinsFactory .AsinhNodeFactory .create ();
681
+ }
682
+ }
683
+
684
+ @ Builtin (name = "atan" , minNumOfPositionalArgs = 1 )
685
+ @ GenerateNodeFactory
686
+ abstract static class AtanNode extends CmathComplexUnaryBuiltinNode {
687
+
688
+ @ Child private AtanhNode atanhNode = AtanhNode .create ();
689
+
690
+ @ Override
691
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
692
+ PComplex s = atanhNode .executeComplex (frame , factory ().createComplex (-imag , real ));
693
+ return factory ().createComplex (s .getImag (), -s .getReal ());
694
+ }
695
+ }
696
+
697
+ @ Builtin (name = "atanh" , minNumOfPositionalArgs = 1 )
698
+ @ GenerateNodeFactory
699
+ abstract static class AtanhNode extends CmathComplexUnaryBuiltinNode {
700
+
701
+ static final double SQRT_LARGE_DOUBLE = Math .sqrt (LARGE_DOUBLE );
702
+ static final double CM_SQRT_DBL_MIN = Math .sqrt (Double .MIN_NORMAL );
703
+
704
+ // @formatter:off
705
+ @ CompilerDirectives .CompilationFinal (dimensions = 2 )
706
+ private static final ComplexConstant [][] SPECIAL_VALUES = {
707
+ {C (-0.0 , -P12 ), C (-0.0 , -P12 ), C (-0.0 , -P12 ), C (-0.0 , P12 ), C (-0.0 , P12 ), C (-0.0 , P12 ), C (-0.0 , NAN )},
708
+ {C (-0.0 , -P12 ), null , null , null , null , C (-0.0 , P12 ), C (NAN , NAN )},
709
+ {C (-0.0 , -P12 ), null , C (-0.0 , -0.0 ), C (-0.0 , 0.0 ), null , C (-0.0 , P12 ), C (-0.0 , NAN )},
710
+ {C (0.0 , -P12 ), null , C (0.0 , -0.0 ), C (0.0 , 0.0 ), null , C (0.0 , P12 ), C (0.0 , NAN )},
711
+ {C (0.0 , -P12 ), null , null , null , null , C (0.0 , P12 ), C (NAN , NAN )},
712
+ {C (0.0 , -P12 ), C (0.0 , -P12 ), C (0.0 , -P12 ), C (0.0 , P12 ), C (0.0 , P12 ), C (0.0 , P12 ), C (0.0 , NAN )},
713
+ {C (0.0 , -P12 ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (0.0 , P12 ), C (NAN , NAN )},
714
+ };
715
+ // @formatter:on
716
+
717
+ @ Override
718
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
719
+ PComplex result = specialValue (factory (), SPECIAL_VALUES , real , imag );
720
+ if (result != null ) {
721
+ return result ;
722
+ }
723
+ if (real < 0.0 ) {
724
+ return computeWithRealPositive (-real , -imag , -1.0 );
725
+ }
726
+ return computeWithRealPositive (real , imag , 1.0 );
727
+ }
728
+
729
+ private PComplex computeWithRealPositive (double real , double imag , double resultScale ) {
730
+ double rreal ;
731
+ double rimag ;
732
+ double ay = Math .abs (imag );
733
+ if (real > SQRT_LARGE_DOUBLE || ay > SQRT_LARGE_DOUBLE ) {
734
+ double h = Math .hypot (real / 2.0 , imag / 2.0 );
735
+ rreal = real / 4.0 / h / h ;
736
+ rimag = -Math .copySign (Math .PI / 2.0 , -imag );
737
+ } else if (real == 1.0 && ay < CM_SQRT_DBL_MIN ) {
738
+ if (ay == 0.0 ) {
739
+ throw raise (ValueError , ErrorMessages .MATH_DOMAIN_ERROR );
740
+ }
741
+ rreal = -Math .log (Math .sqrt (ay ) / Math .sqrt (Math .hypot (ay , 2.0 )));
742
+ rimag = Math .copySign (Math .atan2 (2.0 , -ay ) / 2 , imag );
743
+ } else {
744
+ rreal = Math .log1p (((4.0 * real ) / ((1 - real ) * (1 - real ) + ay * ay ))) / 4.0 ;
745
+ rimag = -Math .atan2 (-2.0 * imag , (1 - real ) * (1 + real ) - ay * ay ) / 2.0 ;
746
+ }
747
+ return factory ().createComplex (resultScale * rreal , resultScale * rimag );
748
+ }
749
+
750
+ static AtanhNode create () {
751
+ return CmathModuleBuiltinsFactory .AtanhNodeFactory .create ();
752
+ }
753
+ }
754
+
580
755
@ Builtin (name = "isclose" , minNumOfPositionalArgs = 2 , maxNumOfPositionalArgs = 2 , keywordOnlyNames = {"rel_tol" , "abs_tol" })
581
756
@ TypeSystemReference (PythonArithmeticTypes .class )
582
757
@ ImportStatic (MathGuards .class )
0 commit comments