diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java index 88bdd0a26bd3b1449cda6f6ced35c8c20854e31f..e8b0a3ede352ad5dd72b25b366d258462993cfe7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abs.java @@ -22,157 +22,69 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.attributes.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.closures.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.ops.na.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; + +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; @RBuiltin(name = "abs", kind = PRIMITIVE, parameterNames = {"x"}) public abstract class Abs extends RBuiltinNode { - @Child private CopyOfRegAttributesNode copyAttributes; - - private final NACheck check = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - - @Specialization - protected int abs(int value) { - controlVisibility(); - check.enable(value); - return performInt(value); - } - - @Specialization - protected int abs(byte value) { - controlVisibility(); - check.enable(value); - if (check.check(value)) { - return RRuntime.INT_NA; - } - return Math.abs(value); - } + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode absNode = UnaryArithmeticNodeGen.create(AbsArithmetic::new, + RError.Message.NON_NUMERIC_MATH, RType.Integer); @Specialization - protected double abs(double value) { - controlVisibility(); - check.enable(value); - return performDouble(value); + protected Object abs(Object value) { + return absNode.execute(boxPrimitive.execute(value)); } - @Specialization - protected double abs(RComplex value) { - controlVisibility(); - check.enable(value); - return performComplex(value); - } + public static class AbsArithmetic extends UnaryArithmetic { - private void copyRegAttributes(RAbstractVector source, RVector target) { - if (copyAttributes == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - copyAttributes = insert(CopyOfRegAttributesNodeGen.create()); + @Override + public RType calculateResultType(RType argumentType) { + switch (argumentType) { + case Complex: + return RType.Double; + default: + return super.calculateResultType(argumentType); + } } - copyAttributes.execute(source, target); - } - - protected boolean isPositiveSequence(RIntSequence sequence) { - return sequence.getStart() >= 0 && (sequence.getStart() + (sequence.getLength() - 1) * (long) sequence.getStride()) <= Integer.MAX_VALUE; - } - @Specialization(guards = "isPositiveSequence(vector)") - protected RIntSequence doAbsIntSequence(RIntSequence vector) { - controlVisibility(); - return vector; - } - - @Specialization - protected RIntVector doAbs(RAbstractIntVector vector) { - controlVisibility(); - check.enable(vector); - int[] intVector = new int[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - intVector[i] = performInt(vector.getDataAt(i)); + @Override + public int op(byte op) { + return Math.abs(op); } - RIntVector res = RDataFactory.createIntVector(intVector, check.neverSeenNA(), vector.getDimensions(), vector.getNames(attrProfiles)); - copyRegAttributes(vector, res); - return res; - } - protected boolean isPositiveSequence(RDoubleSequence sequence) { - return sequence.getStart() >= 0 && sequence.getStride() >= 0; - } - - @Specialization(guards = "isPositiveSequence(vector)") - protected RDoubleSequence doAbsDoubleSequence(RDoubleSequence vector) { - controlVisibility(); - return vector; - } - - @Specialization - protected RDoubleVector abs(RAbstractDoubleVector vector) { - controlVisibility(); - check.enable(vector); - double[] doubleVector = new double[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - doubleVector[i] = performDouble(vector.getDataAt(i)); + @Override + public int op(int op) { + return Math.abs(op); } - RDoubleVector res = RDataFactory.createDoubleVector(doubleVector, check.neverSeenNA(), vector.getDimensions(), vector.getNames(attrProfiles)); - copyRegAttributes(vector, res); - return res; - } - @Specialization - protected RDoubleVector abs(RAbstractComplexVector vector) { - controlVisibility(); - check.enable(vector); - double[] doubleVector = new double[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - doubleVector[i] = performComplex(vector.getDataAt(i)); + @Override + public double op(double op) { + return Math.abs(op); } - RDoubleVector res = RDataFactory.createDoubleVector(doubleVector, check.neverSeenNA(), vector.getDimensions(), vector.getNames(attrProfiles)); - copyRegAttributes(vector, res); - return res; - } - @Specialization - protected RIntVector abs(RAbstractLogicalVector value) { - controlVisibility(); - check.enable(value); - return doAbs(RClosures.createLogicalToIntVector(value)); - } - - @Fallback - @TruffleBoundary - protected Object abs(@SuppressWarnings("unused") Object vector) { - controlVisibility(); - throw RError.error(this, RError.Message.NON_NUMERIC_MATH); - } - - private int performInt(int value) { - if (check.check(value)) { - return RRuntime.INT_NA; + @Override + public RComplex op(double re, double im) { + throw new UnsupportedOperationException(); } - return Math.abs(value); - } - private double performDouble(double value) { - if (check.check(value)) { - return RRuntime.DOUBLE_NA; + @Override + public double opd(double re, double im) { + return RComplex.abs(re, im); } - return Math.abs(value); - } - private double performComplex(RComplex value) { - if (check.check(value)) { - return RRuntime.DOUBLE_NA; - } - return value.abs(); } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java index 2dc20868b4899a43a17d4fac0cc307ce5c0d7784..fc26d9e209823718918541b7e8e8f27eef4fac51 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Ceiling.java @@ -34,11 +34,22 @@ import com.oracle.truffle.r.runtime.ops.*; @RBuiltin(name = "ceiling", kind = PRIMITIVE, parameterNames = {"x"}) public abstract class Ceiling extends RBuiltinNode { + public static final UnaryArithmeticFactory CEILING = CeilingArithmetic::new; + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); - @Child private UnaryArithmeticNode ceiling = UnaryArithmeticNodeGen.create(UnaryArithmetic.CEILING, RError.Message.NON_NUMERIC_MATH, RType.Double); + @Child private UnaryArithmeticNode ceiling = UnaryArithmeticNodeGen.create(CEILING, RError.Message.NON_NUMERIC_MATH, RType.Double); @Specialization protected Object ceiling(Object value) { return ceiling.execute(boxPrimitive.execute(value)); } + + public static class CeilingArithmetic extends Round.RoundArithmetic { + + @Override + public double op(double op) { + return Math.ceil(op); + } + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Conj.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Conj.java index a180cc19ae69068312bd24c132723b0ae383ba29..e6bd1412759d9d12371cf9d7f6627fde0d457a9c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Conj.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Conj.java @@ -22,22 +22,34 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.ops.na.*; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; @RBuiltin(name = "Conj", kind = PRIMITIVE, parameterNames = {"z"}) public abstract class Conj extends RBuiltinNode { - private NACheck naCheck = NACheck.create(); + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode conjNode = UnaryArithmeticNodeGen.create(ConjArithmetic::new, + RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); + + @Specialization + protected Object conj(Object value) { + return conjNode.execute(boxPrimitive.execute(value)); + } @Child private CastDoubleNode castDouble; @@ -49,36 +61,28 @@ public abstract class Conj extends RBuiltinNode { return castDouble.executeDouble(value); } - @Specialization - protected RComplexVector conj(RAbstractComplexVector vector) { - RComplexVector result = (RComplexVector) vector.copy(); - naCheck.enable(vector); - for (int i = 0; i < vector.getLength(); i++) { - RComplex el = vector.getDataAt(i); - if (!naCheck.check(el)) { - result.updateDataAt(i, RDataFactory.createComplex(el.getRealPart(), -el.getImaginaryPart()), naCheck); - } + public static class ConjArithmetic extends UnaryArithmetic { + + @Override + public int op(byte op) { + return op; } - return result; - } - @Specialization - protected RDoubleVector conj(RAbstractDoubleVector vector) { - return (RDoubleVector) vector.copy(); - } + @Override + public int op(int op) { + return op; + } - @Specialization - protected Object conj(RAbstractIntVector vector) { - return castDouble(vector); - } + @Override + public double op(double op) { + return op; + } - @Specialization - protected Object conj(RAbstractLogicalVector vector) { - return castDouble(vector); - } + @Override + public RComplex op(double re, double im) { + return RComplex.valueOf(re, -im); + } - @Fallback - protected Object conj(@SuppressWarnings("unused") Object o) { - throw RError.error(this, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION); } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java index 8d363faa79dbb8163059356d872aa903910d1188..f27bd58ac6d670e39779f44993a2afa16a92c43a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Floor.java @@ -34,11 +34,22 @@ import com.oracle.truffle.r.runtime.ops.*; @RBuiltin(name = "floor", kind = PRIMITIVE, parameterNames = {"x"}) public abstract class Floor extends RBuiltinNode { + public static final UnaryArithmeticFactory FLOOR = FloorArithmetic::new; + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); - @Child private UnaryArithmeticNode floor = UnaryArithmeticNodeGen.create(UnaryArithmetic.FLOOR, RError.Message.NON_NUMERIC_MATH, RType.Double); + @Child private UnaryArithmeticNode floor = UnaryArithmeticNodeGen.create(FLOOR, RError.Message.NON_NUMERIC_MATH, RType.Double); @Specialization protected Object floor(Object value) { return floor.execute(boxPrimitive.execute(value)); } + + public static class FloorArithmetic extends Round.RoundArithmetic { + + @Override + public double op(double op) { + return Math.floor(op); + } + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Im.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Im.java index 3ab06a6e72e2bd01a57989b3149bd85173bf4ef5..cca79acfb3bb3a63531bbb553ecfba19ee139362 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Im.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Im.java @@ -22,47 +22,71 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.nodes.builtin.base.ImNodeGen.ImInternalNodeGen; -import com.oracle.truffle.r.nodes.unary.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.ops.na.*; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; +import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory; @RBuiltin(name = "Im", kind = PRIMITIVE, parameterNames = {"z"}) public abstract class Im extends RBuiltinNode { - @Child private ImInternalNode im = ImInternalNodeGen.create(); + public static final UnaryArithmeticFactory IM = ImArithmetic::new; + + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode imNode = UnaryArithmeticNodeGen.create(IM, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); @Specialization protected Object im(Object value) { - return im.execute(value); + return imNode.execute(boxPrimitive.execute(value)); } - public abstract static class ImInternalNode extends UnaryNode { + public static class ImArithmetic extends UnaryArithmetic { - public abstract RDoubleVector executeRDoubleVector(RAbstractComplexVector vector); + @Override + public RType calculateResultType(RType argumentType) { + switch (argumentType) { + case Complex: + return RType.Double; + default: + return super.calculateResultType(argumentType); + } + } - private NACheck check = NACheck.create(); + @Override + public int op(byte op) { + return 0; + } - @Specialization - protected RDoubleVector im(RAbstractComplexVector vector) { - double[] result = new double[vector.getLength()]; - check.enable(vector); - for (int i = 0; i < vector.getLength(); i++) { - RComplex c = vector.getDataAt(i); - result[i] = check.check(c) ? RRuntime.DOUBLE_NA : c.getImaginaryPart(); - } - return RDataFactory.createDoubleVector(result, check.neverSeenNA()); + @Override + public int op(int op) { + return 0; } - @Specialization - protected RDoubleVector im(RAbstractDoubleVector vector) { - return RDataFactory.createDoubleVector(vector.getLength()); + @Override + public double op(double op) { + return 0; } + + @Override + public RComplex op(double re, double im) { + throw new UnsupportedOperationException(); + } + + @Override + public double opd(double re, double im) { + return im; + } + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java index 25809dc90c8c82c898a2789d1605ff0c45b8b5fe..a05aab28bb59a36cbdd4cddc208917343cba9a25 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java @@ -22,12 +22,26 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; + +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; public class LogFunctions { @RBuiltin(name = "log", kind = PRIMITIVE, parameterNames = {"x", "base"}) @@ -96,128 +110,132 @@ public class LogFunctions { protected static double logb(double x, double base) { return Math.log(x) / Math.log(base); } + } @RBuiltin(name = "log10", kind = PRIMITIVE, parameterNames = {"x"}) public abstract static class Log10 extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode log10Node = UnaryArithmeticNodeGen.create(Log10Arithmetic::new, + RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); - @SuppressWarnings("unused") @Specialization - protected RNull log(RNull x) { - controlVisibility(); - throw RError.error(this, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION); + protected Object log10(Object value) { + return log10Node.execute(boxPrimitive.execute(value)); } - @Specialization - protected double log(int value) { - controlVisibility(); - return Math.log10(value); - } + public static class Log10Arithmetic extends UnaryArithmetic { - @Specialization - protected double log(double value) { - controlVisibility(); - return Math.log10(value); - } + private static final double LOG_10 = Math.log(10); - @Specialization - protected RDoubleVector log(RIntVector vector) { - controlVisibility(); - double[] resultVector = new double[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - int inputValue = vector.getDataAt(i); - double result = RRuntime.DOUBLE_NA; - if (RRuntime.isComplete(inputValue)) { - result = Math.log10(inputValue); - } - resultVector[i] = result; + @Override + public int op(byte op) { + throw new UnsupportedOperationException(); } - RDoubleVector res = RDataFactory.createDoubleVector(resultVector, vector.isComplete(), vector.getNames(attrProfiles)); - res.copyRegAttributesFrom(vector); - return res; - } - @Specialization - protected RDoubleVector log(RDoubleVector vector) { - controlVisibility(); - double[] doubleVector = new double[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - double value = vector.getDataAt(i); - if (RRuntime.isComplete(value)) { - value = Math.log10(value); - } - doubleVector[i] = value; + @Override + public int op(int op) { + throw new UnsupportedOperationException(); } - RDoubleVector res = RDataFactory.createDoubleVector(doubleVector, vector.isComplete(), vector.getNames(attrProfiles)); - res.copyRegAttributesFrom(vector); - return res; + + @Override + public double op(double op) { + return Math.log10(op); + } + + @Override + public RComplex op(double re, double im) { + double arg = Math.atan2(im, re); + double mod = RComplex.abs(re, im); + return RComplex.valueOf(Math.log10(mod), arg / LOG_10); + } + } } @RBuiltin(name = "log2", kind = PRIMITIVE, parameterNames = {"x"}) public abstract static class Log2 extends RBuiltinNode { - private static final double log2value = Math.log(2); + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode log2Node = UnaryArithmeticNodeGen.create(Log2Arithmetic::new, + RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); - @SuppressWarnings("unused") @Specialization - protected RNull log(RNull x) { - controlVisibility(); - throw RError.error(this, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION); + protected Object log2(Object value) { + return log2Node.execute(boxPrimitive.execute(value)); } - @Specialization - protected double log2(int value) { - controlVisibility(); - return log2((double) value); - } + public static class Log2Arithmetic extends UnaryArithmetic { - @Specialization - protected double log2(double value) { - controlVisibility(); - return Math.log(value) / log2value; - } + private static final double LOG_2 = Math.log(2); - @Specialization - protected RDoubleVector log2(RIntVector vector) { - controlVisibility(); - double[] resultVector = new double[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - int inputValue = vector.getDataAt(i); - double result = RRuntime.DOUBLE_NA; - if (RRuntime.isComplete(inputValue)) { - result = log2(inputValue); - } - resultVector[i] = result; + @Override + public int op(byte op) { + throw new UnsupportedOperationException(); } - return RDataFactory.createDoubleVector(resultVector, vector.isComplete()); - } - @Specialization - protected RDoubleVector log2(RDoubleVector vector) { - controlVisibility(); - double[] doubleVector = new double[vector.getLength()]; - for (int i = 0; i < vector.getLength(); i++) { - double value = vector.getDataAt(i); - if (RRuntime.isComplete(value)) { - value = log2(value); - } - doubleVector[i] = value; + @Override + public int op(int op) { + throw new UnsupportedOperationException(); } - return RDataFactory.createDoubleVector(doubleVector, vector.isComplete()); + + @Override + public double op(double op) { + return Math.log(op) / LOG_2; + } + + @Override + public RComplex op(double re, double im) { + double arg = Math.atan2(im, re); + double mod = RComplex.abs(re, im); + return RComplex.valueOf(Math.log(mod) / LOG_2, arg / LOG_2); + } + } + } @RBuiltin(name = "log1p", kind = PRIMITIVE, parameterNames = {"x"}) public abstract static class Log1p extends RBuiltinNode { - @SuppressWarnings("unused") + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode log1pNode = UnaryArithmeticNodeGen.create(Log1pArithmetic::new, + RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); + @Specialization - protected Object log1p(Object x) { - throw RError.nyi(this, "log1p"); + protected Object log1p(Object value) { + return log1pNode.execute(boxPrimitive.execute(value)); + } + + public static class Log1pArithmetic extends UnaryArithmetic { + + @Override + public int op(byte op) { + throw new UnsupportedOperationException(); + } + + @Override + public int op(int op) { + throw new UnsupportedOperationException(); + } + + @Override + public double op(double op) { + return Math.log(1 + op); + } + + @Override + public RComplex op(double r, double i) { + double re = r + 1; + double im = i; + double arg = Math.atan2(im, re); + double mod = RComplex.abs(re, im); + return RComplex.valueOf(Math.log(mod), arg); + } + } + } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mod.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mod.java index 4eff9242b9b8477254cf5ee152a8fb069e575b16..00a7e0336ff7ca6a4661e1bbb1b50683874bd9f1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mod.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mod.java @@ -22,32 +22,68 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.binary.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.nodes.*; -import com.oracle.truffle.r.runtime.ops.*; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; @RBuiltin(name = "Mod", kind = PRIMITIVE, parameterNames = {"z"}) public abstract class Mod extends RBuiltinNode { - @Child private BinaryMapArithmeticFunctionNode pow = new BinaryMapArithmeticFunctionNode(BinaryArithmetic.POW.create()); - @Child private BinaryMapArithmeticFunctionNode add = new BinaryMapArithmeticFunctionNode(BinaryArithmetic.ADD.create()); - @Child private Sqrt sqrt = SqrtNodeGen.create(new RNode[1], null, null); + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode modNode = UnaryArithmeticNodeGen.create(ModArithmetic::new, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); @Specialization - protected RDoubleVector mod(RAbstractComplexVector vec) { - controlVisibility(); - double[] data = new double[vec.getLength()]; - for (int i = 0; i < vec.getLength(); i++) { - RComplex x = vec.getDataAt(i); - data[i] = sqrt.sqrt(add.applyDouble(pow.applyDouble(x.getRealPart(), 2), pow.applyDouble(x.getImaginaryPart(), 2))); + protected Object mod(Object value) { + return modNode.execute(boxPrimitive.execute(value)); + } + + public static class ModArithmetic extends UnaryArithmetic { + + @Override + public RType calculateResultType(RType argumentType) { + switch (argumentType) { + case Complex: + return RType.Double; + default: + return super.calculateResultType(argumentType); + } + } + + @Override + public int op(byte op) { + return op; + } + + @Override + public int op(int op) { + return op; } - return RDataFactory.createDoubleVector(data, RDataFactory.COMPLETE_VECTOR); + + @Override + public double op(double op) { + return op; + } + + @Override + public RComplex op(double re, double im) { + throw new UnsupportedOperationException(); + } + + @Override + public double opd(double re, double im) { + return RComplex.abs(re, im); + } + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java index f522736eca13059849b483f899a3d28d6e06d9d5..576f4e893cab89b10655d26e6038171ac88dfec3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java @@ -31,15 +31,11 @@ import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.access.*; -import com.oracle.truffle.r.nodes.builtin.base.Im.ImInternalNode; -import com.oracle.truffle.r.nodes.builtin.base.ImNodeGen.ImInternalNodeGen; import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrettyPrinterSingleListElementNodeGen; import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrettyPrinterSingleVectorElementNodeGen; import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrintDimNodeGen; import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrintVector2DimNodeGen; import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrintVectorMultiDimNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.Re.ReInternalNode; -import com.oracle.truffle.r.nodes.builtin.base.ReNodeGen.ReInternalNodeGen; import com.oracle.truffle.r.nodes.function.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -76,8 +72,8 @@ public abstract class PrettyPrinterNode extends RNode { @Child private PrettyPrinterSingleVectorElementNode singleVectorElementPrettyPrinter; @Child private PrintVectorMultiDimNode multiDimPrinter; - @Child private ReInternalNode re; - @Child private ImInternalNode im; + @Child private UnaryArithmeticNode re; + @Child private UnaryArithmeticNode im; @Child private IndirectCallNode indirectCall = Truffle.getRuntime().createIndirectCallNode(); @@ -901,12 +897,12 @@ public abstract class PrettyPrinterNode extends RNode { if (re == null) { // the two are allocated side by side; checking for re is sufficient CompilerDirectives.transferToInterpreterAndInvalidate(); - re = insert(ReInternalNodeGen.create()); - im = insert(ImInternalNodeGen.create()); + re = insert(UnaryArithmeticNodeGen.create(Re.RE, RError.Message.NON_NUMERIC_MATH, RType.Double)); + im = insert(UnaryArithmeticNodeGen.create(Im.IM, RError.Message.NON_NUMERIC_MATH, RType.Double)); } - RDoubleVector realParts = re.executeRDoubleVector(operand); - RDoubleVector imaginaryParts = im.executeRDoubleVector(operand); + RAbstractDoubleVector realParts = (RAbstractDoubleVector) re.execute(operand); + RAbstractDoubleVector imaginaryParts = (RAbstractDoubleVector) im.execute(operand); int length = operand.getLength(); String[] realValues = new String[length]; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Re.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Re.java index 639cbfe8793f777bc2ff7c773662ba095c44bea3..3a9514b24c87b8e564dca48e6fba1f17a6f7aab9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Re.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Re.java @@ -22,47 +22,71 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.nodes.builtin.base.ReNodeGen.ReInternalNodeGen; -import com.oracle.truffle.r.nodes.unary.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.ops.na.*; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; +import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory; @RBuiltin(name = "Re", kind = PRIMITIVE, parameterNames = {"z"}) public abstract class Re extends RBuiltinNode { - @Child private ReInternalNode re = ReInternalNodeGen.create(); + public static final UnaryArithmeticFactory RE = ReArithmetic::new; + + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode reNode = UnaryArithmeticNodeGen.create(RE, RError.Message.NON_NUMERIC_ARGUMENT_FUNCTION, RType.Double); @Specialization protected Object re(Object value) { - return re.execute(value); + return reNode.execute(boxPrimitive.execute(value)); } - public abstract static class ReInternalNode extends UnaryNode { + public static class ReArithmetic extends UnaryArithmetic { - public abstract RDoubleVector executeRDoubleVector(Object value); + @Override + public RType calculateResultType(RType argumentType) { + switch (argumentType) { + case Complex: + return RType.Double; + default: + return super.calculateResultType(argumentType); + } + } - private NACheck check = NACheck.create(); + @Override + public int op(byte op) { + return op; + } - @Specialization - protected RDoubleVector re(RAbstractComplexVector vector) { - double[] result = new double[vector.getLength()]; - check.enable(vector); - for (int i = 0; i < vector.getLength(); i++) { - result[i] = vector.getDataAt(i).getRealPart(); - check.check(result[i]); - } - return RDataFactory.createDoubleVector(result, check.neverSeenNA()); + @Override + public int op(int op) { + return op; } - @Specialization - protected RDoubleVector re(RAbstractDoubleVector vector) { - return (RDoubleVector) vector.copy(); + @Override + public double op(double op) { + return op; } + + @Override + public RComplex op(double re, double im) { + throw new UnsupportedOperationException(); + } + + @Override + public double opd(double re, double im) { + return re; + } + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java index 5662f28fcec5ded54024549d9107e3ca4b6d8074..6e131ecbe651a596e65b1e6135a5d733ebf4c5e5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java @@ -22,20 +22,32 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.r.nodes.builtin.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.data.model.*; -import com.oracle.truffle.r.runtime.ops.*; -import com.oracle.truffle.r.runtime.ops.na.*; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributeProfiles; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; +import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory; +import com.oracle.truffle.r.runtime.ops.na.NACheck; @RBuiltin(name = "round", kind = PRIMITIVE, parameterNames = {"x", "digits"}) public abstract class Round extends RBuiltinNode { - @Child private UnaryArithmetic roundOp = UnaryArithmetic.ROUND.create(); + public static final UnaryArithmeticFactory ROUND = RoundArithmetic::new; + + @Child private RoundArithmetic roundOp = new RoundArithmetic(); private final NACheck check = NACheck.create(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @@ -154,4 +166,177 @@ public abstract class Round extends RBuiltinNode { return ret; } + public static class RoundArithmetic extends UnaryArithmetic { + + @Child private BinaryArithmetic pow; + + @Override + public int op(int op) { + return op; + } + + @Override + public double op(double op) { + return Math.rint(op); + } + + @Override + public int op(byte op) { + return op; + } + + @Override + public RComplex op(double re, double im) { + return RDataFactory.createComplex(op(re), op(im)); + } + + public double opd(double op, int digits) { + return fround(op, digits); + } + + public RComplex opd(double re, double im, int digits) { + return zrround(re, im, digits); + } + + // The logic for fround and zrround (z_rround) is derived from GNU R. + + private static final int F_MAX_DIGITS = 308; // IEEE constant + + private double fround(double x, double digits) { + double pow10; + double sgn; + double intx; + int dig; + + if (Double.isNaN(x) || Double.isNaN(digits)) { + return x + digits; + } + if (!RRuntime.isFinite(x)) { + return x; + } + if (digits == Double.POSITIVE_INFINITY) { + return x; + } else if (digits == Double.NEGATIVE_INFINITY) { + return 0.0; + } + + double dd = digits; + double xx = x; + + if (dd > F_MAX_DIGITS) { + dd = F_MAX_DIGITS; + } + + dig = (int) Math.floor(dd + 0.5); + if (xx < 0.0) { + sgn = -1.0; + xx = -xx; + } else { + sgn = 1.0; + } + + if (dig == 0) { + return sgn * op(xx); + } else if (dig > 0) { + pow10 = rpowdi(10.0, dig); + intx = Math.floor(xx); + // System.out.println(String.format("X %.22f RINT1 %.22f POW10 %.22f INTX %.22f", + // new BigDecimal(x), + // new BigDecimal(Math.rint((xx - intx) * pow10)), new BigDecimal(pow10), + // new BigDecimal(intx))); + return sgn * (intx + Math.rint((xx - intx) * pow10) / pow10); + } else { + pow10 = rpowdi(10.0, -dig); + // System.out.println(String.format("RINT2 %.22f", new BigDecimal(Math.rint(xx / + // pow10)))); + return sgn * Math.rint(xx / pow10) * pow10; + } + } + + private double rpowdi(double x, int n) { + double result = 1.0; + + if (Double.isNaN(x)) { + return x; + } + if (n != 0) { + if (!RRuntime.isFinite(x)) { + return rpow(x, n); + } + int nn = n; + double xx = x; + boolean isNeg = (n < 0); + if (isNeg) { + nn = -nn; + } + for (;;) { + if ((nn & 1) != 0) { + result *= xx; + } + if ((nn >>= 1) != 0) { + xx *= xx; + } else { + break; + } + } + if (isNeg) { + result = 1.0 / result; + } + } + return result; + } + + private static double myfmod(double x1, double x2) { + double q = x1 / x2; + return x1 - Math.floor(q) * x2; + } + + private double rpow(double x, double y) { + if (x == 1.0 || y == 0.0) { + return 1.0; + } + if (x == 0.0) { + if (y > 0.0) { + return 0.0; + } + return Double.POSITIVE_INFINITY; + } + if (RRuntime.isFinite(x) && RRuntime.isFinite(y)) { + if (pow == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + pow = insert(BinaryArithmetic.POW.create()); + } + return pow.op(x, y); + } + if (Double.isNaN(x) || Double.isNaN(y)) { + return x + y; // assuming IEEE 754; otherwise return NaN + } + if (!RRuntime.isFinite(x)) { + if (x > 0) { /* Inf ^ y */ + return (y < 0.0) ? 0.0 : Double.POSITIVE_INFINITY; + } else { /* (-Inf) ^ y */ + if (RRuntime.isFinite(y) && y == Math.floor(y)) { /* (-Inf) ^ n */ + return (y < 0.0) ? 0.0 : (myfmod(y, 2.0) != 0.0 ? x : -x); + } + } + } + if (!RRuntime.isFinite(y)) { + if (x >= 0) { + if (y > 0) { /* y == +Inf */ + return (x >= 1) ? Double.POSITIVE_INFINITY : 0.0; + } else { + /* y == -Inf */ + return (x < 1) ? Double.POSITIVE_INFINITY : 0.0; + } + } + } + // all other cases: (-Inf)^{+-Inf, non-int}; (neg)^{+-Inf} + return Double.NaN; + } + + private RComplex zrround(double re, double im, int digits) { + return RDataFactory.createComplex(fround(re, digits), fround(im, digits)); + } + + } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java index c173c6898e62415d1f5d20af1acb9b022df9934a..d8658e3fa8c0c86917b0ea733657c5918a33eab9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java @@ -31,15 +31,19 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNode; import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNodeGen; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode; +import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; +import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RBuiltinKind; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntVector; @@ -47,6 +51,7 @@ import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; +import com.oracle.truffle.r.runtime.ops.UnaryArithmetic; import com.oracle.truffle.r.runtime.ops.na.NACheck; public class TrigExpFunctions { @@ -137,62 +142,90 @@ public class TrigExpFunctions { } @RBuiltin(name = "exp", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x"}) - public abstract static class Exp extends AdapterCall1 { + public abstract static class Exp extends RBuiltinNode { @Child private BinaryArithmetic calculatePowNode; + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode expNode = UnaryArithmeticNodeGen.create(ExpArithmetic::new, RType.Double, + RError.Message.ARGUMENTS_PASSED_0_1, new Object[]{getRBuiltin().name()}); - public RComplex complexOp(RComplex rComplex) { - if (calculatePowNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - calculatePowNode = insert(BinaryArithmetic.POW.create()); - } - return calculatePowNode.op(Math.E, 0, rComplex.getRealPart(), rComplex.getImaginaryPart()); + @Specialization + protected Object exp(Object value) { + return expNode.execute(boxPrimitive.execute(value)); } - @Override - protected double op(double x) { - return Math.exp(x); - } + public class ExpArithmetic extends UnaryArithmetic { - @Specialization - protected RComplex exp(RComplex power) { - controlVisibility(); - return complexOp(power); - } + @Override + public int op(byte op) { + throw new UnsupportedOperationException(); + } - @Specialization - protected RComplexVector exp(RComplexVector powersVector, // - @Cached("createCountingProfile()") LoopConditionProfile profile) { - controlVisibility(); - int length = powersVector.getLength(); - double[] result = new double[length * 2]; - reportWork(length); - profile.profileCounted(length); - for (int i = 0; profile.inject(i < length); i++) { - RComplex rComplexResult = complexOp(powersVector.getDataAt(i)); - result[2 * i] = rComplexResult.getRealPart(); - result[2 * i + 1] = rComplexResult.getImaginaryPart(); + @Override + public int op(int op) { + throw new UnsupportedOperationException(); + } + + @Override + public double op(double op) { + return Math.exp(op); + } + + @Override + public RComplex op(double re, double im) { + if (calculatePowNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + calculatePowNode = insert(BinaryArithmetic.POW.create()); + } + return calculatePowNode.op(Math.E, 0, re, im); } - return RDataFactory.createComplexVector(result, true); + } } @RBuiltin(name = "expm1", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x"}) - public abstract static class ExpM1 extends Exp { + public abstract static class ExpM1 extends RBuiltinNode { @Child private BinaryArithmetic calculatePowNode; + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); + @Child private UnaryArithmeticNode expm1Node = UnaryArithmeticNodeGen.create(ExpM1Arithmetic::new, RType.Double, + RError.Message.ARGUMENTS_PASSED_0_1, new Object[]{getRBuiltin().name()}); - @Override - public RComplex complexOp(RComplex rComplex) { - RComplex intermediate = super.complexOp(rComplex); - return RDataFactory.createComplex(intermediate.getRealPart() - 1d, intermediate.getImaginaryPart()); + @Specialization + protected Object exp(Object value) { + return expm1Node.execute(boxPrimitive.execute(value)); } - @Override - protected double op(double x) { - return Math.expm1(x); + public class ExpM1Arithmetic extends UnaryArithmetic { + + @Override + public int op(byte op) { + throw new UnsupportedOperationException(); + } + + @Override + public int op(int op) { + throw new UnsupportedOperationException(); + } + + @Override + public double op(double op) { + return Math.expm1(op); + } + + @Override + public RComplex op(double re, double im) { + if (calculatePowNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + calculatePowNode = insert(BinaryArithmetic.POW.create()); + } + RComplex x = calculatePowNode.op(Math.E, 0, re, im); + return RDataFactory.createComplex(x.getRealPart() - 1d, x.getImaginaryPart()); + } + } + } @RBuiltin(name = "sin", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x"}) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java index afb06fa9afe69952b8eeb2115c87bfb9d02c8b61..39fe96a09b211597d9fc8c5acbc700f82a6df1c2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Trunc.java @@ -32,11 +32,26 @@ import com.oracle.truffle.r.runtime.ops.*; @RBuiltin(name = "trunc", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x"}) public abstract class Trunc extends RBuiltinNode { + public static final UnaryArithmeticFactory TRUNC = TruncArithmetic::new; + @Child private BoxPrimitiveNode boxPrimitive = BoxPrimitiveNodeGen.create(); - @Child private UnaryArithmeticNode trunc = UnaryArithmeticNodeGen.create(UnaryArithmetic.TRUNC, RError.Message.NON_NUMERIC_MATH, RType.Double); + @Child private UnaryArithmeticNode trunc = UnaryArithmeticNodeGen.create(TRUNC, RError.Message.NON_NUMERIC_MATH, RType.Double); @Specialization protected Object trunc(Object value) { return trunc.execute(boxPrimitive.execute(value)); } + + public static class TruncArithmetic extends Round.RoundArithmetic { + + @Override + public double op(double op) { + if (op > 0) { + return Math.floor(op); + } else { + return Math.ceil(op); + } + } + } + } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java index f53d8e9e280f3c061b4ca4f3d4573ca7c702ade9..646179aff8a119f8cf0f47a7cbeac33d19964b7d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java @@ -16,6 +16,8 @@ import static com.oracle.truffle.r.nodes.builtin.base.printer.Utils.snprintf; import java.io.IOException; +import com.oracle.truffle.r.nodes.builtin.base.Round; +import com.oracle.truffle.r.nodes.builtin.base.Round.RoundArithmetic; import com.oracle.truffle.r.nodes.builtin.base.printer.DoubleVectorPrinter.ScientificDouble; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RComplex; @@ -357,7 +359,7 @@ public final class ComplexVectorPrinter extends VectorPrinter<RAbstractComplexVe return new ComplexVectorMetrics(wr, dr, er, wi, di, ei); } - private static UnaryArithmetic round = UnaryArithmetic.ROUND.create(); + private static RoundArithmetic round = new Round.RoundArithmetic(); private static RComplex zprecr(RComplex x, int digits) { return round.opd(x.getRealPart(), x.getImaginaryPart(), digits); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java index 55c45f16f9030ef4881f6f3e031934c5dfc9bf4a..8841af79f1febe045956afd977160d03d5688f67 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java @@ -35,6 +35,9 @@ import org.junit.*; import org.junit.experimental.theories.*; import org.junit.runner.*; +import com.oracle.truffle.r.nodes.builtin.base.Ceiling; +import com.oracle.truffle.r.nodes.builtin.base.Floor; +import com.oracle.truffle.r.nodes.builtin.base.Round; import com.oracle.truffle.r.nodes.test.TestUtilities.NodeHandle; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -50,6 +53,8 @@ import com.oracle.truffle.r.runtime.ops.*; @RunWith(Theories.class) public class UnaryArithmeticNodeTest extends BinaryVectorTest { + public static final UnaryArithmeticFactory[] ALL = new UnaryArithmeticFactory[]{NEGATE, Round.ROUND, Floor.FLOOR, Ceiling.CEILING, PLUS}; + @DataPoints public static final UnaryArithmeticFactory[] UNARY = ALL; @Theory @@ -147,8 +152,8 @@ public class UnaryArithmeticNodeTest extends BinaryVectorTest { public void testSequenceFolding() { assertFold(true, createIntSequence(1, 3, 10), NEGATE); assertFold(true, createDoubleSequence(1, 3, 10), NEGATE); - assertFold(false, createIntSequence(1, 3, 10), ROUND, FLOOR, CEILING); - assertFold(false, createDoubleSequence(1, 3, 10), ROUND, FLOOR, CEILING); + assertFold(false, createIntSequence(1, 3, 10), Round.ROUND, Floor.FLOOR, Ceiling.CEILING); + assertFold(false, createDoubleSequence(1, 3, 10), Round.ROUND, Floor.FLOOR, Ceiling.CEILING); } @Theory diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapFunctionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapFunctionNode.java index a1097e26fb6599aacd7dd1d4cf5ca366cd8ace63..f78762015966832779825a6a8722a6839449f8ea 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapFunctionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapFunctionNode.java @@ -63,6 +63,10 @@ public abstract class UnaryMapFunctionNode extends RBaseNode { throw RInternalError.shouldNotReachHere(); } + public double applyDouble(RComplex operand) { + throw RInternalError.shouldNotReachHere(); + } + public String applyCharacter(String operand) { throw RInternalError.shouldNotReachHere(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java index 035657c065d8fd3cd9720d1c33eafac485531fae..1bbb2d8874b928c46d3a34a80f7e8cd4c23395ed 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java @@ -111,7 +111,14 @@ public final class UnaryMapNode extends RBaseNode { case Double: return scalarNode.applyDouble(((RAbstractDoubleVector) operand).getDataAt(0)); case Complex: - return scalarNode.applyComplex(((RAbstractComplexVector) operand).getDataAt(0)); + switch (getResultType()) { + case Double: + return scalarNode.applyDouble(((RAbstractComplexVector) operand).getDataAt(0)); + case Complex: + return scalarNode.applyComplex(((RAbstractComplexVector) operand).getDataAt(0)); + default: + throw RInternalError.shouldNotReachHere(); + } default: throw RInternalError.shouldNotReachHere(); } @@ -188,6 +195,12 @@ public final class UnaryMapNode extends RBaseNode { result[resultIndex << 1] = value.getRealPart(); result[(resultIndex << 1) + 1] = value.getImaginaryPart(); }; + + private static final MapIndexedAction<double[], RAbstractComplexVector> DOUBLE_COMPLEX = // + (arithmetic, result, resultIndex, left, leftIndex) -> { + result[resultIndex] = arithmetic.applyDouble(left.getDataAt(leftIndex)); + }; + private static final MapIndexedAction<String[], RAbstractStringVector> CHARACTER = // (arithmetic, result, resultIndex, left, leftIndex) -> { result[resultIndex] = arithmetic.applyCharacter(left.getDataAt(leftIndex)); @@ -232,7 +245,14 @@ public final class UnaryMapNode extends RBaseNode { case Double: return DOUBLE; case Complex: - return COMPLEX; + switch (resultType) { + case Double: + return DOUBLE_COMPLEX; + case Complex: + return COMPLEX; + default: + throw RInternalError.shouldNotReachHere(); + } case Character: return CHARACTER; default: diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ScalarUnaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ScalarUnaryArithmeticNode.java index 00692250a8f5f1d907c5d842ab59043d6131eecd..91c516c6d6adb3ae48ef588d3c138762745822bb 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ScalarUnaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ScalarUnaryArithmeticNode.java @@ -74,6 +74,14 @@ public class ScalarUnaryArithmeticNode extends UnaryMapNAFunctionNode { return arithmetic.op(operand); } + @Override + public final double applyDouble(RComplex operand) { + if (operandNACheck.check(operand)) { + return RRuntime.DOUBLE_NA; + } + return arithmetic.opd(operand.getRealPart(), operand.getImaginaryPart()); + } + @Override public final RComplex applyComplex(RComplex operand) { if (operandNACheck.check(operand)) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java index 5c9d19b4773c1496f724cbcc82033e15b2078039..155a6fa3dc100ed325263a70c807cb1296f2c532 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryArithmeticNode.java @@ -35,12 +35,21 @@ public abstract class UnaryArithmeticNode extends UnaryNode { protected final UnaryArithmeticFactory unary; private final Message error; + private final Object errorArgs; protected final RType minPrecedence; + public UnaryArithmeticNode(UnaryArithmeticFactory factory, RType minPrecedence, Message error, Object... errorArgs) { + this.unary = factory; + this.error = error; + this.errorArgs = errorArgs; + this.minPrecedence = minPrecedence; + } + public UnaryArithmeticNode(UnaryArithmeticFactory factory, Message error, RType minPrecedence) { this.unary = factory; this.error = error; this.minPrecedence = minPrecedence; + this.errorArgs = null; } public UnaryArithmeticNode(UnaryArithmeticFactory factory, Message error) { @@ -65,7 +74,8 @@ public abstract class UnaryArithmeticNode extends UnaryNode { RType operandType = castOperand.getRType(); if (operandType.isNumeric()) { RType type = RType.maxPrecedence(operandType, minPrecedence); - return UnaryMapNode.create(new ScalarUnaryArithmeticNode(arithmetic), castOperand, type, type); + RType resultType = arithmetic.calculateResultType(type); + return UnaryMapNode.create(new ScalarUnaryArithmeticNode(arithmetic), castOperand, type, resultType); } } return null; @@ -86,7 +96,11 @@ public abstract class UnaryArithmeticNode extends UnaryNode { @Fallback protected Object invalidArgType(@SuppressWarnings("unused") Object operand) { - throw RError.error(this, error); + if (errorArgs == null) { + throw RError.error(this, error); + } else { + throw RError.error(this, error, (Object[]) errorArgs); + } } protected static final class GenericNumericVectorNode extends TruffleBoundaryNode { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplex.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplex.java index c0c25521a54957d451dddd4893d975ea3e54aeba..f7da0929205e89dc9ede7e310b13917dc22b9b5f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplex.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RComplex.java @@ -123,16 +123,21 @@ public final class RComplex extends RScalarVector implements RAbstractComplexVec } public double abs() { - if (!RRuntime.isFinite(realPart) || !RRuntime.isFinite(imaginaryPart)) { - if (Double.isInfinite(realPart) || Double.isInfinite(imaginaryPart)) { + return abs(realPart, imaginaryPart); + } + + public static double abs(double re, double im) { + if (!RRuntime.isFinite(re) || !RRuntime.isFinite(im)) { + if (Double.isInfinite(re) || Double.isInfinite(im)) { return Double.POSITIVE_INFINITY; - } else if (Double.isNaN(imaginaryPart)) { - return imaginaryPart; + } else if (Double.isNaN(im)) { + return im; } else { - return realPart; + return re; } } else { - return Math.sqrt(realPart * realPart + imaginaryPart * imaginaryPart); + return Math.sqrt(re * re + im * im); } } + } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java index daaa8791f073d939e5bc5aeb5804cc742802b43d..680b5ea18c442c96a58ae02667dfd93b6e4de05b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/UnaryArithmetic.java @@ -13,36 +13,35 @@ */ package com.oracle.truffle.r.runtime.ops; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RDataFactory; public abstract class UnaryArithmetic extends Operation { public static final UnaryArithmeticFactory NEGATE = Negate::new; - public static final UnaryArithmeticFactory ROUND = Round::new; - public static final UnaryArithmeticFactory FLOOR = Floor::new; - public static final UnaryArithmeticFactory TRUNC = Trunc::new; - public static final UnaryArithmeticFactory CEILING = Ceiling::new; public static final UnaryArithmeticFactory PLUS = Plus::new; - public static final UnaryArithmeticFactory[] ALL = new UnaryArithmeticFactory[]{NEGATE, ROUND, FLOOR, CEILING, PLUS}; public UnaryArithmetic() { super(false, false); } + public RType calculateResultType(RType argumentType) { + return argumentType; + } + public abstract int op(byte op); public abstract int op(int op); public abstract double op(double op); - public abstract double opd(double op, int digits); - public abstract RComplex op(double re, double im); - public abstract RComplex opd(double re, double im, int digits); + @SuppressWarnings("unused") + public double opd(double re, double im) { + throw new UnsupportedOperationException(); + } public static class Negate extends UnaryArithmetic { @@ -66,18 +65,6 @@ public abstract class UnaryArithmetic extends Operation { return RDataFactory.createComplex(op(re), op(im)); } - @Override - @TruffleBoundary - public double opd(double op, int digits) { - throw new UnsupportedOperationException(); - } - - @Override - @TruffleBoundary - public RComplex opd(double re, double im, int digits) { - throw new UnsupportedOperationException(); - } - } public static class Plus extends UnaryArithmetic { @@ -102,222 +89,6 @@ public abstract class UnaryArithmetic extends Operation { return RDataFactory.createComplex(re, im); } - @Override - @TruffleBoundary - public double opd(double op, int digits) { - throw new UnsupportedOperationException(); - } - - @Override - @TruffleBoundary - public RComplex opd(double re, double im, int digits) { - throw new UnsupportedOperationException(); - } - - } - - public static class Round extends UnaryArithmetic { - - @Child private BinaryArithmetic pow; - - @Override - public int op(int op) { - return op; - } - - @Override - public double op(double op) { - return Math.rint(op); - } - - @Override - public int op(byte op) { - return op; - } - - @Override - public RComplex op(double re, double im) { - return RDataFactory.createComplex(op(re), op(im)); - } - - @Override - public double opd(double op, int digits) { - return fround(op, digits); - } - - @Override - public RComplex opd(double re, double im, int digits) { - return zrround(re, im, digits); - } - - // The logic for fround and zrround (z_rround) is derived from GNU R. - - private static final int F_MAX_DIGITS = 308; // IEEE constant - - private double fround(double x, double digits) { - double pow10; - double sgn; - double intx; - int dig; - - if (Double.isNaN(x) || Double.isNaN(digits)) { - return x + digits; - } - if (!RRuntime.isFinite(x)) { - return x; - } - if (digits == Double.POSITIVE_INFINITY) { - return x; - } else if (digits == Double.NEGATIVE_INFINITY) { - return 0.0; - } - - double dd = digits; - double xx = x; - - if (dd > F_MAX_DIGITS) { - dd = F_MAX_DIGITS; - } - - dig = (int) Math.floor(dd + 0.5); - if (xx < 0.0) { - sgn = -1.0; - xx = -xx; - } else { - sgn = 1.0; - } - - if (dig == 0) { - return sgn * op(xx); - } else if (dig > 0) { - pow10 = rpowdi(10.0, dig); - intx = Math.floor(xx); - // System.out.println(String.format("X %.22f RINT1 %.22f POW10 %.22f INTX %.22f", - // new BigDecimal(x), - // new BigDecimal(Math.rint((xx - intx) * pow10)), new BigDecimal(pow10), - // new BigDecimal(intx))); - return sgn * (intx + Math.rint((xx - intx) * pow10) / pow10); - } else { - pow10 = rpowdi(10.0, -dig); - // System.out.println(String.format("RINT2 %.22f", new BigDecimal(Math.rint(xx / - // pow10)))); - return sgn * Math.rint(xx / pow10) * pow10; - } - } - - private double rpowdi(double x, int n) { - double result = 1.0; - - if (Double.isNaN(x)) { - return x; - } - if (n != 0) { - if (!RRuntime.isFinite(x)) { - return rpow(x, n); - } - int nn = n; - double xx = x; - boolean isNeg = (n < 0); - if (isNeg) { - nn = -nn; - } - for (;;) { - if ((nn & 1) != 0) { - result *= xx; - } - if ((nn >>= 1) != 0) { - xx *= xx; - } else { - break; - } - } - if (isNeg) { - result = 1.0 / result; - } - } - return result; - } - - private static double myfmod(double x1, double x2) { - double q = x1 / x2; - return x1 - Math.floor(q) * x2; - } - - private double rpow(double x, double y) { - if (x == 1.0 || y == 0.0) { - return 1.0; - } - if (x == 0.0) { - if (y > 0.0) { - return 0.0; - } - return Double.POSITIVE_INFINITY; - } - if (RRuntime.isFinite(x) && RRuntime.isFinite(y)) { - if (pow == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - pow = insert(BinaryArithmetic.POW.create()); - } - return pow.op(x, y); - } - if (Double.isNaN(x) || Double.isNaN(y)) { - return x + y; // assuming IEEE 754; otherwise return NaN - } - if (!RRuntime.isFinite(x)) { - if (x > 0) { /* Inf ^ y */ - return (y < 0.0) ? 0.0 : Double.POSITIVE_INFINITY; - } else { /* (-Inf) ^ y */ - if (RRuntime.isFinite(y) && y == Math.floor(y)) { /* (-Inf) ^ n */ - return (y < 0.0) ? 0.0 : (myfmod(y, 2.0) != 0.0 ? x : -x); - } - } - } - if (!RRuntime.isFinite(y)) { - if (x >= 0) { - if (y > 0) { /* y == +Inf */ - return (x >= 1) ? Double.POSITIVE_INFINITY : 0.0; - } else { - /* y == -Inf */ - return (x < 1) ? Double.POSITIVE_INFINITY : 0.0; - } - } - } - // all other cases: (-Inf)^{+-Inf, non-int}; (neg)^{+-Inf} - return Double.NaN; - } - - private RComplex zrround(double re, double im, int digits) { - return RDataFactory.createComplex(fround(re, digits), fround(im, digits)); - } - - } - - public static class Floor extends Round { - - @Override - public double op(double op) { - return Math.floor(op); - } - } - - public static class Trunc extends Round { - - @Override - public double op(double op) { - if (op > 0) { - return Math.floor(op); - } else { - return Math.ceil(op); - } - } - } - - public static class Ceiling extends Round { - - @Override - public double op(double op) { - return Math.ceil(op); - } } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 6b5087fcb513526860b96e8f36080762c09f89f5..c8eac9c7ea54815f375cfb0ea98d5514ff2750c2 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -605,6 +605,10 @@ Error: unexpected symbol in "argv <- list(c('* Edit the help file skeletons in ' #{ Im(as.double(NA)) } [1] 0 +##com.oracle.truffle.r.test.builtins.TestBuiltin_Im.testIm +#{ Im(as.raw(12)) } +Error in Im(as.raw(12)) : non-numeric argument to function + ##com.oracle.truffle.r.test.builtins.TestBuiltin_Im.testIm #{ Im(c(1+1i,2-2i)) } [1] 1 -2 @@ -890,6 +894,14 @@ $vt [1,] -2 1.5 [2,] 1 -0.5 +##com.oracle.truffle.r.test.builtins.TestBuiltin_Mod.testMod +#{ Mod(as.raw(12)) } +Error in Mod(as.raw(12)) : non-numeric argument to function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_Mod.testMod +#{ is.integer(Mod(FALSE) } +Error: unexpected '}' in "{ is.integer(Mod(FALSE) }" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_Mod.testMod #{ round(Mod(1+1i)*10000) } [1] 14142 @@ -1074,6 +1086,10 @@ function (..., recursive = FALSE) .Primitive("c") #{ Re(as.double(NA)) } [1] NA +##com.oracle.truffle.r.test.builtins.TestBuiltin_Re.testRe +#{ Re(as.raw(12)) } +Error in Re(as.raw(12)) : non-numeric argument to function + ##com.oracle.truffle.r.test.builtins.TestBuiltin_Re.testRe #{ Re(c(1+1i,2-2i)) } [1] 1 2 @@ -1423,6 +1439,10 @@ Error in abs(NULL) : non-numeric argument to mathematical function #{ abs(c(1L, 2L, 3L)) } [1] 1 2 3 +##com.oracle.truffle.r.test.builtins.TestBuiltin_abs.testAbs +#{ is.integer(abs(FALSE) } +Error: unexpected '}' in "{ is.integer(abs(FALSE) }" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_abs.testabs1 #argv <- list(c(0.9, 0.1, 0.3, 0.5, 0.7, 0.9, 0.1, 0.3, 0.5));abs(argv[[1]]); [1] 0.9 0.1 0.3 0.5 0.7 0.9 0.1 0.3 0.5 @@ -26899,6 +26919,10 @@ Error in eval(expr, envir, enclos) : object 'y' not found #{ log10(c(0,1)) } [1] -Inf 0 +##com.oracle.truffle.r.test.builtins.TestBuiltin_log10.testLog10 +#{ log10(c(1+1i, -1-1i)) } +[1] 0.150515+0.3410941i 0.150515-1.0232823i + ##com.oracle.truffle.r.test.builtins.TestBuiltin_log10.testLog10 #{ m <- matrix(1:4, nrow=2) ; round( log10(m), digits=5 ) } [,1] [,2] @@ -26997,10 +27021,19 @@ wha #argv <- list(-7e-04);log1p(argv[[1]]); [1] -0.0007002451 +##com.oracle.truffle.r.test.builtins.TestBuiltin_log1p.testlog1p3 +#log1p(c(1+1i,-1-1i)) +Error in log1p(c(1 + (0+1i), -1 - (0+1i))) : + unimplemented complex function + ##com.oracle.truffle.r.test.builtins.TestBuiltin_log2.testLog2 #{ as.integer(log2(6)*1000000) } [1] 2584962 +##com.oracle.truffle.r.test.builtins.TestBuiltin_log2.testLog2 +#{ log10(c(1+1i, -1-1i)) } +[1] 0.150515+0.3410941i 0.150515-1.0232823i + ##com.oracle.truffle.r.test.builtins.TestBuiltin_log2.testLog2 #{ log2(0) } [1] -Inf @@ -43269,6 +43302,10 @@ In sqrt(argv[[1]]) : NaNs produced #argv <- list(0+1i);sqrt(argv[[1]]); [1] 0.7071068+0.7071068i +##com.oracle.truffle.r.test.builtins.TestBuiltin_sqrt.testsqrt12 +#argv <- list(c(TRUE, FALSE));sqrt(argv[[1]]); +[1] 1 0 + ##com.oracle.truffle.r.test.builtins.TestBuiltin_sqrt.testsqrt2 #argv <- list(numeric(0));sqrt(argv[[1]]); numeric(0) diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Im.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Im.java index c6c398e78fcbb91ab8a33d7b23f5933f340174de..6538af0b3905acb29eb387d208ce305a87c51955 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Im.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Im.java @@ -24,12 +24,12 @@ public class TestBuiltin_Im extends TestBase { @Test public void testIm2() { - assertEval(Ignored.Unknown, "argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));Im(argv[[1]]);"); + assertEval("argv <- list(structure(numeric(0), .Dim = c(0L, 0L)));Im(argv[[1]]);"); } @Test public void testIm3() { - assertEval(Ignored.Unknown, "argv <- list(FALSE);Im(argv[[1]]);"); + assertEval("argv <- list(FALSE);Im(argv[[1]]);"); } @Test @@ -39,8 +39,7 @@ public class TestBuiltin_Im extends TestBase { @Test public void testIm5() { - assertEval(Ignored.Unknown, - "argv <- list(structure(c(3+2i, 3+2i, NA, 3+2i, 3+2i, 3+2i, 3+2i, 3+2i, 4-5i, 3-5i, NA, NA, 2-5i, 3-5i, 4-5i, 5-5i), .Dim = c(8L, 2L), .Dimnames = list(NULL, c('x1', 'x2'))));Im(argv[[1]]);"); + assertEval("argv <- list(structure(c(3+2i, 3+2i, NA, 3+2i, 3+2i, 3+2i, 3+2i, 3+2i, 4-5i, 3-5i, NA, NA, 2-5i, 3-5i, 4-5i, 5-5i), .Dim = c(8L, 2L), .Dimnames = list(NULL, c('x1', 'x2'))));Im(argv[[1]]);"); } @Test @@ -54,11 +53,14 @@ public class TestBuiltin_Im extends TestBase { assertEval("{ Im(1) }"); assertEval("{ Im(c(1+1i,2-2i)) }"); assertEval("{ Im(c(1,2)) }"); - assertEval("{ Im(as.double(NA)) }"); - assertEval("{ Im(c(1,NA,2)) }"); - assertEval("{ Im(NA+2i) }"); + // GnuR3.1.3 probably wrongly interprets complex NAs (should be verified) + assertEval(Ignored.ReferenceError, "{ Im(as.double(NA)) }"); + assertEval(Ignored.ReferenceError, "{ Im(c(1,NA,2)) }"); + assertEval(Ignored.ReferenceError, "{ Im(NA+2i) }"); assertEval(Ignored.Unknown, "{ x <- 1:2 ; attr(x,\"my\") <- 2 ; Im(x) }"); assertEval(Ignored.Unknown, "{ x <- c(1+2i,3-4i) ; attr(x,\"my\") <- 2 ; Im(x) }"); + + assertEval("{ Im(as.raw(12)) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Mod.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Mod.java index f0026fc6d4b52be0b5d079452a08c36930a30a6f..6a73e1dee888efadf3c00e1ca1b68d9e819db395 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Mod.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Mod.java @@ -24,29 +24,28 @@ public class TestBuiltin_Mod extends TestBase { @Test public void testMod2() { - assertEval(Ignored.Unknown, - "argv <- list(c(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000));Mod(argv[[1]]);"); + assertEval("argv <- list(c(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000));Mod(argv[[1]]);"); } @Test public void testMod3() { - assertEval(Ignored.Unknown, - "argv <- list(structure(c(-0.00275201701154004+0i, 0.73267342182576+1.53432836384434i, 1.19603180664097+2.58954103250214i, -1.78551995785074+3.6927974843213i, -0.21286727655171-2.24663622584203i, 1.71166744547715-2.14519629896288i, -1.56293209739181+1.57166915011841i, -1.58375104473686+3.6829699402818i, -2.00504145581753-1.3546174582843i, 0.683574008984187+0.815530349018154i, -1.53010401343571-2.36562392372444i, 0.99061039704013+3.53936165201907i, 1.67472443120722-1.95559489480179i, -0.68341618370449-2.47704044044817i, 1.48062655483323-1.57686725056915i, 2.87299425968444+2.35949377337065i, 1.8028932379829+0.54336001329155i, 0.8410445275115-2.79377726088858i, -0.85630340738898+1.95000905938152i, -0.070268282309003-0.407774647142381i, 0.87904100084727+1.42913449570069i, -0.5398835286832-1.49689799587001i, -4.20150499254585-1.17770608296304i, -4.20150499254585+1.17770608296304i, -0.5398835286832+1.49689799587001i, 0.87904100084727-1.42913449570068i, -0.070268282309002+0.407774647142381i, -0.85630340738898-1.95000905938152i, 0.8410445275115+2.79377726088858i, 1.8028932379829-0.54336001329155i, 2.87299425968444-2.35949377337065i, 1.48062655483323+1.57686725056915i, -0.68341618370449+2.47704044044817i, 1.67472443120722+1.95559489480179i, 0.99061039704013-3.53936165201907i, -1.53010401343571+2.36562392372443i, 0.683574008984187-0.815530349018153i, -2.00504145581753+1.3546174582843i, -1.58375104473686-3.6829699402818i, -1.56293209739181-1.57166915011841i, 1.71166744547714+2.14519629896288i, -0.21286727655171+2.24663622584203i, -1.78551995785073-3.6927974843213i, 1.19603180664097-2.58954103250214i, 0.73267342182576-1.53432836384434i), .Dim = c(45L, 1L), '`scaled:center`' = -0.00488570008479763));Mod(argv[[1]]);"); + assertEval("argv <- list(structure(c(-0.00275201701154004+0i, 0.73267342182576+1.53432836384434i, 1.19603180664097+2.58954103250214i, -1.78551995785074+3.6927974843213i, -0.21286727655171-2.24663622584203i, 1.71166744547715-2.14519629896288i, -1.56293209739181+1.57166915011841i, -1.58375104473686+3.6829699402818i, -2.00504145581753-1.3546174582843i, 0.683574008984187+0.815530349018154i, -1.53010401343571-2.36562392372444i, 0.99061039704013+3.53936165201907i, 1.67472443120722-1.95559489480179i, -0.68341618370449-2.47704044044817i, 1.48062655483323-1.57686725056915i, 2.87299425968444+2.35949377337065i, 1.8028932379829+0.54336001329155i, 0.8410445275115-2.79377726088858i, -0.85630340738898+1.95000905938152i, -0.070268282309003-0.407774647142381i, 0.87904100084727+1.42913449570069i, -0.5398835286832-1.49689799587001i, -4.20150499254585-1.17770608296304i, -4.20150499254585+1.17770608296304i, -0.5398835286832+1.49689799587001i, 0.87904100084727-1.42913449570068i, -0.070268282309002+0.407774647142381i, -0.85630340738898-1.95000905938152i, 0.8410445275115+2.79377726088858i, 1.8028932379829-0.54336001329155i, 2.87299425968444-2.35949377337065i, 1.48062655483323+1.57686725056915i, -0.68341618370449+2.47704044044817i, 1.67472443120722+1.95559489480179i, 0.99061039704013-3.53936165201907i, -1.53010401343571+2.36562392372443i, 0.683574008984187-0.815530349018153i, -2.00504145581753+1.3546174582843i, -1.58375104473686-3.6829699402818i, -1.56293209739181-1.57166915011841i, 1.71166744547714+2.14519629896288i, -0.21286727655171+2.24663622584203i, -1.78551995785073-3.6927974843213i, 1.19603180664097-2.58954103250214i, 0.73267342182576-1.53432836384434i), .Dim = c(45L, 1L), '`scaled:center`' = -0.00488570008479763));Mod(argv[[1]]);"); } @Test public void testMod4() { - assertEval(Ignored.Unknown, "argv <- list(logical(0));Mod(argv[[1]]);"); + assertEval("argv <- list(logical(0));Mod(argv[[1]]);"); } @Test public void testMod5() { - assertEval(Ignored.Unknown, - "argv <- list(c(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000, 1.12400072777761e+21, 2.5852016738885e+22, 6.20448401733239e+23, 1.5511210043331e+25, 4.03291461126606e+26, 1.08888694504184e+28, 3.04888344611714e+29, 8.8417619937397e+30, 2.65252859812191e+32, 8.22283865417792e+33, 2.63130836933694e+35, 8.68331761881189e+36, 2.95232799039604e+38, 1.03331479663861e+40, 3.71993326789901e+41, 1.37637530912263e+43, 5.23022617466601e+44, 2.03978820811974e+46, 8.15915283247898e+47, 3.34525266131638e+49, 1.40500611775288e+51, 6.04152630633738e+52, 2.65827157478845e+54, 1.1962222086548e+56, 5.50262215981209e+57, 2.58623241511168e+59, 1.24139155925361e+61, 6.08281864034268e+62, 3.04140932017134e+64, 1.55111875328738e+66, 8.06581751709439e+67, 4.27488328406003e+69, 2.30843697339241e+71, 1.26964033536583e+73, 7.10998587804863e+74, 4.05269195048772e+76, 2.35056133128288e+78, 1.3868311854569e+80, 8.32098711274139e+81, 5.07580213877225e+83, 3.14699732603879e+85, 1.98260831540444e+87, 1.26886932185884e+89, 8.24765059208247e+90, 5.44344939077443e+92, 3.64711109181887e+94, 2.48003554243683e+96, 1.71122452428141e+98, 1.19785716699699e+100, 8.50478588567862e+101, 6.12344583768861e+103, 4.47011546151268e+105, 3.30788544151939e+107, 2.48091408113954e+109, 1.88549470166605e+111, 1.45183092028286e+113, 1.13242811782063e+115, 8.94618213078298e+116, 7.15694570462638e+118, 5.79712602074737e+120, 4.75364333701284e+122, 3.94552396972066e+124, 3.31424013456535e+126, 2.81710411438055e+128, 2.42270953836727e+130, 2.10775729837953e+132, 1.85482642257398e+134, 1.65079551609085e+136, 1.48571596448176e+138, 1.3520015276784e+140, 1.24384140546413e+142, 1.15677250708164e+144, 1.08736615665674e+146, 1.03299784882391e+148, 9.9167793487095e+149, 9.61927596824821e+151, 9.42689044888325e+153, 9.33262154439442e+155, 9.33262154439442e+157, 9.42594775983836e+159, 9.61446671503513e+161, 9.90290071648618e+163, 1.02990167451456e+166, 1.08139675824029e+168, 1.14628056373471e+170, 1.22652020319614e+172, 1.32464181945183e+174, 1.44385958320249e+176, 1.58824554152274e+178, 1.76295255109024e+180, 1.97450685722107e+182, 2.23119274865981e+184, 2.54355973347219e+186, 2.92509369349302e+188, 3.3931086844519e+190, 3.96993716080872e+192, 4.68452584975429e+194, 5.57458576120761e+196));Mod(argv[[1]]);"); + assertEval("argv <- list(c(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000, 1.12400072777761e+21, 2.5852016738885e+22, 6.20448401733239e+23, 1.5511210043331e+25, 4.03291461126606e+26, 1.08888694504184e+28, 3.04888344611714e+29, 8.8417619937397e+30, 2.65252859812191e+32, 8.22283865417792e+33, 2.63130836933694e+35, 8.68331761881189e+36, 2.95232799039604e+38, 1.03331479663861e+40, 3.71993326789901e+41, 1.37637530912263e+43, 5.23022617466601e+44, 2.03978820811974e+46, 8.15915283247898e+47, 3.34525266131638e+49, 1.40500611775288e+51, 6.04152630633738e+52, 2.65827157478845e+54, 1.1962222086548e+56, 5.50262215981209e+57, 2.58623241511168e+59, 1.24139155925361e+61, 6.08281864034268e+62, 3.04140932017134e+64, 1.55111875328738e+66, 8.06581751709439e+67, 4.27488328406003e+69, 2.30843697339241e+71, 1.26964033536583e+73, 7.10998587804863e+74, 4.05269195048772e+76, 2.35056133128288e+78, 1.3868311854569e+80, 8.32098711274139e+81, 5.07580213877225e+83, 3.14699732603879e+85, 1.98260831540444e+87, 1.26886932185884e+89, 8.24765059208247e+90, 5.44344939077443e+92, 3.64711109181887e+94, 2.48003554243683e+96, 1.71122452428141e+98, 1.19785716699699e+100, 8.50478588567862e+101, 6.12344583768861e+103, 4.47011546151268e+105, 3.30788544151939e+107, 2.48091408113954e+109, 1.88549470166605e+111, 1.45183092028286e+113, 1.13242811782063e+115, 8.94618213078298e+116, 7.15694570462638e+118, 5.79712602074737e+120, 4.75364333701284e+122, 3.94552396972066e+124, 3.31424013456535e+126, 2.81710411438055e+128, 2.42270953836727e+130, 2.10775729837953e+132, 1.85482642257398e+134, 1.65079551609085e+136, 1.48571596448176e+138, 1.3520015276784e+140, 1.24384140546413e+142, 1.15677250708164e+144, 1.08736615665674e+146, 1.03299784882391e+148, 9.9167793487095e+149, 9.61927596824821e+151, 9.42689044888325e+153, 9.33262154439442e+155, 9.33262154439442e+157, 9.42594775983836e+159, 9.61446671503513e+161, 9.90290071648618e+163, 1.02990167451456e+166, 1.08139675824029e+168, 1.14628056373471e+170, 1.22652020319614e+172, 1.32464181945183e+174, 1.44385958320249e+176, 1.58824554152274e+178, 1.76295255109024e+180, 1.97450685722107e+182, 2.23119274865981e+184, 2.54355973347219e+186, 2.92509369349302e+188, 3.3931086844519e+190, 3.96993716080872e+192, 4.68452584975429e+194, 5.57458576120761e+196));Mod(argv[[1]]);"); } @Test public void testMod() { assertEval("{ round(Mod(1+1i)*10000) }"); + assertEval("{ Mod(as.raw(12)) }"); + assertEval("{ is.integer(Mod(FALSE) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Re.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Re.java index 7c47a894779c4b87ebf58e032a1239b75c56eef9..1209b66cc405b6e3a3e7f4d075c5154b838cd37c 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Re.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_Re.java @@ -24,8 +24,7 @@ public class TestBuiltin_Re extends TestBase { @Test public void testRe2() { - assertEval(Ignored.Unknown, - "argv <- list(structure(c(3+2i, 3+2i, NA, 3+2i, 3+2i, 3+2i, 3+2i, 3+2i, 4-5i, 3-5i, NA, NA, 2-5i, 3-5i, 4-5i, 5-5i), .Dim = c(8L, 2L), .Dimnames = list(NULL, c('x1', 'x2'))));Re(argv[[1]]);"); + assertEval("argv <- list(structure(c(3+2i, 3+2i, NA, 3+2i, 3+2i, 3+2i, 3+2i, 3+2i, 4-5i, 3-5i, NA, NA, 2-5i, 3-5i, 4-5i, 5-5i), .Dim = c(8L, 2L), .Dimnames = list(NULL, c('x1', 'x2'))));Re(argv[[1]]);"); } @Test @@ -40,12 +39,12 @@ public class TestBuiltin_Re extends TestBase { @Test public void testRe5() { - assertEval(Ignored.Unknown, "argv <- list(logical(0));Re(argv[[1]]);"); + assertEval("argv <- list(logical(0));Re(argv[[1]]);"); } @Test public void testRe6() { - assertEval(Ignored.Unknown, "argv <- list(FALSE);Re(argv[[1]]);"); + assertEval("argv <- list(FALSE);Re(argv[[1]]);"); } @Test @@ -65,5 +64,7 @@ public class TestBuiltin_Re extends TestBase { assertEval(Ignored.Unknown, "{ x <- 1:2 ; attr(x,\"my\") <- 2 ; Re(x) }"); assertEval(Ignored.Unknown, "{ x <- c(1+2i,3-4i) ; attr(x,\"my\") <- 2 ; Re(x) }"); + + assertEval("{ Re(as.raw(12)) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_abs.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_abs.java index 7f7977ebd85545415f07321c5b12f6f09e388144..53a106905f25dc4878bfc1bb29b2b02ebd254c5d 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_abs.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_abs.java @@ -60,7 +60,7 @@ public class TestBuiltin_abs extends TestBase { @Test public void testabs9() { - assertEval(Ignored.Unknown, "argv <- list(structure(c(56.8666666666667, 52.8833333333333), .Dim = 2L, .Dimnames = structure(list(K = c('0', '1')), .Names = 'K')));abs(argv[[1]]);"); + assertEval("argv <- list(structure(c(56.8666666666667, 52.8833333333333), .Dim = 2L, .Dimnames = structure(list(K = c('0', '1')), .Names = 'K')));abs(argv[[1]]);"); } @Test @@ -75,8 +75,7 @@ public class TestBuiltin_abs extends TestBase { @Test public void testabs12() { - assertEval(Ignored.Unknown, - "argv <- list(structure(c(1.47191076131574, 0.586694550701453, NA, 0.258706725324317, 0.948371836939988, 0.396080061109718, NA, 0.350912037541581), .Dim = c(4L, 2L), .Dimnames = list(c('(Intercept)', 'x1', 'x2', 'x3'), c('Estimate', 'Std. Error'))));abs(argv[[1]]);"); + assertEval("argv <- list(structure(c(1.47191076131574, 0.586694550701453, NA, 0.258706725324317, 0.948371836939988, 0.396080061109718, NA, 0.350912037541581), .Dim = c(4L, 2L), .Dimnames = list(c('(Intercept)', 'x1', 'x2', 'x3'), c('Estimate', 'Std. Error'))));abs(argv[[1]]);"); } @Test @@ -91,7 +90,7 @@ public class TestBuiltin_abs extends TestBase { @Test public void testabs15() { - assertEval(Ignored.Unknown, "argv <- list(structure(c(NA, NA), .Dim = 1:2, .Dimnames = list('x', c('Estimate', 'Std. Error'))));abs(argv[[1]]);"); + assertEval("argv <- list(structure(c(NA, NA), .Dim = 1:2, .Dimnames = list('x', c('Estimate', 'Std. Error'))));abs(argv[[1]]);"); } @Test @@ -152,5 +151,7 @@ public class TestBuiltin_abs extends TestBase { assertEval(Ignored.Unknown, "{ abs(c(0/0,1i)) }"); assertEval("{ abs(1:3) }"); assertEval("{ abs(-1:-3) }"); + + assertEval("{ is.integer(abs(FALSE) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_exp.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_exp.java index cf98c68626841e7fd088d6bc58f9c6a752d9db43..c82560a76829020ed342685a2d1b105a7318057b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_exp.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_exp.java @@ -49,7 +49,7 @@ public class TestBuiltin_exp extends TestBase { @Test public void testexp8() { - assertEval(Ignored.Unknown, "argv <- list(logical(0));exp(argv[[1]]);"); + assertEval("argv <- list(logical(0));exp(argv[[1]]);"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_expm1.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_expm1.java index 393f5836b80ffd28431c431b01537854dc243a14..c5994dedf9a19d6e2193fecba91252dad5f9bb11 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_expm1.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_expm1.java @@ -34,7 +34,7 @@ public class TestBuiltin_expm1 extends TestBase { @Test public void testexpm14() { - assertEval(Ignored.Unknown, "argv <- list(logical(0));expm1(argv[[1]]);"); + assertEval("argv <- list(logical(0));expm1(argv[[1]]);"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java index 496a428341cf330c89a67ef496bcc17511d71f9b..73a0ec140dceddecd818c452df71679b2c0ca9ad 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java @@ -49,8 +49,7 @@ public class TestBuiltin_log10 extends TestBase { @Test public void testlog107() { - assertEval(Ignored.Unknown, - "argv <- list(structure(numeric(0), .Dim = c(20L, 0L), .Dimnames = list(c('ant', 'bee', 'cat', 'cpl', 'chi', 'cow', 'duc', 'eag', 'ele', 'fly', 'fro', 'her', 'lio', 'liz', 'lob', 'man', 'rab', 'sal', 'spi', 'wha'), NULL)));log10(argv[[1]]);"); + assertEval("argv <- list(structure(numeric(0), .Dim = c(20L, 0L), .Dimnames = list(c('ant', 'bee', 'cat', 'cpl', 'chi', 'cow', 'duc', 'eag', 'ele', 'fly', 'fro', 'her', 'lio', 'liz', 'lob', 'man', 'rab', 'sal', 'spi', 'wha'), NULL)));log10(argv[[1]]);"); } @Test @@ -63,7 +62,9 @@ public class TestBuiltin_log10 extends TestBase { assertEval("{ log10(100) } "); assertEval("{ as.integer(log10(200)*100000) } "); - assertEval(Ignored.Unknown, "{ m <- matrix(1:4, nrow=2) ; round( log10(m), digits=5 ) }"); + assertEval("{ m <- matrix(1:4, nrow=2) ; round( log10(m), digits=5 ) }"); assertEval(Ignored.Unknown, "{ x <- c(a=1, b=10) ; round( c(log(x), log10(x), log2(x)), digits=5 ) }"); + + assertEval("{ log10(c(1+1i, -1-1i)) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log1p.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log1p.java index 5c85cc776b5bf90f26d21330fa64174e9d3c310e..3319f3c29506bab5d31c715f5f59449d91acd43b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log1p.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log1p.java @@ -19,12 +19,16 @@ public class TestBuiltin_log1p extends TestBase { @Test public void testlog1p1() { - assertEval(Ignored.Unknown, - "argv <- list(c(-0.160475096572577, -0.953101214495634, -0.329547420118877, -0.234819677566528, -0.108178529791777, -0.0994458210555148, -0.282992873965743, -0.731707656126625, -0.866467764292465, -0.76039953639421, -0.3580569675068, -0.52382260076554, -0.240530699925064, -0.236619747356161, -0.811827419307205, -0.154911720192001, -0.97472580847241, -0.464016625026599, -0.58493655376716, -0.230096919024049));log1p(argv[[1]]);"); + assertEval("argv <- list(c(-0.160475096572577, -0.953101214495634, -0.329547420118877, -0.234819677566528, -0.108178529791777, -0.0994458210555148, -0.282992873965743, -0.731707656126625, -0.866467764292465, -0.76039953639421, -0.3580569675068, -0.52382260076554, -0.240530699925064, -0.236619747356161, -0.811827419307205, -0.154911720192001, -0.97472580847241, -0.464016625026599, -0.58493655376716, -0.230096919024049));log1p(argv[[1]]);"); } @Test public void testlog1p2() { - assertEval(Ignored.Unknown, "argv <- list(-7e-04);log1p(argv[[1]]);"); + assertEval("argv <- list(-7e-04);log1p(argv[[1]]);"); + } + + @Test + public void testlog1p3() { + assertEval(Ignored.ReferenceError, "log1p(c(1+1i,-1-1i))"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log2.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log2.java index b12eadd7a1476b8b25e75b0a11ec729505646626..10d840218a7a934f1189a154e549bcac3c4d6de1 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log2.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log2.java @@ -24,7 +24,7 @@ public class TestBuiltin_log2 extends TestBase { @Test public void testlog22() { - assertEval(Ignored.Unknown, "argv <- list(FALSE);log2(argv[[1]]);"); + assertEval("argv <- list(FALSE);log2(argv[[1]]);"); } @Test @@ -46,5 +46,7 @@ public class TestBuiltin_log2 extends TestBase { assertEval("{ log2(2) } "); assertEval("{ log2(4) } "); assertEval("{ as.integer(log2(6)*1000000) } "); + + assertEval("{ log10(c(1+1i, -1-1i)) }"); } }