Skip to content

Commit 5cba922

Browse files
committed
Implementation of cmath.acos
1 parent 2a2df0b commit 5cba922

File tree

1 file changed

+64
-9
lines changed

1 file changed

+64
-9
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CmathModuleBuiltins.java

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,30 +145,34 @@ static SpecialType ofDouble(double d) {
145145
@TypeSystemReference(PythonArithmeticTypes.class)
146146
@ImportStatic(MathGuards.class)
147147
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) {
149153
CompilerDirectives.transferToInterpreterAndInvalidate();
150154
throw new IllegalStateException("should not be reached");
151155
}
152156

153157
@Specialization
154-
PComplex doL(long value) {
155-
return compute(value, 0);
158+
PComplex doL(VirtualFrame frame, long value) {
159+
return compute(frame, value, 0);
156160
}
157161

158162
@Specialization
159-
PComplex doD(double value) {
160-
return compute(value, 0);
163+
PComplex doD(VirtualFrame frame, double value) {
164+
return compute(frame, value, 0);
161165
}
162166

163167
@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());
166170
}
167171

168172
@Specialization
169173
PComplex doGeneral(VirtualFrame frame, Object value,
170174
@Cached CoerceToComplexNode coerceToComplex) {
171-
return doC(coerceToComplex.execute(frame, value));
175+
return doC(frame, coerceToComplex.execute(frame, value));
172176
}
173177
}
174178

@@ -491,7 +495,7 @@ abstract static class SqrtNode extends CmathComplexUnaryBuiltinNode {
491495
// @formatter:on
492496

493497
@Override
494-
PComplex compute(double real, double imag) {
498+
PComplex compute(VirtualFrame frame, double real, double imag) {
495499
PComplex result = specialValue(factory(), SPECIAL_VALUES, real, imag);
496500
if (result != null) {
497501
return result;
@@ -520,6 +524,57 @@ PComplex compute(double real, double imag) {
520524
}
521525
return factory().createComplex(d, Math.copySign(s, imag));
522526
}
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+
}
523578
}
524579

525580
@Builtin(name = "isclose", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2, keywordOnlyNames = {"rel_tol", "abs_tol"})

0 commit comments

Comments
 (0)