@@ -145,30 +145,34 @@ static SpecialType ofDouble(double d) {
145
145
@ TypeSystemReference (PythonArithmeticTypes .class )
146
146
@ ImportStatic (MathGuards .class )
147
147
abstract static class CmathComplexUnaryBuiltinNode extends PythonUnaryBuiltinNode {
148
- PComplex compute (@ SuppressWarnings ("unused" ) double real , @ SuppressWarnings ("unused" ) double imag ) {
148
+
149
+ public abstract PComplex executeComplex (VirtualFrame frame , Object value );
150
+
151
+ @ SuppressWarnings ("unused" )
152
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
149
153
CompilerDirectives .transferToInterpreterAndInvalidate ();
150
154
throw new IllegalStateException ("should not be reached" );
151
155
}
152
156
153
157
@ Specialization
154
- PComplex doL (long value ) {
155
- return compute (value , 0 );
158
+ PComplex doL (VirtualFrame frame , long value ) {
159
+ return compute (frame , value , 0 );
156
160
}
157
161
158
162
@ Specialization
159
- PComplex doD (double value ) {
160
- return compute (value , 0 );
163
+ PComplex doD (VirtualFrame frame , double value ) {
164
+ return compute (frame , value , 0 );
161
165
}
162
166
163
167
@ Specialization
164
- PComplex doC (PComplex value ) {
165
- return compute (value .getReal (), value .getImag ());
168
+ PComplex doC (VirtualFrame frame , PComplex value ) {
169
+ return compute (frame , value .getReal (), value .getImag ());
166
170
}
167
171
168
172
@ Specialization
169
173
PComplex doGeneral (VirtualFrame frame , Object value ,
170
174
@ Cached CoerceToComplexNode coerceToComplex ) {
171
- return doC (coerceToComplex .execute (frame , value ));
175
+ return doC (frame , coerceToComplex .execute (frame , value ));
172
176
}
173
177
}
174
178
@@ -491,7 +495,7 @@ abstract static class SqrtNode extends CmathComplexUnaryBuiltinNode {
491
495
// @formatter:on
492
496
493
497
@ Override
494
- PComplex compute (double real , double imag ) {
498
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
495
499
PComplex result = specialValue (factory (), SPECIAL_VALUES , real , imag );
496
500
if (result != null ) {
497
501
return result ;
@@ -520,6 +524,57 @@ PComplex compute(double real, double imag) {
520
524
}
521
525
return factory ().createComplex (d , Math .copySign (s , imag ));
522
526
}
527
+
528
+ static SqrtNode create () {
529
+ return CmathModuleBuiltinsFactory .SqrtNodeFactory .create ();
530
+ }
531
+ }
532
+
533
+ @ Builtin (name = "acos" , minNumOfPositionalArgs = 1 )
534
+ @ GenerateNodeFactory
535
+ abstract static class AcosNode extends CmathComplexUnaryBuiltinNode {
536
+
537
+ @ Child private SqrtNode sqrtNode = SqrtNode .create ();
538
+ @ Child private MathModuleBuiltins .AsinhNode realAsinhNode = MathModuleBuiltins .AsinhNode .create ();
539
+
540
+ // @formatter:off
541
+ @ CompilerDirectives .CompilationFinal (dimensions = 2 )
542
+ private static final ComplexConstant [][] SPECIAL_VALUES = {
543
+ {C (P34 , INF ), C (P , INF ), C (P , INF ), C (P , -INF ), C (P , -INF ), C (P34 , -INF ), C (NAN , INF )},
544
+ {C (P12 , INF ), null , null , null , null , C (P12 , -INF ), C (NAN , NAN )},
545
+ {C (P12 , INF ), null , C (P12 , 0.0 ), C (P12 , -0.0 ), null , C (P12 , -INF ), C (P12 , NAN )},
546
+ {C (P12 , INF ), null , C (P12 , 0.0 ), C (P12 , -0.0 ), null , C (P12 , -INF ), C (P12 , NAN )},
547
+ {C (P12 , INF ), null , null , null , null , C (P12 , -INF ), C (NAN , NAN )},
548
+ {C (P14 , INF ), C (0.0 , INF ), C (0.0 , INF ), C (0.0 , -INF ), C (0.0 , -INF ), C (P14 , -INF ), C (NAN , INF )},
549
+ {C (NAN , INF ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , NAN ), C (NAN , -INF ), C (NAN , NAN )},
550
+ };
551
+ // @formatter:on
552
+
553
+ @ Override
554
+ PComplex compute (VirtualFrame frame , double real , double imag ) {
555
+ PComplex result = specialValue (factory (), SPECIAL_VALUES , real , imag );
556
+ if (result != null ) {
557
+ return result ;
558
+ }
559
+
560
+ double rreal ;
561
+ double rimag ;
562
+ if (Math .abs (real ) > largeDouble || Math .abs (imag ) > largeDouble ) {
563
+ rreal = Math .atan2 (Math .abs (imag ), real );
564
+ double s = Math .log (Math .hypot (real / 2.0 , imag / 2.0 )) + ln2 * 2.0 ;
565
+ if (real < 0.0 ) {
566
+ rimag = -Math .copySign (s , imag );
567
+ } else {
568
+ rimag = Math .copySign (s , -imag );
569
+ }
570
+ } else {
571
+ PComplex s1 = sqrtNode .executeComplex (frame , factory ().createComplex (1.0 - real , -imag ));
572
+ PComplex s2 = sqrtNode .executeComplex (frame , factory ().createComplex (1.0 + real , imag ));
573
+ rreal = 2.0 * Math .atan2 (s1 .getReal (), s2 .getReal ());
574
+ rimag = realAsinhNode .executeObject (frame , s2 .getReal () * s1 .getImag () - s2 .getImag () * s1 .getReal ());
575
+ }
576
+ return factory ().createComplex (rreal , rimag );
577
+ }
523
578
}
524
579
525
580
@ Builtin (name = "isclose" , minNumOfPositionalArgs = 2 , maxNumOfPositionalArgs = 2 , keywordOnlyNames = {"rel_tol" , "abs_tol" })
0 commit comments