diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java new file mode 100644 index 0000000000000000000000000000000000000000..8180a40c81aab0ab113e233038c39c1b55685160 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.library.stats.deriv; + +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.typeName; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.access.ConstantNode; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RExpression; +import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; + +public abstract class D extends RExternalBuiltinNode.Arg2 { + + static { + Casts casts = new Casts(D.class); + casts.arg(0, "expr").mustBe(instanceOf(RExpression.class).or(instanceOf(RLanguage.class)).or(instanceOf(RSymbol.class)).or(numericValue()).or(complexValue()), + RError.Message.INVALID_EXPRESSION_TYPE, typeName()); + casts.arg(1, "namevec").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.GENERIC, "variable must be a character string").shouldBe(size(1), + RError.Message.ONLY_FIRST_VARIABLE_NAME).findFirst(); + } + + public static D create() { + return DNodeGen.create(); + } + + protected static boolean isConstant(Object expr) { + return !(expr instanceof RLanguage || expr instanceof RExpression || expr instanceof RSymbol); + } + + @Specialization(guards = "isConstant(expr)") + @TruffleBoundary + protected Object doD(Object expr, String var) { + return doD(ConstantNode.create(expr), var); + } + + @Specialization + @TruffleBoundary + protected Object doD(RSymbol expr, String var) { + return doD(RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, expr.getName(), false), var); + } + + @Specialization + @TruffleBoundary + protected Object doD(RLanguage expr, String var) { + return doD((RSyntaxElement) expr.getRep(), var); + } + + @Specialization + @TruffleBoundary + protected Object doD(RExpression expr, String var, + @Cached("create()") D dNode) { + return dNode.execute(expr.getDataAt(0), var); + } + + private static Object doD(RSyntaxElement elem, String var) { + RSyntaxVisitor<RSyntaxElement> vis = new DerivVisitor(var); + RSyntaxElement dExpr = vis.accept(elem); + dExpr = Deriv.addParens(dExpr); + return RASTUtils.createLanguageElement(dExpr); + } + +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java new file mode 100644 index 0000000000000000000000000000000000000000..36aa40831565010b6d586d365c774143b1879bc4 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java @@ -0,0 +1,703 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995, 1996 Robert Gentleman and Ross Ihaka + * Copyright (c) 1997-2013, The R Core Team + * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats.deriv; + +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asLogicalVector; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.boxPrimitive; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.findFirst; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lengthGte; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.lengthLte; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.map; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.RRootNode; +import com.oracle.truffle.r.nodes.access.ConstantNode; +import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.nodes.function.FormalArguments; +import com.oracle.truffle.r.nodes.function.RCallSpecialNode; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +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.context.RContext; +import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.REmpty; +import com.oracle.truffle.r.runtime.data.RExpression; +import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; +import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; + +//Transcribed from GnuR, library/stats/src/deriv.c + +public abstract class Deriv extends RExternalBuiltinNode { + + static { + Casts casts = new Casts(Deriv.class); + casts.arg(1, "namevec").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.INVALID_VARIABLE_NAMES); + casts.arg(2, "function.arg").mapIf(logicalValue(), chain(asLogicalVector()).with(findFirst().logicalElement()).with(map(toBoolean())).end()).mapIf(stringValue(), boxPrimitive()); + casts.arg(3, "tag").defaultError(RError.Message.INVALID_VARIABLE_NAMES).mustBe(stringValue()).asStringVector().mustBe(notEmpty()).findFirst().mustBe(lengthGte(1).and(lengthLte(60))); + casts.arg(4, "hessian").asLogicalVector().findFirst(RRuntime.LOGICAL_NA).map(toBoolean()); + } + + static final String LEFT_PAREN = "("; + static final String PLUS = "+"; + static final String MINUS = "-"; + static final String TIMES = "*"; + static final String DIVIDE = "/"; + static final String POWER = "^"; + static final String LOG = "log"; + static final String EXP = "exp"; + static final String COS = "cos"; + static final String SIN = "sin"; + static final String TAN = "tan"; + static final String COSH = "cosh"; + static final String SINH = "sinh"; + static final String TANH = "tanh"; + static final String SQRT = "sqrt"; + static final String PNORM = "pnorm"; + static final String DNORM = "dnorm"; + static final String ASIN = "asin"; + static final String ACOS = "acos"; + static final String ATAN = "atan"; + static final String GAMMA = "gamma"; + static final String LGAMMA = "lgamma"; + static final String DIGAMMA = "digamma"; + static final String TRIGAMMA = "trigamma"; + static final String PSIGAMMA = "psigamma"; + + public static Deriv create() { + return DerivNodeGen.create(); + } + + public abstract Object execute(VirtualFrame frame, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5); + + @Override + public Object call(VirtualFrame frame, RArgsValuesAndNames args) { + checkLength(args, 5); + return execute(frame, castArg(args, 0), castArg(args, 1), castArg(args, 2), castArg(args, 3), castArg(args, 4)); + } + + @Override + protected Object call(RArgsValuesAndNames args) { + throw RInternalError.shouldNotReachHere(); + } + + protected static boolean isConstant(Object expr) { + return !(expr instanceof RLanguage || expr instanceof RExpression || expr instanceof RSymbol); + } + + @Specialization(guards = "isConstant(expr)") + protected Object derive(VirtualFrame frame, Object expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return derive(frame, RDataFactory.createLanguage(ConstantNode.create(expr)), names, functionArg, tag, hessian); + } + + @Specialization + protected Object derive(VirtualFrame frame, RSymbol expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return derive(frame, (RBaseNode) RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, expr.getName(), false), names, functionArg, tag, hessian); + } + + @Specialization + protected Object derive(VirtualFrame frame, RExpression expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian, + @Cached("create()") Deriv derivNode) { + return derivNode.execute(frame, expr.getDataAt(0), names, functionArg, tag, hessian); + } + + @Specialization + protected Object derive(VirtualFrame frame, RLanguage expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return derive(frame, expr.getRep(), names, functionArg, tag, hessian); + } + + private Object derive(VirtualFrame frame, RBaseNode elem, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + LinkedList<RSyntaxNode> exprlist = new LinkedList<>(); + int fIndex = findSubexpression(elem, exprlist, tag); + + int nderiv = names.getLength(); + int[] dIndex = new int[nderiv]; + int[] d2Index = hessian ? new int[(nderiv * (1 + nderiv)) / 2] : null; + for (int i = 0, k = 0; i < nderiv; i++) { + RBaseNode dExpr = d(elem, names.getDataAt(i)); + dIndex[i] = findSubexpression(dExpr, exprlist, tag); + + if (hessian) { + for (int j = i; j < nderiv; j++) { + RBaseNode d2Expr = d(dExpr, names.getDataAt(j)); + d2Index[k] = findSubexpression(d2Expr, exprlist, tag); + k++; + } + } + } + + int nexpr = exprlist.size(); + + if (fIndex > 0) { + exprlist.add(ReadVariableNode.create(tag + fIndex)); + } else { + exprlist.add(cloneElement(elem.asRSyntaxNode())); + } + + exprlist.add(null); + if (hessian) { + exprlist.add(null); + } + + for (int i = 0, k = 0; i < nderiv; i++) { + if (dIndex[i] > 0) { + exprlist.add(ReadVariableNode.create(tag + dIndex[i])); + + if (hessian) { + RBaseNode dExpr = d(elem, names.getDataAt(i)); + for (int j = i; j < nderiv; j++) { + if (d2Index[k] > 0) { + exprlist.add(ReadVariableNode.create(tag + d2Index[k])); + } else { + exprlist.add((RSyntaxNode) d(dExpr, names.getDataAt(j))); + } + k++; + } + } + + } else { + // the first derivative is constant or simple variable + // TODO: do not call the d twice + RBaseNode dExpr = d(elem, names.getDataAt(i)); + exprlist.add((RSyntaxNode) dExpr); + + if (hessian) { + for (int j = i; j < nderiv; j++) { + if (d2Index[k] > 0) { + exprlist.add(ReadVariableNode.create(tag + d2Index[k])); + } else { + RBaseNode d2Expr = d(dExpr, names.getDataAt(j)); + if (isZero((RSyntaxElement) d2Expr)) { + exprlist.add(null); + } else { + exprlist.add((RSyntaxNode) d2Expr); + } + } + k++; + } + } + } + } + + exprlist.add(null); + exprlist.add(null); + if (hessian) { + exprlist.add(null); + } + + for (int i = 0; i < nexpr; i++) { + String subexprName = tag + (i + 1); + if (countOccurences(subexprName, exprlist, i + 1) < 2) { + replace(subexprName, exprlist.get(i), exprlist, i + 1); + exprlist.set(i, null); + } else { + exprlist.set(i, createAssignNode(subexprName, exprlist.get(i))); + } + } + + int p = nexpr; + exprlist.set(p++, createAssignNode(".value", exprlist.get(nexpr))); // .value <- + exprlist.set(p++, createGrad(names)); // .grad <- + if (hessian) { + exprlist.set(p++, createHess(names)); // .hessian + } + // .grad[, "..."] <- ... + for (int i = 0; i < nderiv; i++) { + RSyntaxNode ans = exprlist.get(p); + exprlist.set(p, derivAssign(names.getDataAt(i), ans)); + p++; + + if (hessian) { + for (int j = i; j < nderiv; j++, p++) { + ans = exprlist.get(p); + if (ans != null) { + if (i == j) { + exprlist.set(p, hessAssign1(names.getDataAt(i), addParens(ans))); + } else { + exprlist.set(p, hessAssign2(names.getDataAt(i), names.getDataAt(j), addParens(ans))); + } + } + } + } + + } + // attr(.value, "gradient") <- .grad + exprlist.set(p++, addGrad()); + if (hessian) { + exprlist.set(p++, addHess()); + } + + // .value + exprlist.set(p++, ReadVariableNode.create(".value")); + + // prune exprlist + exprlist.removeAll(Collections.singleton(null)); + + List<Argument<RSyntaxNode>> blockStatements = exprlist.stream().map(e -> RCodeBuilder.argument(e)).collect(Collectors.toList()); + RSyntaxNode blockCall = RContext.getASTBuilder().call(RSyntaxNode.LAZY_DEPARSE, ReadVariableNode.create("{"), blockStatements); + + if (functionArg instanceof RAbstractStringVector) { + RAbstractStringVector funArgNames = (RAbstractStringVector) functionArg; + List<Argument<RSyntaxNode>> targetArgs = new ArrayList<>(); + for (int i = 0; i < funArgNames.getLength(); i++) { + targetArgs.add(RCodeBuilder.argument(RSyntaxNode.LAZY_DEPARSE, funArgNames.getDataAt(i), ConstantNode.create(RMissing.instance))); + } + + return createFunction(frame, blockCall, targetArgs); + } else if (functionArg == Boolean.TRUE) { + List<Argument<RSyntaxNode>> targetArgs = new ArrayList<>(); + for (int i = 0; i < names.getLength(); i++) { + targetArgs.add(RCodeBuilder.argument(RSyntaxNode.LAZY_DEPARSE, names.getDataAt(i), ConstantNode.create(RMissing.instance))); + } + + return createFunction(frame, blockCall, targetArgs); + } else if (functionArg instanceof RFunction) { + RFunction funTemplate = (RFunction) functionArg; + FormalArguments formals = ((RRootNode) funTemplate.getRootNode()).getFormalArguments(); + RNode[] defArgs = formals.getArguments(); + List<Argument<RSyntaxNode>> targetArgs = new ArrayList<>(); + for (int i = 0; i < defArgs.length; i++) { + targetArgs.add(RCodeBuilder.argument(RSyntaxNode.LAZY_DEPARSE, formals.getSignature().getName(i), cloneElement((RSyntaxNode) defArgs[i]))); + } + + return createFunction(frame, blockCall, targetArgs); + } else { + RLanguage lan = RDataFactory.createLanguage(blockCall.asRNode()); + RExpression res = RDataFactory.createExpression(new Object[]{lan}); + return res; + } + + } + + private static RFunction createFunction(VirtualFrame frame, RSyntaxNode blockCall, List<Argument<RSyntaxNode>> targetArgs) { + RootCallTarget callTarget = RContext.getASTBuilder().rootFunction(RSyntaxNode.LAZY_DEPARSE, targetArgs, blockCall, null); + FrameSlotChangeMonitor.initializeEnclosingFrame(callTarget.getRootNode().getFrameDescriptor(), frame); + return RDataFactory.createFunction(RFunction.NO_NAME, RFunction.NO_NAME, callTarget, null, frame.materialize()); + } + + private int findSubexpression(RBaseNode expr, List<RSyntaxNode> exprlist, String tag) { + if (!(expr instanceof RSyntaxElement)) { + throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); + } + + RSyntaxVisitor<Integer> vis = new RSyntaxVisitor<Integer>() { + @Override + protected Integer visit(RSyntaxCall call) { + if (call.getSyntaxLHS() instanceof RSyntaxLookup && ((RSyntaxLookup) call.getSyntaxLHS()).getIdentifier() == LEFT_PAREN) { + return accept(call.getSyntaxArguments()[0]); + } + + RSyntaxElement[] args = call.getSyntaxArguments(); + List<Argument<RSyntaxNode>> newArgs = new ArrayList<>(); + for (int i = 0; i < args.length; i++) { + int k = accept(args[i]); + if (k > 0) { + newArgs.add(RCodeBuilder.argument(ReadVariableNode.create(tag + k))); + } else { + newArgs.add(RCodeBuilder.argument(cloneElement(args[i]))); + } + } + RSyntaxNode newCall = RContext.getASTBuilder().call(call.getSourceSection(), cloneElement(call.getSyntaxLHS()), newArgs); + return accumulate(newCall, exprlist); + } + + @Override + protected Integer visit(RSyntaxConstant element) { + return checkConstant(element.getValue()); + } + + @Override + protected Integer visit(RSyntaxLookup element) { + return 0; + } + + @Override + protected Integer visit(RSyntaxFunction element) { + throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); + } + + }; + return vis.accept((RSyntaxElement) expr); + } + + private static int checkConstant(Object val) { + if (val instanceof Double || val instanceof Integer || val instanceof RComplex || val instanceof Byte || val instanceof RSymbol) { + return 0; + } else { + throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); + } + } + + private static boolean isDoubleValue(RSyntaxElement elem, double value) { + if (elem instanceof RSyntaxConstant) { + Object val = ((RSyntaxConstant) elem).getValue(); + if (val instanceof Number) { + return ((Number) val).doubleValue() == value; + } else { + return false; + } + } else { + return false; + } + } + + static boolean isZero(RSyntaxElement elem) { + return isDoubleValue(elem, 0.); + } + + static boolean isOne(RSyntaxElement elem) { + return isDoubleValue(elem, 1.); + } + + private int accumulate(RSyntaxElement expr, List<RSyntaxNode> exprlist) { + for (int k = 0; k < exprlist.size(); k++) { + if (equal(expr, exprlist.get(k))) { + return k + 1; + } + } + exprlist.add((RSyntaxNode) expr); + return exprlist.size(); + } + + // TODO: move to a utility class + private boolean equal(RSyntaxElement expr1, RSyntaxElement expr2) { + if (expr1.getClass() != expr2.getClass()) { + return false; + } + if (expr1 instanceof RSyntaxLookup) { + return ((RSyntaxLookup) expr1).getIdentifier() == ((RSyntaxLookup) expr2).getIdentifier(); + } + if (expr1 instanceof RSyntaxConstant) { + return ((RSyntaxConstant) expr1).getValue().equals(((RSyntaxConstant) expr2).getValue()); + } + if (expr1 instanceof RSyntaxCall) { + RSyntaxElement[] args1 = ((RSyntaxCall) expr1).getSyntaxArguments(); + RSyntaxElement[] args2 = ((RSyntaxCall) expr2).getSyntaxArguments(); + if (args1.length != args2.length) { + return false; + } + if (!equal(((RSyntaxCall) expr1).getSyntaxLHS(), ((RSyntaxCall) expr2).getSyntaxLHS())) { + return false; + } + for (int i = 0; i < args1.length; i++) { + if (!equal(args1[i], args2[i])) { + return false; + } + } + return true; + } + + throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "equal"); + } + + static String getFunctionName(RSyntaxElement expr) { + if (expr instanceof RSyntaxCall) { + RSyntaxCall call = (RSyntaxCall) expr; + return call.getSyntaxLHS() instanceof RSyntaxLookup ? ((RSyntaxLookup) call.getSyntaxLHS()).getIdentifier() : null; + } else { + return null; + } + } + + static RSyntaxNode cloneElement(RSyntaxElement element) { + return (RSyntaxNode) RASTUtils.cloneNode(((RBaseNode) element)); + } + + private static RBaseNode d(RBaseNode expr, String var) { + if (!(expr instanceof RSyntaxElement)) { + throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); + } + + RSyntaxVisitor<RSyntaxElement> vis = new DerivVisitor(var); + return (RBaseNode) vis.accept((RSyntaxElement) expr); + } + + private static int argsLength(RSyntaxElement elem) { + if (elem instanceof RSyntaxCall) { + return ((RSyntaxCall) elem).getSyntaxArguments().length; + } else { + return 0; + } + } + + static RSyntaxElement arg(RSyntaxElement elem, int argIndex) { + assert elem instanceof RSyntaxCall && (argIndex < ((RSyntaxCall) elem).getSyntaxArguments().length); + return ((RSyntaxCall) elem).getSyntaxArguments()[argIndex]; + } + + private static RSyntaxElement setArg(RSyntaxElement elem, int argIndex, RSyntaxElement arg) { + assert elem instanceof RSyntaxCall && (argIndex < ((RSyntaxCall) elem).getSyntaxArguments().length); + RSyntaxCall call = (RSyntaxCall) elem; + RSyntaxElement[] args = call.getSyntaxArguments(); + RSyntaxNode[] newArgs = new RSyntaxNode[args.length]; + for (int i = 0; i < args.length; i++) { + if (i == argIndex) { + newArgs[i] = (RSyntaxNode) arg; + } else { + newArgs[i] = cloneElement(args[i]); + } + } + return RCallSpecialNode.createCall(call.getSourceSection(), (RNode) cloneElement(call.getSyntaxLHS()), ArgumentsSignature.empty(args.length), newArgs); + } + + static RSyntaxNode newCall(String functionName, RSyntaxElement arg1, RSyntaxElement arg2) { + if (arg2 == null) { + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create(functionName), (RSyntaxNode) arg1); + } else { + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create(functionName), (RSyntaxNode) arg1, (RSyntaxNode) arg2); + } + } + + private static int countOccurences(String subexprName, List<RSyntaxNode> exprlist, int fromIndex) { + if (fromIndex >= exprlist.size()) { + return 0; + } + + RSyntaxNode exprListNode = exprlist.get(fromIndex); + if (exprListNode == null) { + return countOccurences(subexprName, exprlist, fromIndex + 1); + } + + RSyntaxVisitor<Integer> vis = new RSyntaxVisitor<Integer>() { + @Override + protected Integer visit(RSyntaxCall element) { + RSyntaxElement[] args = element.getSyntaxArguments(); + int cnt = 0; + for (int i = 0; i < args.length; i++) { + cnt += accept(args[i]); + } + return cnt; + } + + @Override + protected Integer visit(RSyntaxConstant element) { + return 0; + } + + @Override + protected Integer visit(RSyntaxLookup element) { + return subexprName.equals(element.getIdentifier()) ? 1 : 0; + } + + @Override + protected Integer visit(RSyntaxFunction element) { + throw RInternalError.shouldNotReachHere(); + } + }; + + return vis.accept(exprListNode) + countOccurences(subexprName, exprlist, fromIndex + 1); + } + + private static void replace(String subexprName, RSyntaxNode replacement, List<RSyntaxNode> exprlist, int fromIndex) { + if (fromIndex >= exprlist.size()) { + return; + } + + RSyntaxElement exprListNode = exprlist.get(fromIndex); + if (exprListNode == null) { + replace(subexprName, replacement, exprlist, fromIndex + 1); + return; + } + + RSyntaxVisitor<RSyntaxElement> vis = new RSyntaxVisitor<RSyntaxElement>() { + + // TODO: do not create a new call node after the first replacement + + @Override + protected RSyntaxElement visit(RSyntaxCall call) { + RSyntaxElement[] args = call.getSyntaxArguments(); + RSyntaxNode[] newArgs = new RSyntaxNode[args.length]; + for (int i = 0; i < args.length; i++) { + newArgs[i] = (RSyntaxNode) accept(args[i]); + } + return RCallSpecialNode.createCall(call.getSourceSection(), (RNode) call.getSyntaxLHS(), ArgumentsSignature.empty(args.length), newArgs); + } + + @Override + protected RSyntaxElement visit(RSyntaxConstant element) { + return element; + } + + @Override + protected RSyntaxElement visit(RSyntaxLookup element) { + return subexprName.equals(element.getIdentifier()) ? replacement : element; + } + + @Override + protected RSyntaxElement visit(RSyntaxFunction element) { + throw RInternalError.shouldNotReachHere(); + } + + }; + + exprlist.set(fromIndex, (RSyntaxNode) vis.accept(exprListNode)); + + replace(subexprName, replacement, exprlist, fromIndex + 1); + } + + private static RSyntaxNode createAssignNode(String varName, RSyntaxNode rhs) { + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), ReadVariableNode.create(varName.intern()), addParens(rhs)); + } + + private static RSyntaxNode hessAssign1(String varName, RSyntaxNode rhs) { + RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".hessian"), ConstantNode.create(REmpty.instance), + ConstantNode.create(varName.intern()), ConstantNode.create(varName.intern())); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, rhs); + } + + private static RSyntaxNode hessAssign2(String varName1, String varName2, RSyntaxNode rhs) { + RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".hessian"), ConstantNode.create(REmpty.instance), + ConstantNode.create(varName1.intern()), ConstantNode.create(varName2.intern())); + RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".hessian"), ConstantNode.create(REmpty.instance), + ConstantNode.create(varName2.intern()), ConstantNode.create(varName1.intern())); + + RSyntaxNode tmp3 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp2, rhs); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp1, tmp3); + } + + private static RSyntaxNode createGrad(RAbstractStringVector names) { + int n = names.getLength(); + List<Argument<RSyntaxNode>> cArgs = new ArrayList<>(); + for (int i = 0; i < n; i++) { + cArgs.add(RCodeBuilder.argument(ConstantNode.create(names.getDataAt(i).intern()))); + } + RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), cArgs); + RSyntaxNode dimnames = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("list"), ConstantNode.create(RNull.instance), tmp1); + + RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("length"), ReadVariableNode.create(".value")); + RSyntaxNode dim = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), tmp2, ConstantNode.create(n)); + ConstantNode data = ConstantNode.create(0.); + + RSyntaxNode p = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("array"), data, dim, dimnames); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), ReadVariableNode.create(".grad"), p); + } + + private static RSyntaxNode createHess(RAbstractStringVector names) { + int n = names.getLength(); + List<Argument<RSyntaxNode>> cArgs = new ArrayList<>(); + for (int i = 0; i < n; i++) { + cArgs.add(RCodeBuilder.argument(ConstantNode.create(names.getDataAt(i).intern()))); + } + RSyntaxNode tmp1 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), cArgs); + RSyntaxNode tmp1Clone = cloneElement(tmp1); + RSyntaxNode dimnames = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("list"), ConstantNode.create(RNull.instance), tmp1, tmp1Clone); + + RSyntaxNode tmp2 = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("length"), ReadVariableNode.create(".value")); + RSyntaxNode dim = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("c"), tmp2, ConstantNode.create(n), ConstantNode.create(n)); + ConstantNode data = ConstantNode.create(0.); + + RSyntaxNode p = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("array"), data, dim, dimnames); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), ReadVariableNode.create(".hessian"), p); + } + + private static RSyntaxNode derivAssign(String name, RSyntaxNode expr) { + RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("["), ReadVariableNode.create(".grad"), ConstantNode.create(REmpty.instance), + ConstantNode.create(name.intern())); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, expr); + } + + private static RSyntaxNode addGrad() { + RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("attr"), ReadVariableNode.create(".value"), ConstantNode.create("gradient")); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, ReadVariableNode.create(".grad")); + } + + private static RSyntaxNode addHess() { + RSyntaxNode tmp = RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("attr"), ReadVariableNode.create(".value"), ConstantNode.create("hessian")); + return RContext.getASTBuilder().call(RSyntaxNode.SOURCE_UNAVAILABLE, ReadVariableNode.create("<-"), tmp, ReadVariableNode.create(".hessian")); + } + + private static boolean isForm(RSyntaxElement expr, String functionName) { + return argsLength(expr) == 2 && getFunctionName(expr) == functionName; + } + + static RSyntaxNode addParens(RSyntaxElement node) { + RSyntaxElement expr = node; + if (node instanceof RSyntaxCall) { + RSyntaxCall call = (RSyntaxCall) node; + RSyntaxElement[] args = call.getSyntaxArguments(); + RSyntaxNode[] newArgs = new RSyntaxNode[args.length]; + for (int i = 0; i < args.length; i++) { + newArgs[i] = addParens(args[i]); + } + expr = RCallSpecialNode.createCall(call.getSourceSection(), (RNode) cloneElement(call.getSyntaxLHS()), ArgumentsSignature.empty(args.length), newArgs); + } + + if (isForm(expr, PLUS)) { + if (isForm(arg(expr, 1), PLUS)) { + expr = setArg(expr, 1, newCall(LEFT_PAREN, arg(expr, 1), null)); + } + } else if (isForm(expr, MINUS)) { + if (isForm(arg(expr, 1), PLUS) || isForm(arg(expr, 1), MINUS)) { + expr = setArg(expr, 1, newCall(LEFT_PAREN, arg(expr, 1), null)); + } + } else if (isForm(expr, TIMES)) { + if (isForm(arg(expr, 1), PLUS) || isForm(arg(expr, 1), MINUS) || isForm(arg(expr, 1), TIMES) || + isForm(arg(expr, 1), DIVIDE)) { + expr = setArg(expr, 1, newCall(LEFT_PAREN, arg(expr, 1), null)); + } + if (isForm(arg(expr, 0), MINUS) || isForm(arg(expr, 0), MINUS)) { + expr = setArg(expr, 0, newCall(LEFT_PAREN, arg(expr, 0), null)); + } + } else if (isForm(expr, DIVIDE)) { + if (isForm(arg(expr, 1), PLUS) || isForm(arg(expr, 1), MINUS) || isForm(arg(expr, 1), TIMES) || + isForm(arg(expr, 1), DIVIDE)) { + expr = setArg(expr, 1, newCall(LEFT_PAREN, arg(expr, 1), null)); + } + if (isForm(arg(expr, 0), PLUS) || isForm(arg(expr, 0), MINUS)) { + expr = setArg(expr, 0, newCall(LEFT_PAREN, arg(expr, 0), null)); + } + } else if (isForm(expr, POWER)) { + if (isForm(arg(expr, 0), POWER)) { + expr = setArg(expr, 0, newCall(LEFT_PAREN, arg(expr, 0), null)); + } + if (isForm(arg(expr, 1), PLUS) || isForm(arg(expr, 1), MINUS) || isForm(arg(expr, 1), TIMES) || + isForm(arg(expr, 1), DIVIDE)) { + expr = setArg(expr, 1, newCall(LEFT_PAREN, arg(expr, 1), null)); + } + } + return (RSyntaxNode) expr; + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/DerivVisitor.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/DerivVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..8dc3708ecd3527565a524513b83072f1e4407a53 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/DerivVisitor.java @@ -0,0 +1,408 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1995, 1996 Robert Gentleman and Ross Ihaka + * Copyright (c) 1997-2013, The R Core Team + * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats.deriv; + +import static com.oracle.truffle.r.library.stats.deriv.Deriv.*; + +import com.oracle.truffle.r.nodes.access.ConstantNode; +import com.oracle.truffle.r.runtime.RDeparse; +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.Utils; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; +import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; +import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; + +//Transcribed from GnuR, library/stats/src/deriv.c + +public class DerivVisitor extends RSyntaxVisitor<RSyntaxElement> { + + private final String var; + + DerivVisitor(String var) { + this.var = var; + } + + @Override + protected RSyntaxElement visit(RSyntaxCall call) { + String functionName = getFunctionName(call); + assert Utils.isInterned(functionName); + + RSyntaxElement arg0 = call.getSyntaxArguments()[0]; + RSyntaxElement arg1 = call.getSyntaxArguments().length > 1 ? call.getSyntaxArguments()[1] : null; + + if (functionName == LEFT_PAREN) { + return accept(arg0); + } + + if (functionName == PLUS) { + if (call.getSyntaxArguments().length == 1) { + return accept(arg0); + } else { + return simplify(PLUS, accept(arg0), accept(arg1)); + } + } + + if (functionName == MINUS) { + if (call.getSyntaxArguments().length == 1) { + return simplify(MINUS, accept(arg0), null); + } else { + return simplify(MINUS, accept(arg0), accept(arg1)); + } + } + + if (functionName == TIMES) { + return simplify(PLUS, simplify(TIMES, accept(arg0), cloneElement(arg1)), + simplify(TIMES, cloneElement(arg0), accept(arg1))); + } + + if (functionName == DIVIDE) { + return simplify(MINUS, + simplify(DIVIDE, accept(arg0), cloneElement(arg1)), + simplify(DIVIDE, + simplify(TIMES, cloneElement(arg0), accept(arg1)), + simplify(POWER, cloneElement(arg1), ConstantNode.create(2.)))); + } + + if (functionName == POWER) { + if (isNumeric(arg1)) { + return simplify(TIMES, + arg1, + simplify(TIMES, + accept(arg0), + simplify(POWER, cloneElement(arg0), decDouble(arg1)))); + + } else { + // (a^b)' = a^(b-1).b.a' + a^b.log(a).b' + RSyntaxElement expr1 = simplify(TIMES, + simplify(POWER, + arg0, + simplify(MINUS, cloneElement(arg1), ConstantNode.create(1.))), + simplify(TIMES, cloneElement(arg1), accept(arg0))); + + RSyntaxElement expr2 = simplify(TIMES, + simplify(POWER, cloneElement(arg0), cloneElement(arg1)), + simplify(TIMES, + simplify(LOG, cloneElement(arg0), null), + accept(arg1))); + return simplify(PLUS, expr1, expr2); + } + } + + if (functionName == EXP) { + return simplify(TIMES, cloneElement(call), accept(arg0)); + } + + if (functionName == LOG) { + if (call.getSyntaxArguments().length != 1) { + throw RError.error(RError.SHOW_CALLER, RError.Message.GENERIC, "only single-argument calls are supported"); + } + return simplify(DIVIDE, accept(arg0), cloneElement(arg0)); + } + + if (functionName == COS) { + return simplify(TIMES, + simplify(SIN, cloneElement(arg0), null), + simplify(MINUS, accept(arg0), null)); + } + + if (functionName == SIN) { + return simplify(TIMES, + simplify(COS, cloneElement(arg0), null), + accept(arg0)); + } + + if (functionName == TAN) { + return simplify(DIVIDE, + accept(arg0), + simplify(POWER, + simplify(COS, cloneElement(arg0), null), + ConstantNode.create(2.))); + } + + if (functionName == COSH) { + return simplify(TIMES, + simplify(SINH, cloneElement(arg0), null), + accept(arg0)); + } + + if (functionName == SINH) { + return simplify(TIMES, + simplify(COSH, cloneElement(arg0), null), + accept(arg0)); + } + + if (functionName == TANH) { + return simplify(DIVIDE, + accept(arg0), + simplify(POWER, + simplify(COSH, cloneElement(arg0), null), + ConstantNode.create(2.))); + } + + if (functionName == SQRT) { + return accept(simplify(POWER, cloneElement(arg0), ConstantNode.create(0.5))); + } + + if (functionName == PNORM) { + return simplify(TIMES, + simplify(DNORM, cloneElement(arg0), null), + accept(arg0)); + } + + if (functionName == DNORM) { + return simplify(TIMES, + simplify(MINUS, cloneElement(arg0), null), + simplify(TIMES, + simplify(DNORM, cloneElement(arg0), null), + accept(arg0))); + } + + if (functionName == ASIN) { + return simplify(DIVIDE, + accept(arg0), + simplify(SQRT, + simplify(MINUS, + ConstantNode.create(1.), + simplify(POWER, cloneElement(arg0), ConstantNode.create(2.))), + null)); + } + + if (functionName == ACOS) { + return simplify(MINUS, + simplify(DIVIDE, + accept(arg0), + simplify(SQRT, + simplify(MINUS, + ConstantNode.create(1.), + simplify(POWER, cloneElement(arg0), ConstantNode.create(2.))), + null)), + null); + } + + if (functionName == ATAN) { + return simplify(DIVIDE, + accept(arg0), + simplify(PLUS, + ConstantNode.create(1.), + simplify(POWER, cloneElement(arg0), ConstantNode.create(2.)))); + } + + if (functionName == LGAMMA) { + return simplify(TIMES, + accept(arg0), + simplify(DIGAMMA, cloneElement(arg0), null)); + } + + if (functionName == GAMMA) { + return simplify(TIMES, + accept(arg0), + simplify(TIMES, cloneElement(call), + simplify(DIGAMMA, cloneElement(arg0), null))); + } + + if (functionName == DIGAMMA) { + return simplify(TIMES, + accept(arg0), + simplify(TRIGAMMA, cloneElement(arg0), null)); + } + + if (functionName == TRIGAMMA) { + return simplify(TIMES, + accept(arg0), + simplify(PSIGAMMA, cloneElement(arg0), ConstantNode.create(2))); + } + + if (functionName == PSIGAMMA) { + if (call.getSyntaxArguments().length == 1) { + return simplify(TIMES, + accept(arg0), + simplify(PSIGAMMA, cloneElement(arg0), ConstantNode.create(1))); + } else if (isIntegerOrDouble(arg1)) { + return simplify(TIMES, + accept(arg0), + simplify(PSIGAMMA, cloneElement(arg0), incInteger(arg1))); + } else { + return simplify(TIMES, + accept(arg0), + simplify(PSIGAMMA, + cloneElement(arg0), + simplify(PLUS, cloneElement(arg1), ConstantNode.create(1)))); + } + } + + throw RError.error(RError.SHOW_CALLER, RError.Message.NOT_IN_DERIVATIVE_TABLE, RDeparse.deparseSyntaxElement(call.getSyntaxLHS())); + } + + @Override + protected RSyntaxElement visit(RSyntaxConstant element) { + return ConstantNode.create(0.); + } + + @Override + protected RSyntaxElement visit(RSyntaxLookup element) { + double dVal = element.getIdentifier().equals(var) ? 1 : 0; + return ConstantNode.create(dVal); + } + + @Override + protected RSyntaxElement visit(RSyntaxFunction element) { + throw RInternalError.shouldNotReachHere(); + } + + private RSyntaxElement simplify(String functionName, RSyntaxElement arg1, RSyntaxElement arg2) { + if (functionName == PLUS) { + if (arg2 == null) { + return arg1; + } else if (isZero(arg1)) { + return arg2; + } else if (isZero(arg2)) { + return arg1; + } else if (isUminus(arg1)) { + return simplify(MINUS, arg2, arg(arg1, 0)); + } else if (isUminus(arg2)) { + return simplify(MINUS, arg1, arg(arg2, 0)); + } else { + return newCall(PLUS, arg1, arg2); + } + } else if (functionName == MINUS) { + if (arg2 == null) { + if (isZero(arg1)) { + return ConstantNode.create(0.); + } else if (isUminus(arg1)) { + return arg(arg1, 0); + } else { + return newCall(MINUS, arg1, arg2); + } + } else { + if (isZero(arg2)) { + return arg1; + } else if (isZero(arg1)) { + return simplify(MINUS, arg2, null); + } else if (isUminus(arg1)) { + return simplify(MINUS, + simplify(PLUS, arg(arg1, 0), arg2), + null); + } else if (isUminus(arg2)) { + return simplify(PLUS, arg1, arg(arg2, 0)); + } else { + return newCall(MINUS, arg1, arg2); + } + } + } else if (functionName == TIMES) { + if (isZero(arg1) || isZero(arg2)) { + return ConstantNode.create(0.); + } else if (isOne(arg1)) { + return arg2; + } else if (isOne(arg2)) { + return arg1; + } else if (isUminus(arg1)) { + return simplify(MINUS, simplify(TIMES, arg(arg1, 0), arg2), null); + } else if (isUminus(arg2)) { + return simplify(MINUS, simplify(TIMES, arg1, arg(arg2, 0)), null); + } else { + return newCall(TIMES, arg1, arg2); + } + } else if (functionName == DIVIDE) { + if (isZero(arg1)) { + return ConstantNode.create(0.); + } else if (isZero(arg2)) { + return ConstantNode.create(RRuntime.DOUBLE_NA); + } else if (isOne(arg2)) { + return arg1; + } else if (isUminus(arg1)) { + return simplify(MINUS, simplify(DIVIDE, arg(arg1, 0), arg2), null); + } else if (isUminus(arg2)) { + return simplify(MINUS, simplify(DIVIDE, arg1, arg(arg2, 0)), null); + } else { + return newCall(DIVIDE, arg1, arg2); + } + } else if (functionName == POWER) { + if (isZero(arg2)) { + return ConstantNode.create(1.); + } else if (isZero(arg1)) { + return ConstantNode.create(0.); + } else if (isOne(arg1)) { + return ConstantNode.create(1.); + } else if (isOne(arg2)) { + return arg1; + } else { + return newCall(POWER, arg1, arg2); + } + } else if (functionName == EXP) { + // FIXME: simplify exp(lgamma( E )) = gamma( E ) + return newCall(EXP, arg1, null); + } else if (functionName == LOG) { + // FIXME: simplify log(gamma( E )) = lgamma( E ) + return newCall(LOG, arg1, null); + } else if (functionName == COS || functionName == SIN || functionName == TAN || functionName == COSH || functionName == SINH || functionName == TANH || functionName == SQRT || + functionName == PNORM || functionName == DNORM || functionName == ASIN || functionName == ACOS || functionName == ATAN || functionName == GAMMA || functionName == LGAMMA || + functionName == DIGAMMA || functionName == TRIGAMMA || functionName == PSIGAMMA) { + return newCall(functionName, arg1, arg2); + } else { + return ConstantNode.create(RRuntime.DOUBLE_NA); + } + } + + private static boolean isIntegerOrDouble(RSyntaxElement elem) { + if (elem instanceof RSyntaxConstant) { + Object val = ((RSyntaxConstant) elem).getValue(); + return val instanceof Integer || val instanceof Double; + } else { + return false; + } + } + + private static boolean isUminus(RSyntaxElement elem) { + if (elem instanceof RSyntaxCall && MINUS == getFunctionName(elem)) { + RSyntaxElement[] args = ((RSyntaxCall) elem).getSyntaxArguments(); + switch (args.length) { + case 1: + return true; + case 2: + return false; + default: + throw RError.error(RError.SHOW_CALLER, RError.Message.GENERIC, "invalid form in unary minus check"); + } + } else { + return false; + } + } + + private static boolean isNumeric(RSyntaxElement elem) { + if (elem instanceof RSyntaxConstant) { + Object val = ((RSyntaxConstant) elem).getValue(); + return val instanceof Integer || val instanceof Double || val instanceof Byte; + } else { + return false; + } + } + + private static RSyntaxConstant decDouble(RSyntaxElement elem) { + assert elem instanceof RSyntaxConstant; + assert ((RSyntaxConstant) elem).getValue() instanceof Number; + Number n = (Number) ((RSyntaxConstant) elem).getValue(); + return ConstantNode.create(n.doubleValue() - 1); + } + + private static RSyntaxConstant incInteger(RSyntaxElement elem) { + assert elem instanceof RSyntaxConstant; + assert ((RSyntaxConstant) elem).getValue() instanceof Number; + Number n = (Number) ((RSyntaxConstant) elem).getValue(); + return ConstantNode.create(n.intValue() + 1); + } + +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java index 037a66f6f7d9034bd65102b4af1278fc46b53cc2..ab28e791fd8d730b36e6b70e815fb86459e08692 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java @@ -55,6 +55,8 @@ import com.oracle.truffle.r.library.stats.RandFunctionsNodes.RandFunction3Node; import com.oracle.truffle.r.library.stats.SignrankFreeNode; import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineCoefNodeGen; import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineEvalNodeGen; +import com.oracle.truffle.r.library.stats.deriv.D; +import com.oracle.truffle.r.library.stats.deriv.Deriv; import com.oracle.truffle.r.library.stats.StatsFunctionsNodes; import com.oracle.truffle.r.library.stats.WilcoxFreeNode; import com.oracle.truffle.r.library.tools.C_ParseRdNodeGen; @@ -744,6 +746,11 @@ public class CallAndExternalFunctions { switch (name) { case "compcases": return new CompleteCases(); + // stats + case "doD": + return D.create(); + case "deriv": + return Deriv.create(); // utils case "countfields": return CountFieldsNodeGen.create(); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ExtBuiltinsList.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ExtBuiltinsList.java index 8b6d15fd217dab5b26a49b9ba64c163f26c7e3c6..98eb067b7a6a144ec15572ed5ce698a971c85cd2 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ExtBuiltinsList.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ExtBuiltinsList.java @@ -101,6 +101,7 @@ public class ExtBuiltinsList { com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_getGenericNodeGen.class, com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_nextMethodCallNodeGen.class, com.oracle.truffle.r.library.methods.MethodsListDispatchFactory.R_externalPtrPrototypeObjectNodeGen.class, + com.oracle.truffle.r.library.stats.deriv.DerivNodeGen.class, }; @SuppressWarnings("unchecked") diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ForwardedValuesAnalyserTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ForwardedValuesAnalyserTest.java index 76fb3d04577b1188b8cbea518df1d6cc276afd4f..ccaa151114c738a42ee2174ab5a8ab647be51b32 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ForwardedValuesAnalyserTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ForwardedValuesAnalyserTest.java @@ -22,6 +22,12 @@ */ package com.oracle.truffle.r.nodes.test; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.asLogicalVector; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.findFirst; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.map; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -30,6 +36,7 @@ import org.junit.Test; import com.oracle.truffle.r.nodes.builtin.casts.Filter.AndFilter; import com.oracle.truffle.r.nodes.builtin.casts.Filter.CompareFilter; import com.oracle.truffle.r.nodes.builtin.casts.Filter.CompareFilter.ScalarValue; +import com.oracle.truffle.r.nodes.builtin.casts.Mapper.MapByteToBoolean; import com.oracle.truffle.r.nodes.builtin.casts.Filter.DoubleFilter; import com.oracle.truffle.r.nodes.builtin.casts.Filter.MissingFilter; import com.oracle.truffle.r.nodes.builtin.casts.Filter.NotFilter; @@ -42,6 +49,7 @@ import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.CoercionStep; import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.FilterStep; import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.FindFirstStep; import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.MapIfStep; +import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep.MapStep; import com.oracle.truffle.r.nodes.builtin.casts.analysis.ForwardedValuesAnalyser; import com.oracle.truffle.r.nodes.builtin.casts.analysis.ForwardingAnalysisResult; import com.oracle.truffle.r.runtime.RType; @@ -406,4 +414,26 @@ public class ForwardedValuesAnalyserTest { assertFalse(result.isStringForwarded()); assertFalse(result.isMissingForwarded()); } + + @Test + public void testReturnIfWithTrueBranchChain() { + //@formatter:off + PipelineStep<?, ?> findFirstBoolean = new CoercionStep<>(RType.Logical, false).setNext(new FindFirstStep<>(null, Byte.class, null)).setNext(new MapStep<>(new MapByteToBoolean(false))); + PipelineStep<?, ?> firstStep = new MapIfStep<>(new RTypeFilter<>(RType.Logical), // the condition + findFirstBoolean, null, true); + //@formatter:on + + ForwardedValuesAnalyser fwdAn = new ForwardedValuesAnalyser(); + ForwardingAnalysisResult result = fwdAn.analyse(firstStep); + // TODO: change it to the positive assertion when the selected mappers (such as + // MapByteToBoolean) are supported + assertFalse(result.isLogicalForwarded()); + assertTrue(result.logicalForwarded.mapper instanceof MapByteToBoolean); + assertTrue(result.isDoubleForwarded()); + assertTrue(result.isIntegerForwarded()); + assertTrue(result.isNullForwarded()); + assertTrue(result.isStringForwarded()); + assertTrue(result.isMissingForwarded()); + } + } diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/RBuiltinDiagnostics.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/RBuiltinDiagnostics.java index c4f1c1b1027b5e5ecf2f0b8896461261a3c1959b..2ab3ac955ae37a9d70be769c8dc9672812c3dce1 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/RBuiltinDiagnostics.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/RBuiltinDiagnostics.java @@ -431,13 +431,14 @@ public class RBuiltinDiagnostics { print(1, "\nUnhandled argument combinations: " + nonCoveredArgsSet.size()); print(1, ""); - printDeadSpecs(); - if (diagSuite.diagConfig.verbose) { for (List<Type> uncoveredArgs : nonCoveredArgsSet) { print(1, uncoveredArgs.stream().map(t -> typeName(t)).collect(Collectors.toList())); } } + print(1, ""); + + printDeadSpecs(); } private void printBuiltinHeader(int level) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java index da3d7e2cdac4f5c63b62551ddf169dc28594d37f..61b20ae0af9b73459e1bbf93c03c203e48c9e8db 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java @@ -426,6 +426,10 @@ public final class CastBuilder { return new NotNAStep<>(null, null); } + public static <T> PipelineStep<T, T> boxPrimitive() { + return new PipelineStep.BoxPrimitiveStep<>(); + } + public static NullFilter nullValue() { return NullFilter.INSTANCE; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingStatus.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingStatus.java index a59b7c04358ce5fb1082ad0ce8fc5e88288ccd3d..c8fb811228400ddc74a78045c5d8bb38f83da2cd 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingStatus.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/analysis/ForwardingStatus.java @@ -39,7 +39,7 @@ public abstract class ForwardingStatus { }; public static final ForwardingStatus FORWARDED = new Forwarded(null); - final Mapper<?, ?> mapper; + public final Mapper<?, ?> mapper; private final byte flag; protected ForwardingStatus(byte flag, Mapper<?, ?> mapper) { @@ -97,7 +97,7 @@ public abstract class ForwardingStatus { } ForwardingStatus or(ForwardingStatus other) { - return fromFlag(or(this.flag, other.flag)); + return fromFlag(or(this.flag, other.flag), this.mapper != null ? this.mapper : other.mapper); } ForwardingStatus not() { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index 12d944ccc087bbfe42d0fcd5d2124de5af982738..a73c50c1f77bbaeeee28f2096cb40fe1c101214a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -847,7 +847,12 @@ public final class RError extends RuntimeException { TRUNCATE_NOT_ENABLED("truncation not enabled for this connection"), TRUNCATE_UNSUPPORTED_FOR_CONN("cannot truncate connection: %s"), INCOMPLETE_STRING_AT_EOF_DISCARDED("incomplete string at end of file has been discarded"), - INVALID_CHANNEL_OBJECT("invalid channel object type: %s"); + INVALID_CHANNEL_OBJECT("invalid channel object type: %s"), + INVALID_TAG("invalid tag"), + INVALID_VARIABLE_NAMES("invalid variable names"), + INVALID_EXPRESSION("invalid expression in '%s'"), + INVALID_EXPRESSION_TYPE("expression must not be type '%s'"), + NOT_IN_DERIVATIVE_TABLE("Function '%s' is not in the derivatives table"); public final String message; final boolean hasArgs; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RCodeBuilder.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RCodeBuilder.java index 45eb98dceacf4427936a8021a8802062e44c5a97..50b52b7a7ef0e93896dfca6e108a376bda383a04 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RCodeBuilder.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RCodeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,4 +197,11 @@ public interface RCodeBuilder<T> { default T call(SourceSection source, T lhs, T argument1, T argument2, T argument3) { return call(source, lhs, Arrays.asList(argument(argument1), argument(argument2), argument(argument3))); } + + /** + * Helper function: create a call with four unnamed arguments. + */ + default T call(SourceSection source, T lhs, T argument1, T argument2, T argument3, T argument4) { + return call(source, lhs, Arrays.asList(argument(argument1), argument(argument2), argument(argument3), argument(argument4))); + } } 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 f263e95c09ba7a7061c57e8701408ed1807fbfc9..5fc5fb2db8221b3e3d75f80c919c2a45921cac57 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 @@ -143,6 +143,31 @@ Error in Conj(as.raw(12)) : non-numeric argument to function attr(,"foo") [1] "foo" +##com.oracle.truffle.r.test.builtins.TestBuiltin_D.testD# +#(df <- D(1, "x"));df(0) +[1] 0 +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_D.testD# +#(df <- D(expression(x^2*sin(x)), "x"));df(0) +2 * x * sin(x) + x^2 * cos(x) +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_D.testD# +#(df <- D(quote(x^2*sin(x)), "x"));df(0) +2 * x * sin(x) + x^2 * cos(x) +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_D.testD# +#g<-quote(x^2);(df <- D(g, "x"));df(0) +2 * x +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_D.testD# +#x<-1;(df <- D(x, "x"));df(0) +[1] 0 +Error in df(0) : argument "df1" is missing, with no default + ##com.oracle.truffle.r.test.builtins.TestBuiltin_Date2POSIXlt.testDate2POSIXlt1# #argv <- list(structure(c(14712, 14712), class = 'Date')); .Internal(Date2POSIXlt(argv[[1]])) [1] "2010-04-13 UTC" "2010-04-13 UTC" @@ -4827,11 +4852,11 @@ numeric(0) #argv <- list(structure(list(sec = 0, min = 0L, hour = 0L, mday = 22:27, mon = 3L, year = 108L, wday = 2L, yday = 112L, isdst = -1L), .Names = c('sec', 'min', 'hour', 'mday', 'mon', 'year', 'wday', 'yday', 'isdst'), class = c('POSIXlt', 'POSIXt'), tzone = 'GMT'), 'GMT'); .Internal(as.POSIXct(argv[[1]], argv[[2]])) [1] 1208822400 1208908800 1208995200 1209081600 1209168000 1209254400 -##com.oracle.truffle.r.test.builtins.TestBuiltin_asPOSIXlt.testasPOSIXlt# +##com.oracle.truffle.r.test.builtins.TestBuiltin_asPOSIXlt.testasPOSIXlt#Output.MayIgnoreErrorContext# #.Internal(as.POSIXlt(, 1)) Error in .Internal(as.POSIXlt(, 1)) : argument 1 is empty -##com.oracle.truffle.r.test.builtins.TestBuiltin_asPOSIXlt.testasPOSIXlt# +##com.oracle.truffle.r.test.builtins.TestBuiltin_asPOSIXlt.testasPOSIXlt#Output.MayIgnoreErrorContext# #.Internal(as.POSIXlt(2, )) Error in .Internal(as.POSIXlt(2, )) : argument 2 is empty @@ -9310,11 +9335,11 @@ Error in bitwOr(c(1, 2, 3, 4), c(3 + (0+3i))) : [25] -33554432 -67108864 -134217728 -268435456 -536870912 -1073741824 [31] NA -##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftL.testBitwiseFunctions# +##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftL.testBitwiseFunctions#Output.MayIgnoreErrorContext# #{ .Internal(bitwiseShiftL(, 1))} Error in .Internal(bitwiseShiftL(, 1)) : argument 1 is empty -##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftL.testBitwiseFunctions# +##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftL.testBitwiseFunctions#Output.MayIgnoreErrorContext# #{ .Internal(bitwiseShiftL(200, ))} Error in .Internal(bitwiseShiftL(200, )) : argument 2 is empty @@ -9357,11 +9382,11 @@ In bitwShiftL(c(3, 2, 4), c(3 + (0+3i))) : #{ bitwShiftL(c(8,4,2), NULL) } integer(0) -##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftR.testBitwiseFunctions# +##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftR.testBitwiseFunctions#Output.MayIgnoreErrorContext# #{ .Internal(bitwiseShiftR(, 1))} Error in .Internal(bitwiseShiftR(, 1)) : argument 1 is empty -##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftR.testBitwiseFunctions# +##com.oracle.truffle.r.test.builtins.TestBuiltin_bitwiseShiftR.testBitwiseFunctions#Output.MayIgnoreErrorContext# #{ .Internal(bitwiseShiftR(200, ))} Error in .Internal(bitwiseShiftR(200, )) : argument 2 is empty @@ -12944,15 +12969,15 @@ function() 42 #{ x=1;class(x)<-"character"; x} [1] "1" -##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass# +##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass#Output.MayIgnoreErrorContext# #{`class<-`(, "foo") } Error in `class<-`(, "foo") : argument 1 is empty -##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass# +##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass#Output.MayIgnoreErrorContext# #{`class<-`(, ) } Error in `class<-`(, ) : argument 1 is empty -##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass# +##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass#Output.MayIgnoreErrorContext# #{`class<-`(NULL, "first") } Error: attempt to set an attribute on NULL @@ -13077,7 +13102,7 @@ Error in class(x) <- "array" : #{x<-c(2+3i,4+5i);class(x)<-"a";class(x)<-"complex";x;} [1] 2+3i 4+5i -##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass# +##com.oracle.truffle.r.test.builtins.TestBuiltin_classassign.testUpdateClass#Output.MayIgnoreErrorContext# #{x=1; `class<-`(x, ) } Error in `class<-`(x, ) : argument 2 is empty @@ -16782,6 +16807,2495 @@ invalid 'cutoff' value for 'deparse', using default #argv <- list(quote(utils::str), 60L, TRUE, 69, -1L); .Internal(deparse(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]])) [1] "utils::str" +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)*(x+2), c("x"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr2 <- x + 2 + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- .expr2 + .expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)*(x+2), c("x"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr2 <- x + 2 + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- .expr2 + .expr1 + .hessian[, "x", "x"] <- 1 + 1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)*(x+2*(x-1)), c("x"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr4 <- x + 2 * (x - 1) + .value <- .expr1 * .expr4 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- .expr4 + .expr1 * (1 + 2) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)*(x+2*(x-1)), c("x"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr4 <- x + 2 * (x - 1) + .expr6 <- 1 + 2 + .value <- .expr1 * .expr4 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- .expr4 + .expr1 * .expr6 + .hessian[, "x", "x"] <- .expr6 + .expr6 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)+(x+2), c("x"), hessian=FALSE) +expression({ + .value <- x + 1 + (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1 + 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)+(x+2), c("x"), hessian=TRUE) +expression({ + .value <- x + 1 + (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1 + 1 + .hessian[, "x", "x"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)-(x+2), c("x"), hessian=FALSE) +expression({ + .value <- x + 1 - (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1 - 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)-(x+2), c("x"), hessian=TRUE) +expression({ + .value <- x + 1 - (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1 - 1 + .hessian[, "x", "x"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ (x+1)/(x+2), c("x"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr2 <- x + 2 + .value <- .expr1/.expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/.expr2 - .expr1/.expr2^2 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1#Output.IgnoreWhitespace# +#deriv(~ (x+1)/(x+2), c("x"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr2 <- x + 2 + .expr5 <- .expr2^2 + .expr8 <- 1/.expr5 + .value <- .expr1/.expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/.expr2 - .expr1/.expr5 + .hessian[, "x", "x"] <- -(.expr8 + (.expr8 - .expr1 * (2 * + .expr2)/.expr5^2)) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1#Ignored.OutputFormatting# +#deriv(~ (x+1)^(x+2), c("x"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr2 <- x + 2 + .expr3 <- .expr1^.expr2 + .value <- .expr3 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- .expr1^(.expr2 - 1) * .expr2 + .expr3 * log(.expr1) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ -(x+1)+(x+2), c("x"), hessian=FALSE) +expression({ + .value <- -(x + 1) + (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1 - 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ -(x+1)+(x+2), c("x"), hessian=TRUE) +expression({ + .value <- -(x + 1) + (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1 - 1 + .hessian[, "x", "x"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ -(x+1)-(x+2), c("x"), hessian=FALSE) +expression({ + .value <- -(x + 1) - (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- -(1 + 1) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ -(x+1)-(x+2), c("x"), hessian=TRUE) +expression({ + .value <- -(x + 1) - (x + 2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- -(1 + 1) + .hessian[, "x", "x"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ 1, c("x"), hessian=FALSE) +expression({ + .value <- 1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 0 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ 1, c("x"), hessian=TRUE) +expression({ + .value <- 1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ 2*x, c("x"), hessian=FALSE) +expression({ + .value <- 2 * x + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ 2*x, c("x"), hessian=TRUE) +expression({ + .value <- 2 * x + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 2 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1#Ignored.OutputFormatting# +#deriv(~ 2/x, c("x"), hessian=FALSE) +expression({ + .value <- 2/x + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- -(2/x^2) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x+1, c("x"), hessian=FALSE) +expression({ + .value <- x + 1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x+1, c("x"), hessian=TRUE) +expression({ + .value <- x + 1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x, c("x"), hessian=FALSE) +expression({ + .value <- x + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x, c("x"), hessian=TRUE) +expression({ + .value <- x + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x/2, c("x"), hessian=FALSE) +expression({ + .value <- x/2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/2 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x/2, c("x"), hessian=TRUE) +expression({ + .value <- x/2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/2 + .hessian[, "x", "x"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x^2, c("x"), hessian=FALSE) +expression({ + .value <- x^2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#deriv(~ x^2, c("x"), hessian=TRUE) +expression({ + .value <- x^2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 2 * x + .hessian[, "x", "x"] <- 2 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)*(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 2 +attr(,"gradient") + x +[1,] 3 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)*(x+2), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 2 +attr(,"gradient") + x +[1,] 3 +attr(,"hessian") +, , x + + x +[1,] 2 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)*(x+2*(x-1)), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -2 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)*(x+2*(x-1)), c("x"), hessian=TRUE); x<-0; eval(df) +[1] -2 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 6 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)+(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 3 +attr(,"gradient") + x +[1,] 2 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)+(x+2), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 3 +attr(,"gradient") + x +[1,] 2 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)-(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -1 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)-(x+2), c("x"), hessian=TRUE); x<-0; eval(df) +[1] -1 +attr(,"gradient") + x +[1,] 0 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)/(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0.5 +attr(,"gradient") + x +[1,] 0.25 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)/(x+2), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0.5 +attr(,"gradient") + x +[1,] 0.25 +attr(,"hessian") +, , x + + x +[1,] -0.25 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ (x+1)^(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 2 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ -(x+1)+(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ -(x+1)+(x+2), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ -(x+1)-(x+2), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -3 +attr(,"gradient") + x +[1,] -2 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ -(x+1)-(x+2), c("x"), hessian=TRUE); x<-0; eval(df) +[1] -3 +attr(,"gradient") + x +[1,] -2 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ 1, c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ 1, c("x"), hessian=TRUE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ 2*x, c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 2 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ 2*x, c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 2 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ 2/x, c("x"), hessian=FALSE); x<-0; eval(df) +[1] Inf +attr(,"gradient") + x +[1,] -Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x+1, c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x+1, c("x"), hessian=TRUE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x, c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x, c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x/2, c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 0.5 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x/2, c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 0.5 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x^2, c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions1# +#df <- deriv(~ x^2, c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 0 +attr(,"hessian") +, , x + + x +[1,] 2 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ (x+1)*(y+2), c("x","y"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr2 <- y + 2 + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- .expr2 + .grad[, "y"] <- .expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ (x+1)*(y+2), c("x","y"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr2 <- y + 2 + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- .expr2 + .hessian[, "x", "x"] <- 0 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- 1 + .grad[, "y"] <- .expr1 + .hessian[, "y", "y"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ (x+1)*(y+2*(x-1)), c("x","y"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr4 <- y + 2 * (x - 1) + .value <- .expr1 * .expr4 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- .expr4 + .expr1 * 2 + .grad[, "y"] <- .expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ (x+1)*(y+2*(x-1)), c("x","y"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr4 <- y + 2 * (x - 1) + .value <- .expr1 * .expr4 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- .expr4 + .expr1 * 2 + .hessian[, "x", "x"] <- 2 + 2 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- 1 + .grad[, "y"] <- .expr1 + .hessian[, "y", "y"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ (x+1)-(y+2), c("x","y"), hessian=FALSE) +expression({ + .value <- x + 1 - (y + 2) + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- 1 + .grad[, "y"] <- -1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ (x+1)-(y+2), c("x","y"), hessian=TRUE) +expression({ + .value <- x + 1 - (y + 2) + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- 1 + .grad[, "y"] <- -1 + .hessian[, "y", "y"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ (x+1)/(y+2), c("x","y"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr2 <- y + 2 + .value <- .expr1/.expr2 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- 1/.expr2 + .grad[, "y"] <- -(.expr1/.expr2^2) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ (x+1)/(y+2), c("x","y"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr2 <- y + 2 + .expr5 <- .expr2^2 + .value <- .expr1/.expr2 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- 1/.expr2 + .hessian[, "x", "x"] <- 0 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- -(1/.expr5) + .grad[, "y"] <- -(.expr1/.expr5) + .hessian[, "y", "y"] <- .expr1 * (2 * .expr2)/.expr5^2 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ (x+1)^(y+2), c("x","y"), hessian=FALSE) +expression({ + .expr1 <- x + 1 + .expr2 <- y + 2 + .expr3 <- .expr1^.expr2 + .value <- .expr3 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- .expr1^(.expr2 - 1) * .expr2 + .grad[, "y"] <- .expr3 * log(.expr1) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ (x+1)^(y+2), c("x","y"), hessian=TRUE) +expression({ + .expr1 <- x + 1 + .expr2 <- y + 2 + .expr3 <- .expr1^.expr2 + .expr4 <- .expr2 - 1 + .expr5 <- .expr1^.expr4 + .expr11 <- log(.expr1) + .expr15 <- .expr3 * .expr11 + .value <- .expr3 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- .expr5 * .expr2 + .hessian[, "x", "x"] <- .expr1^(.expr4 - 1) * .expr4 * .expr2 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- .expr5 * + .expr11 * .expr2 + .expr5 + .grad[, "y"] <- .expr15 + .hessian[, "y", "y"] <- .expr15 * .expr11 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ -(x+1)+(y+2), c("x","y"), hessian=FALSE) +expression({ + .value <- -(x + 1) + (y + 2) + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- -1 + .grad[, "y"] <- 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ -(x+1)+(y+2), c("x","y"), hessian=TRUE) +expression({ + .value <- -(x + 1) + (y + 2) + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- -1 + .hessian[, "x", "x"] <- 0 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- 0 + .grad[, "y"] <- 1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ -(x+1)-(y+2), c("x","y"), hessian=FALSE) +expression({ + .expr5 <- -1 + .value <- -(x + 1) - (y + 2) + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- .expr5 + .grad[, "y"] <- .expr5 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ -(x+1)-(y+2), c("x","y"), hessian=TRUE) +expression({ + .expr5 <- -1 + .value <- -(x + 1) - (y + 2) + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- .expr5 + .hessian[, "x", "x"] <- 0 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- 0 + .grad[, "y"] <- .expr5 + .hessian[, "y", "y"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ 2*x*y, c("x","y"), hessian=FALSE) +expression({ + .expr1 <- 2 * x + .value <- .expr1 * y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- 2 * y + .grad[, "y"] <- .expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ 2*x*y, c("x","y"), hessian=TRUE) +expression({ + .expr1 <- 2 * x + .value <- .expr1 * y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- 2 * y + .hessian[, "x", "x"] <- 0 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- 2 + .grad[, "y"] <- .expr1 + .hessian[, "y", "y"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ 2/x*y, c("x","y"), hessian=FALSE) +expression({ + .expr1 <- 2/x + .value <- .expr1 * y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- -(2/x^2 * y) + .grad[, "y"] <- .expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ 2/x*y, c("x","y"), hessian=TRUE) +expression({ + .expr1 <- 2/x + .expr3 <- x^2 + .expr4 <- 2/.expr3 + .value <- .expr1 * y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- -(.expr4 * y) + .hessian[, "x", "x"] <- 2 * (2 * x)/.expr3^2 * y + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- -.expr4 + .grad[, "y"] <- .expr1 + .hessian[, "y", "y"] <- 0 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ x + y, c("x","y"), hessian=FALSE) +expression({ + .value <- x + y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- 1 + .grad[, "y"] <- 1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ x + y, c("x","y"), hessian=TRUE) +expression({ + .value <- x + y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- 1 + .grad[, "y"] <- 1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#deriv(~ x*y, c("x","y"), hessian=FALSE) +expression({ + .value <- x * y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- y + .grad[, "y"] <- x + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ x*y, c("x","y"), hessian=TRUE) +expression({ + .value <- x * y + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- y + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- 1 + .grad[, "y"] <- x + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ x/y/2, c("x","y"), hessian=FALSE) +expression({ + .value <- x/y/2 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- 1/y/2 + .grad[, "y"] <- -(x/y^2/2) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ x/y/2, c("x","y"), hessian=TRUE) +expression({ + .expr5 <- y^2 + .value <- x/y/2 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- 1/y/2 + .hessian[, "x", "x"] <- 0 + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- -(1/.expr5/2) + .grad[, "y"] <- -(x/.expr5/2) + .hessian[, "y", "y"] <- x * (2 * y)/.expr5^2/2 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ x^y, c("x","y"), hessian=FALSE) +expression({ + .expr1 <- x^y + .value <- .expr1 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- x^(y - 1) * y + .grad[, "y"] <- .expr1 * log(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2#Ignored.OutputFormatting# +#deriv(~ x^y, c("x","y"), hessian=TRUE) +expression({ + .expr1 <- x^y + .expr2 <- y - 1 + .expr3 <- x^.expr2 + .expr9 <- log(x) + .expr13 <- .expr1 * .expr9 + .value <- .expr1 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- .expr3 * y + .hessian[, "x", "x"] <- x^(.expr2 - 1) * .expr2 * y + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- .expr3 * + .expr9 * y + .expr3 + .grad[, "y"] <- .expr13 + .hessian[, "y", "y"] <- .expr13 * .expr9 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)*(y+2), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 2 +attr(,"gradient") + x y +[1,] 2 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)*(y+2), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 2 +attr(,"gradient") + x y +[1,] 2 1 +attr(,"hessian") +, , x + + x y +[1,] 0 1 + +, , y + + x y +[1,] 1 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)*(y+2*(x-1)), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] -2 +attr(,"gradient") + x y +[1,] 0 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)*(y+2*(x-1)), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] -2 +attr(,"gradient") + x y +[1,] 0 1 +attr(,"hessian") +, , x + + x y +[1,] 4 1 + +, , y + + x y +[1,] 1 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)-(y+2), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] -1 +attr(,"gradient") + x y +[1,] 1 -1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)-(y+2), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] -1 +attr(,"gradient") + x y +[1,] 1 -1 +attr(,"hessian") +, , x + + x y +[1,] 0 0 + +, , y + + x y +[1,] 0 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)/(y+2), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 0.5 +attr(,"gradient") + x y +[1,] 0.5 -0.25 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)/(y+2), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 0.5 +attr(,"gradient") + x y +[1,] 0.5 -0.25 +attr(,"hessian") +, , x + + x y +[1,] 0 -0.25 + +, , y + + x y +[1,] -0.25 0.25 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)^(y+2), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 1 +attr(,"gradient") + x y +[1,] 2 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)^(y+2), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 1 +attr(,"gradient") + x y +[1,] 2 0 +attr(,"hessian") +, , x + + x y +[1,] 2 1 + +, , y + + x y +[1,] 1 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ (x+1)^(y+2), c("x","y"), hessian=TRUE); x<-1; y<-1; eval(df) +[1] 8 +attr(,"gradient") + x y +[1,] 12 5.545177 +attr(,"hessian") +, , x + + x y +[1,] 12 12.31777 + +, , y + + x y +[1,] 12.31777 3.843624 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ -(x+1)+(y+2), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 1 +attr(,"gradient") + x y +[1,] -1 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ -(x+1)+(y+2), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 1 +attr(,"gradient") + x y +[1,] -1 1 +attr(,"hessian") +, , x + + x y +[1,] 0 0 + +, , y + + x y +[1,] 0 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ -(x+1)-(y+2), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] -3 +attr(,"gradient") + x y +[1,] -1 -1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ -(x+1)-(y+2), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] -3 +attr(,"gradient") + x y +[1,] -1 -1 +attr(,"hessian") +, , x + + x y +[1,] 0 0 + +, , y + + x y +[1,] 0 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ 2*x*y, c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 0 +attr(,"gradient") + x y +[1,] 0 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ 2*x*y, c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 0 +attr(,"gradient") + x y +[1,] 0 0 +attr(,"hessian") +, , x + + x y +[1,] 0 2 + +, , y + + x y +[1,] 2 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ 2/x*y, c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] NaN +attr(,"gradient") + x y +[1,] NaN Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ 2/x*y, c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] NaN +attr(,"gradient") + x y +[1,] NaN Inf +attr(,"hessian") +, , x + + x y +[1,] NaN -Inf + +, , y + + x y +[1,] -Inf 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x + y, c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 0 +attr(,"gradient") + x y +[1,] 1 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x + y, c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 0 +attr(,"gradient") + x y +[1,] 1 1 +attr(,"hessian") +, , x + + x y +[1,] 0 0 + +, , y + + x y +[1,] 0 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x*y, c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 0 +attr(,"gradient") + x y +[1,] 0 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x*y, c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 0 +attr(,"gradient") + x y +[1,] 0 0 +attr(,"hessian") +, , x + + x y +[1,] 0 1 + +, , y + + x y +[1,] 1 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x/y/2, c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] NaN +attr(,"gradient") + x y +[1,] Inf NaN + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x/y/2, c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] NaN +attr(,"gradient") + x y +[1,] Inf NaN +attr(,"hessian") +, , x + + x y +[1,] 0 -Inf + +, , y + + x y +[1,] -Inf NaN + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x^y, c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] 1 +attr(,"gradient") + x y +[1,] NaN -Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveBasicExpressions2# +#df <- deriv(~ x^y, c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] 1 +attr(,"gradient") + x y +[1,] NaN -Inf +attr(,"hessian") +, , x + + x y +[1,] NaN NaN + +, , y + + x y +[1,] NaN Inf + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.OutputFormatting# +#deriv(~ acos(x), c("x"), hessian=FALSE) +expression({ + .value <- acos(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- -(1/sqrt(1 - x^2)) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ asin(x), c("x"), hessian=FALSE) +expression({ + .value <- asin(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/sqrt(1 - x^2) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ asin(x), c("x"), hessian=TRUE) +expression({ + .expr3 <- 1 - x^2 + .expr4 <- sqrt(.expr3) + .value <- asin(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/.expr4 + .hessian[, "x", "x"] <- 0.5 * (2 * x * .expr3^-0.5)/.expr4^2 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ atan(x), c("x"), hessian=FALSE) +expression({ + .value <- atan(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/(1 + x^2) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.OutputFormatting# +#deriv(~ atan(x), c("x"), hessian=TRUE) +expression({ + .expr3 <- 1 + x^2 + .value <- atan(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/.expr3 + .hessian[, "x", "x"] <- -(2 * x/.expr3^2) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ cos(x), c("x"), hessian=FALSE) +expression({ + .value <- cos(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- -sin(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ cos(x), c("x"), hessian=TRUE) +expression({ + .expr1 <- cos(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- -sin(x) + .hessian[, "x", "x"] <- -.expr1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ cosh(x), c("x"), hessian=FALSE) +expression({ + .value <- cosh(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- sinh(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ cosh(x), c("x"), hessian=TRUE) +expression({ + .expr1 <- cosh(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- sinh(x) + .hessian[, "x", "x"] <- .expr1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ digamma(x), c("x"), hessian=FALSE) +expression({ + .value <- digamma(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- trigamma(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.OutputFormatting# +#deriv(~ dnorm(x), c("x"), hessian=FALSE) +expression({ + .expr1 <- dnorm(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- -(x * .expr1) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ exp(x), c("x"), hessian=FALSE) +expression({ + .expr1 <- exp(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- .expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ exp(x), c("x"), hessian=TRUE) +expression({ + .expr1 <- exp(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- .expr1 + .hessian[, "x", "x"] <- .expr1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ gamma(x), c("x"), hessian=FALSE) +expression({ + .expr1 <- gamma(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- .expr1 * digamma(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ lgamma(x), c("x"), hessian=FALSE) +expression({ + .value <- lgamma(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- digamma(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ log(x), c("x"), hessian=FALSE) +expression({ + .value <- log(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/x + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.OutputFormatting# +#deriv(~ log(x), c("x"), hessian=TRUE) +expression({ + .value <- log(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/x + .hessian[, "x", "x"] <- -(1/x^2) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ pnorm(x), c("x"), hessian=FALSE) +expression({ + .value <- pnorm(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- dnorm(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.OutputFormatting# +#deriv(~ pnorm(x), c("x"), hessian=TRUE) +expression({ + .expr2 <- dnorm(x) + .value <- pnorm(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- .expr2 + .hessian[, "x", "x"] <- -(x * .expr2) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ psigamma(x), c("x"), hessian=FALSE) +expression({ + .value <- psigamma(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- psigamma(x, 1L) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ sin(x), c("x"), hessian=FALSE) +expression({ + .value <- sin(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- cos(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ sin(x), c("x"), hessian=TRUE) +expression({ + .expr1 <- sin(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- cos(x) + .hessian[, "x", "x"] <- -.expr1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ sinh(x), c("x"), hessian=FALSE) +expression({ + .value <- sinh(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- cosh(x) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ sinh(x), c("x"), hessian=TRUE) +expression({ + .expr1 <- sinh(x) + .value <- .expr1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- cosh(x) + .hessian[, "x", "x"] <- .expr1 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ sqrt(x), c("x"), hessian=FALSE) +expression({ + .value <- sqrt(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 0.5 * x^-0.5 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ sqrt(x), c("x"), hessian=TRUE) +expression({ + .value <- sqrt(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 0.5 * x^-0.5 + .hessian[, "x", "x"] <- 0.5 * (-0.5 * x^-1.5) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ tan(x), c("x"), hessian=FALSE) +expression({ + .value <- tan(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/cos(x)^2 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ tan(x), c("x"), hessian=TRUE) +expression({ + .expr2 <- cos(x) + .expr3 <- .expr2^2 + .value <- tan(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/.expr3 + .hessian[, "x", "x"] <- 2 * (sin(x) * .expr2)/.expr3^2 + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ tanh(x), c("x"), hessian=FALSE) +expression({ + .value <- tanh(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 1/cosh(x)^2 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.OutputFormatting# +#deriv(~ tanh(x), c("x"), hessian=TRUE) +expression({ + .expr2 <- cosh(x) + .expr3 <- .expr2^2 + .value <- tanh(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 1/.expr3 + .hessian[, "x", "x"] <- -(2 * (sinh(x) * .expr2)/.expr3^2) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#deriv(~ trigamma(x), c("x"), hessian=FALSE) +expression({ + .value <- trigamma(x) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- psigamma(x, 2L) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ acos(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1.570796 +attr(,"gradient") + x +[1,] -1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ asin(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ asin(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ atan(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ atan(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ cos(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ cos(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 +attr(,"hessian") +, , x + + x +[1,] -1 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ cosh(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ cosh(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 0 +attr(,"hessian") +, , x + + x +[1,] 1 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.Unimplemented# +#df <- deriv(~ digamma(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] NaN +attr(,"gradient") + x +[1,] Inf +Warning message: +In digamma(x) : NaNs produced + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ dnorm(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0.3989423 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ exp(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ exp(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 1 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 1 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.Unimplemented# +#df <- deriv(~ gamma(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] NaN +attr(,"gradient") + x +[1,] NaN +Warning messages: +1: In gamma(x) : NaNs produced +2: In digamma(x) : NaNs produced + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ lgamma(x), c("x"), hessian=FALSE); x<-0.5; eval(df) +[1] 0.5723649 +attr(,"gradient") + x +[1,] -1.96351 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ log(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.MissingWarning# +#df <- deriv(~ log(x), c("x"), hessian=TRUE); x<--1; eval(df) +[1] NaN +attr(,"gradient") + x +[1,] -1 +attr(,"hessian") +, , x + + x +[1,] -1 + +Warning message: +In log(x) : NaNs produced + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ log(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf +attr(,"hessian") +, , x + + x +[1,] -Inf + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ log(x), c("x"), hessian=TRUE); x<-1; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] -1 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ pnorm(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0.5 +attr(,"gradient") + x +[1,] 0.3989423 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ pnorm(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0.5 +attr(,"gradient") + x +[1,] 0.3989423 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.Unimplemented# +#df <- deriv(~ psigamma(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] NaN +attr(,"gradient") + x +[1,] Inf +Warning message: +In psigamma(x) : NaNs produced + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ sin(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ sin(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ sinh(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ sinh(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ sqrt(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ sqrt(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] Inf +attr(,"hessian") +, , x + + x +[1,] -Inf + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ tan(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ tan(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ tanh(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ tanh(x), c("x"), hessian=TRUE); x<--1; eval(df) +[1] -0.7615942 +attr(,"gradient") + x +[1,] 0.4199743 +attr(,"hessian") +, , x + + x +[1,] 0.6397 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ tanh(x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] 0 +attr(,"gradient") + x +[1,] 1 +attr(,"hessian") +, , x + + x +[1,] 0 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1# +#df <- deriv(~ tanh(x), c("x"), hessian=TRUE); x<-1; eval(df) +[1] 0.7615942 +attr(,"gradient") + x +[1,] 0.4199743 +attr(,"hessian") +, , x + + x +[1,] -0.6397 + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctions1#Ignored.Unimplemented# +#df <- deriv(~ trigamma(x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] Inf +attr(,"gradient") + x +[1,] NaN +Warning message: +In psigamma(x, 2L) : NaNs produced + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#deriv(~ log(2*x), c("x"), hessian=FALSE) +expression({ + .expr1 <- 2 * x + .value <- log(.expr1) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2/.expr1 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1#Ignored.OutputFormatting# +#deriv(~ log(2*x), c("x"), hessian=TRUE) +expression({ + .expr1 <- 2 * x + .value <- log(.expr1) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- 2/.expr1 + .hessian[, "x", "x"] <- -(2 * 2/.expr1^2) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#deriv(~ log(sin(2*x)), c("x"), hessian=FALSE) +expression({ + .expr1 <- 2 * x + .expr2 <- sin(.expr1) + .value <- log(.expr2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- cos(.expr1) * 2/.expr2 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1#Output.IgnoreWhitespace# +#deriv(~ log(sin(2*x)), c("x"), hessian=TRUE) +expression({ + .expr1 <- 2 * x + .expr2 <- sin(.expr1) + .expr5 <- cos(.expr1) * 2 + .value <- log(.expr2) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL, + c("x"), c("x"))) + .grad[, "x"] <- .expr5/.expr2 + .hessian[, "x", "x"] <- -(.expr2 * 2 * 2/.expr2 + .expr5 * + .expr5/.expr2^2) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1#Output.IgnoreWhitespace# +#deriv(~ log(sin(2*x)*cos(x^2)), c("x"), hessian=FALSE) +expression({ + .expr1 <- 2 * x + .expr2 <- sin(.expr1) + .expr3 <- x^2 + .expr4 <- cos(.expr3) + .expr5 <- .expr2 * .expr4 + .value <- log(.expr5) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- (cos(.expr1) * 2 * .expr4 - .expr2 * (sin(.expr3) * + .expr1))/.expr5 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1#Output.IgnoreWhitespace# +#deriv(~ pnorm(sin(2*x)^log(x+1)), c("x"), hessian=FALSE) +expression({ + .expr1 <- 2 * x + .expr2 <- sin(.expr1) + .expr3 <- x + 1 + .expr4 <- log(.expr3) + .expr5 <- .expr2^.expr4 + .value <- pnorm(.expr5) + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- dnorm(.expr5) * (.expr2^(.expr4 - 1) * (.expr4 * + (cos(.expr1) * 2)) + .expr5 * (log(.expr2) * (1/.expr3))) + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#df <- deriv(~ log(2*x), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#df <- deriv(~ log(2*x), c("x"), hessian=TRUE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf +attr(,"hessian") +, , x + + x +[1,] -Inf + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#df <- deriv(~ log(sin(2*x)), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#df <- deriv(~ log(sin(2*x)), c("x"), hessian=TRUE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf +attr(,"hessian") +, , x + + x +[1,] NaN + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#df <- deriv(~ log(sin(2*x)*cos(x^2)), c("x"), hessian=FALSE); x<-0; eval(df) +[1] -Inf +attr(,"gradient") + x +[1,] Inf + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testDeriveFunctionsWithCompArg1# +#df <- deriv(~ pnorm(sin(2*x)^log(x+1)), c("x"), hessian=FALSE); x<-0; eval(df) +[1] 0.8413447 +attr(,"gradient") + x +[1,] NaN + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testFunctionGenereration#Output.IgnoreWhitespace# +#(df <- deriv(~x^2*sin(x), "x", function.arg=TRUE));df(0) +function (x) +{ + .expr1 <- x^2 + .expr2 <- sin(x) + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x * .expr2 + .expr1 * cos(x) + attr(.value, "gradient") <- .grad + .value +} +[1] 0 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testFunctionGenereration#Output.IgnoreWhitespace# +#(df <- deriv(~x^2*sin(x), "x", function.arg=c("x")));df(0) +function (x) +{ + .expr1 <- x^2 + .expr2 <- sin(x) + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x * .expr2 + .expr1 * cos(x) + attr(.value, "gradient") <- .grad + .value +} +[1] 0 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testFunctionGenereration#Output.IgnoreWhitespace# +#(df <- deriv(~x^2*sin(x), "x", function.arg=function(x=1){}));df(0) +function (x = 1) +{ + .expr1 <- x^2 + .expr2 <- sin(x) + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x * .expr2 + .expr1 * cos(x) + attr(.value, "gradient") <- .grad + .value +} +[1] 0 +attr(,"gradient") + x +[1,] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testLongExpression#Output.IgnoreWhitespace# +#deriv(~ (log(2*x)+sin(x))*cos(y^x*(exp(x)))*(x*y+x^y/(x+y+1)), c("x","y"), hessian=FALSE) +expression({ + .expr1 <- 2 * x + .expr4 <- log(.expr1) + sin(x) + .expr5 <- y^x + .expr6 <- exp(x) + .expr7 <- .expr5 * .expr6 + .expr8 <- cos(.expr7) + .expr9 <- .expr4 * .expr8 + .expr11 <- x^y + .expr13 <- x + y + 1 + .expr15 <- x * y + .expr11/.expr13 + .expr21 <- sin(.expr7) + .expr35 <- .expr11/.expr13^2 + .value <- .expr9 * .expr15 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .grad[, "x"] <- ((2/.expr1 + cos(x)) * .expr8 - .expr4 * + (.expr21 * (.expr5 * log(y) * .expr6 + .expr7))) * .expr15 + + .expr9 * (y + (x^(y - 1) * y/.expr13 - .expr35)) + .grad[, "y"] <- .expr9 * (x + (.expr11 * log(x)/.expr13 - + .expr35)) - .expr4 * (.expr21 * (y^(x - 1) * x * .expr6)) * + .expr15 + attr(.value, "gradient") <- .grad + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testLongExpression#Ignored.OutputFormatting# +#deriv(~ (log(2*x)+sin(x))*cos(y^x*(exp(x)))*(x*y+x^y/(x+y+1)), c("x","y"), hessian=TRUE) +expression({ + .expr1 <- 2 * x + .expr3 <- sin(x) + .expr4 <- log(.expr1) + .expr3 + .expr5 <- y^x + .expr6 <- exp(x) + .expr7 <- .expr5 * .expr6 + .expr8 <- cos(.expr7) + .expr9 <- .expr4 * .expr8 + .expr11 <- x^y + .expr13 <- x + y + 1 + .expr15 <- x * y + .expr11/.expr13 + .expr19 <- 2/.expr1 + cos(x) + .expr21 <- sin(.expr7) + .expr22 <- log(y) + .expr23 <- .expr5 * .expr22 + .expr24 <- .expr23 * .expr6 + .expr25 <- .expr24 + .expr7 + .expr26 <- .expr21 * .expr25 + .expr28 <- .expr19 * .expr8 - .expr4 * .expr26 + .expr30 <- y - 1 + .expr31 <- x^.expr30 + .expr32 <- .expr31 * y + .expr34 <- .expr13^2 + .expr35 <- .expr11/.expr34 + .expr37 <- y + (.expr32/.expr13 - .expr35) + .expr40 <- .expr28 * .expr37 + .expr41 <- .expr19 * .expr26 + .expr66 <- .expr32/.expr34 + .expr71 <- .expr11 * (2 * .expr13)/.expr34^2 + .expr77 <- log(x) + .expr78 <- .expr11 * .expr77 + .expr81 <- x + (.expr78/.expr13 - .expr35) + .expr83 <- x - 1 + .expr85 <- y^.expr83 * x + .expr86 <- .expr85 * .expr6 + .expr87 <- .expr21 * .expr86 + .expr89 <- .expr8 * .expr86 + .expr108 <- .expr78/.expr34 + .expr109 <- .expr108 - .expr71 + .expr113 <- .expr4 * .expr87 + .expr125 <- .expr113 * .expr81 + .value <- .expr9 * .expr15 + .grad <- array(0, c(length(.value), 2L), list(NULL, c("x", + "y"))) + .hessian <- array(0, c(length(.value), 2L, 2L), list(NULL, + c("x", "y"), c("x", "y"))) + .grad[, "x"] <- .expr28 * .expr15 + .expr9 * .expr37 + .hessian[, "x", "x"] <- .expr40 - (.expr41 + (.expr3 + 2 * + 2/.expr1^2) * .expr8 + (.expr41 + .expr4 * (.expr8 * + .expr25 * .expr25 + .expr21 * (.expr23 * .expr22 * .expr6 + + .expr24 + .expr25)))) * .expr15 + (.expr40 + .expr9 * + (x^(.expr30 - 1) * .expr30 * y/.expr13 - .expr66 - (.expr66 - + .expr71))) + .hessian[, "x", "y"] <- .hessian[, "y", "x"] <- .expr28 * + .expr81 - (.expr19 * .expr87 + .expr4 * (.expr89 * .expr25 + + .expr21 * ((.expr85 * .expr22 + .expr5 * (1/y)) * .expr6 + + .expr86))) * .expr15 + (.expr9 * (1 + ((.expr31 * + .expr77 * y + .expr31)/.expr13 - .expr66 - .expr109)) - + .expr113 * .expr37) + .grad[, "y"] <- .expr9 * .expr81 - .expr113 * .expr15 + .hessian[, "y", "y"] <- .expr9 * (.expr78 * .expr77/.expr13 - + .expr108 - .expr109) - .expr125 - (.expr4 * (.expr89 * + .expr86 + .expr21 * (y^(.expr83 - 1) * .expr83 * x * + .expr6)) * .expr15 + .expr125) + attr(.value, "gradient") <- .grad + attr(.value, "hessian") <- .hessian + .value +}) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testLongExpression# +#df <- deriv(~ (log(2*x)+sin(x))*cos(y^x*(exp(x)))*(x*y+x^y/(x+y+1)), c("x","y"), hessian=FALSE); x<-0; y<-0; eval(df) +[1] -Inf +attr(,"gradient") + x y +[1,] NaN NaN + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testLongExpression# +#df <- deriv(~ (log(2*x)+sin(x))*cos(y^x*(exp(x)))*(x*y+x^y/(x+y+1)), c("x","y"), hessian=TRUE); x<-0; y<-0; eval(df) +[1] -Inf +attr(,"gradient") + x y +[1,] NaN NaN +attr(,"hessian") +, , x + + x y +[1,] NaN NaN + +, , y + + x y +[1,] NaN NaN + + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testUnusualExprs# +#(df <- deriv(1, "x"));df(0) +expression({ + .value <- 1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 0 + attr(.value, "gradient") <- .grad + .value +}) +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testUnusualExprs# +#(df <- deriv(expression(x^2*sin(x)), "x"));df(0) +expression({ + .expr1 <- x^2 + .expr2 <- sin(x) + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x * .expr2 + .expr1 * cos(x) + attr(.value, "gradient") <- .grad + .value +}) +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testUnusualExprs# +#(df <- deriv(quote(x^2*sin(x)), "x"));df(0) +expression({ + .expr1 <- x^2 + .expr2 <- sin(x) + .value <- .expr1 * .expr2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x * .expr2 + .expr1 * cos(x) + attr(.value, "gradient") <- .grad + .value +}) +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testUnusualExprs# +#g<-quote(x^2);(df <- deriv(g, "x"));df(0) +expression({ + .value <- x^2 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 2 * x + attr(.value, "gradient") <- .grad + .value +}) +Error in df(0) : argument "df1" is missing, with no default + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testUnusualExprs# +#x<-1;(df <- deriv(x, "x"));df(0) +expression({ + .value <- 1 + .grad <- array(0, c(length(.value), 1L), list(NULL, c("x"))) + .grad[, "x"] <- 0 + attr(.value, "gradient") <- .grad + .value +}) +Error in df(0) : argument "df1" is missing, with no default + ##com.oracle.truffle.r.test.builtins.TestBuiltin_det.testDet# #{ det(matrix(c(1,-3,4,-5),nrow=2)) } [1] 7 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_D.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_D.java new file mode 100644 index 0000000000000000000000000000000000000000..6fd2878571ecbc2930acd06ac4419c7daf4aa65e --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_D.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.test.builtins; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; + +public class TestBuiltin_D extends TestBase { + + @Test + public void testD() { + assertEval("(df <- D(expression(x^2*sin(x)), \"x\"));df(0)"); + assertEval("(df <- D(quote(x^2*sin(x)), \"x\"));df(0)"); + assertEval("g<-quote(x^2);(df <- D(g, \"x\"));df(0)"); + assertEval("(df <- D(1, \"x\"));df(0)"); + assertEval("x<-1;(df <- D(x, \"x\"));df(0)"); + } + +} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java new file mode 100644 index 0000000000000000000000000000000000000000..13eae8aaf36d8b65cd6a89324b32744c8ea6686c --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.test.builtins; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; +import com.oracle.truffle.r.test.TestTrait; + +public class TestBuiltin_deriv extends TestBase { + + final class DerivExpr { + final String expr; + final String assertedExpr; + final int dn; + final boolean hessian; + + DerivExpr(String expr, int dn) { + this(expr, dn, false); + } + + DerivExpr(String expr, int dn, boolean hessian) { + this.expr = expr; + this.dn = dn; + this.hessian = hessian; + String vars = dn == 1 ? "c(\"x\")" : "c(\"x\",\"y\")"; + String h = hessian ? "TRUE" : "FALSE"; + this.assertedExpr = "deriv(~ " + expr + ", " + vars + ", hessian=" + h + ")"; + } + + DerivEval derive() { + assertEval(assertedExpr); + return new DerivEval(this); + } + + DerivEval derive(TestTrait trait) { + assertEval(trait, assertedExpr); + return new DerivEval(this); + } + } + + final class DerivEval { + final DerivExpr de; + final String assertedExpr; + + DerivEval(DerivExpr de) { + this.de = de; + String vars = de.dn == 1 ? "x<-%s" : "x<-%s; y<-%s"; + this.assertedExpr = "df <- " + de.assertedExpr + "; " + vars + "; eval(df)"; + } + + DerivEval eval(Object... vals) { + String ex = String.format(this.assertedExpr, vals); + assertEval(ex); + return this; + } + + DerivEval eval(TestTrait trait, Object... vals) { + String ex = String.format(this.assertedExpr, vals); + assertEval(trait, ex); + return this; + } + + DerivExpr withHessian() { + return new DerivExpr(de.expr, de.dn, true); + } + } + + private DerivExpr deriv1(String expr) { + return new DerivExpr(expr, 1); + } + + private DerivExpr deriv2(String expr) { + return new DerivExpr(expr, 2); + } + + private void assertDerivAndEval1(String expr) { + deriv1(expr).derive().eval(0).withHessian().derive().eval(0); + } + + private void assertDerivAndEval1(TestTrait trait, String expr) { + deriv1(expr).derive(trait).eval(0, 0); + } + + private DerivEval assertDeriv1(String expr) { + return deriv1(expr).derive(); + } + + private void assertDerivAndEval2(String expr) { + deriv2(expr).derive().eval(0, 0).withHessian().derive().eval(0, 0); + } + + @Test + public void testDeriveBasicExpressions1() { + assertDerivAndEval1("1"); + assertDerivAndEval1("x"); + assertDerivAndEval1("x+1"); + assertDerivAndEval1("2*x"); + assertDerivAndEval1("x/2"); + assertDerivAndEval1(Ignored.OutputFormatting, "2/x"); + assertDerivAndEval1("x^2"); + assertDerivAndEval1("(x+1)+(x+2)"); + assertDerivAndEval1("(x+1)-(x+2)"); + assertDerivAndEval1("-(x+1)+(x+2)"); + assertDerivAndEval1("-(x+1)-(x+2)"); + assertDerivAndEval1("(x+1)*(x+2)"); + deriv1("(x+1)/(x+2)").derive().eval(0).withHessian().derive(Output.IgnoreWhitespace).eval(0); + assertDerivAndEval1("(x+1)*(x+2*(x-1))"); + assertDerivAndEval1(Ignored.OutputFormatting, "(x+1)^(x+2)"); + } + + @Test + public void testDeriveFunctions1() { + deriv1("log(x)").derive().eval(0).withHessian().derive(Ignored.OutputFormatting).eval(0).eval(1).eval(Ignored.MissingWarning, + -1); + assertDerivAndEval1("exp(x)"); + assertDerivAndEval1("cos(x)"); + assertDerivAndEval1("sin(x)"); + assertDerivAndEval1("tan(x)"); + assertDerivAndEval1("cosh(x)"); + assertDerivAndEval1("sinh(x)"); + deriv1("tanh(x)").derive().eval(0).withHessian().derive(Ignored.OutputFormatting).eval(0).eval(1).eval(-1); + assertDerivAndEval1("sqrt(x)"); + deriv1("pnorm(x)").derive().eval(0).withHessian().derive(Ignored.OutputFormatting).eval(0); + assertDerivAndEval1(Ignored.OutputFormatting, "dnorm(x)"); + assertDerivAndEval1("asin(x)"); + assertDerivAndEval1(Ignored.OutputFormatting, "acos(x)"); + deriv1("atan(x)").derive().eval(0).withHessian().derive(Ignored.OutputFormatting).eval(0); + assertDeriv1("gamma(x)").eval(Ignored.Unimplemented, 0); + assertDeriv1("lgamma(x)").eval(0.5); + assertDeriv1("digamma(x)").eval(Ignored.Unimplemented, 0); + assertDeriv1("trigamma(x)").eval(Ignored.Unimplemented, 0); + assertDeriv1("psigamma(x)").eval(Ignored.Unimplemented, 0); + } + + @Test + public void testDeriveFunctionsWithCompArg1() { + deriv1("log(2*x)").derive().eval(0).withHessian().derive(Ignored.OutputFormatting).eval(0); + deriv1("log(sin(2*x))").derive().eval(0).withHessian().derive(Output.IgnoreWhitespace).eval(0); + assertDerivAndEval1(Output.IgnoreWhitespace, "log(sin(2*x)*cos(x^2))"); + assertDerivAndEval1(Output.IgnoreWhitespace, "pnorm(sin(2*x)^log(x+1))"); + } + + @Test + public void testDeriveBasicExpressions2() { + assertDerivAndEval2("x + y"); + deriv2("x*y").derive().eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("2*x*y").derive().eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("x/y/2").derive(Ignored.OutputFormatting).eval(0, + 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("2/x*y").derive(Ignored.OutputFormatting).eval(0, + 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("x^y").derive(Ignored.OutputFormatting).eval(0, + 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("(x+1)*(y+2)").derive().eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, + 0); + assertDerivAndEval2("(x+1)-(y+2)"); + deriv2("-(x+1)+(y+2)").derive().eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, + 0); + deriv2("-(x+1)-(y+2)").derive().eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, + 0); + deriv2("(x+1)/(y+2)").derive(Ignored.OutputFormatting).eval(0, + 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("(x+1)*(y+2*(x-1))").derive().eval(0, + 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + deriv2("(x+1)^(y+2)").derive().eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, + 0).eval(1, 1); + } + + @Test + public void testLongExpression() { + deriv2("(log(2*x)+sin(x))*cos(y^x*(exp(x)))*(x*y+x^y/(x+y+1))").derive(Output.IgnoreWhitespace).eval(0, 0).withHessian().derive(Ignored.OutputFormatting).eval(0, 0); + } + + @Test + public void testFunctionGenereration() { + assertEval(Output.IgnoreWhitespace, "(df <- deriv(~x^2*sin(x), \"x\", function.arg=TRUE));df(0)"); + assertEval(Output.IgnoreWhitespace, "(df <- deriv(~x^2*sin(x), \"x\", function.arg=c(\"x\")));df(0)"); + assertEval(Output.IgnoreWhitespace, "(df <- deriv(~x^2*sin(x), \"x\", function.arg=function(x=1){}));df(0)"); + } + + @Test + public void testUnusualExprs() { + assertEval("(df <- deriv(expression(x^2*sin(x)), \"x\"));df(0)"); + assertEval("(df <- deriv(quote(x^2*sin(x)), \"x\"));df(0)"); + assertEval("g<-quote(x^2);(df <- deriv(g, \"x\"));df(0)"); + assertEval("(df <- deriv(1, \"x\"));df(0)"); + assertEval("x<-1;(df <- deriv(x, \"x\"));df(0)"); + } + +} diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 9ace1ab1d3a27e419cea334c91beb3be453f17cd..f6786e5110ab80a04fbc540258a0b5e20b71bfcc 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -764,3 +764,5 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/p com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ComplexVectorPrinter.java,gnu_r_gentleman_ihaka2.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LogicalVectorPrinter.java,gnu_r_gentleman_ihaka2.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java,gnu_r_gentleman_ihaka2.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java,gnu_r_gentleman_ihaka2.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/DerivVisitor.java,gnu_r_gentleman_ihaka2.copyright