[SYSTEMML-2077] New second-order eval builtin function Closes #740.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/2af84960 Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/2af84960 Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/2af84960 Branch: refs/heads/master Commit: 2af84960095b2648f10b5a211ad849b3e6366fef Parents: 2cee9bb Author: EdgarLGB <[email protected]> Authored: Thu Mar 8 22:49:42 2018 -0800 Committer: Matthias Boehm <[email protected]> Committed: Thu Mar 8 23:58:08 2018 -0800 ---------------------------------------------------------------------- src/main/java/org/apache/sysml/hops/Hop.java | 3 +- src/main/java/org/apache/sysml/hops/NaryOp.java | 3 +- .../sysml/hops/ipa/InterProceduralAnalysis.java | 2 +- src/main/java/org/apache/sysml/lops/Nary.java | 3 +- .../sysml/parser/BuiltinFunctionExpression.java | 13 +++ .../org/apache/sysml/parser/DMLTranslator.java | 4 + .../org/apache/sysml/parser/Expression.java | 1 + .../sysml/parser/dml/DmlSyntacticValidator.java | 9 +- .../sysml/runtime/functionobjects/Builtin.java | 3 +- .../instructions/CPInstructionParser.java | 3 +- .../cp/BuiltinNaryCPInstruction.java | 3 + .../instructions/cp/EvalNaryCPInstruction.java | 87 ++++++++++++++++++++ .../cp/FunctionCallCPInstruction.java | 2 +- .../integration/mlcontext/MLContextTest.java | 8 ++ .../apache/sysml/api/mlcontext/eval-test.dml | 55 +++++++++++++ 15 files changed, 187 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/hops/Hop.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/Hop.java b/src/main/java/org/apache/sysml/hops/Hop.java index 8b917b4..78c0687 100644 --- a/src/main/java/org/apache/sysml/hops/Hop.java +++ b/src/main/java/org/apache/sysml/hops/Hop.java @@ -1099,7 +1099,7 @@ public abstract class Hop implements ParseInfo // Operations that require a variable number of operands public enum OpOpN { - PRINTF, CBIND, RBIND, + PRINTF, CBIND, RBIND, EVAL } public enum AggOp { @@ -1383,6 +1383,7 @@ public abstract class Hop implements ParseInfo HopsOpOpNLops.put(OpOpN.PRINTF, Nary.OperationType.PRINTF); HopsOpOpNLops.put(OpOpN.CBIND, Nary.OperationType.CBIND); HopsOpOpNLops.put(OpOpN.RBIND, Nary.OperationType.RBIND); + HopsOpOpNLops.put(OpOpN.EVAL, Nary.OperationType.EVAL); } protected static final HashMap<Hop.OpOp1, String> HopsOpOp12String; http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/hops/NaryOp.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/NaryOp.java b/src/main/java/org/apache/sysml/hops/NaryOp.java index bc3b163..1a6da2e 100644 --- a/src/main/java/org/apache/sysml/hops/NaryOp.java +++ b/src/main/java/org/apache/sysml/hops/NaryOp.java @@ -159,7 +159,7 @@ public class NaryOp extends Hop { setRequiresRecompileIfNecessary(); //ensure cp exec type for single-node operations - if ( _op == OpOpN.PRINTF ) + if ( _op == OpOpN.PRINTF || _op == OpOpN.EVAL) _etype = ExecType.CP; return _etype; @@ -187,6 +187,7 @@ public class NaryOp extends Hop { setDim2(HopRewriteUtils.getMaxInputDim(this, false)); break; case PRINTF: + case EVAL: //do nothing: } } http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java b/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java index 3ec5f6a..6a5788e 100644 --- a/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java +++ b/src/main/java/org/apache/sysml/hops/ipa/InterProceduralAnalysis.java @@ -89,7 +89,7 @@ public class InterProceduralAnalysis protected static final boolean INTRA_PROCEDURAL_ANALYSIS = true; //propagate statistics across statement blocks (main/functions) protected static final boolean PROPAGATE_KNOWN_UDF_STATISTICS = true; //propagate statistics for known external functions protected static final boolean ALLOW_MULTIPLE_FUNCTION_CALLS = true; //propagate consistent statistics from multiple calls - protected static final boolean REMOVE_UNUSED_FUNCTIONS = true; //remove unused functions (inlined or never called) + protected static final boolean REMOVE_UNUSED_FUNCTIONS = false; //remove unused functions (inlined or never called) protected static final boolean FLAG_FUNCTION_RECOMPILE_ONCE = true; //flag functions which require recompilation inside a loop for full function recompile protected static final boolean REMOVE_UNNECESSARY_CHECKPOINTS = true; //remove unnecessary checkpoints (unconditionally overwritten intermediates) protected static final boolean REMOVE_CONSTANT_BINARY_OPS = true; //remove constant binary operations (e.g., X*ones, where ones=matrix(1,...)) http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/lops/Nary.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/lops/Nary.java b/src/main/java/org/apache/sysml/lops/Nary.java index 90966fa..7df863a 100644 --- a/src/main/java/org/apache/sysml/lops/Nary.java +++ b/src/main/java/org/apache/sysml/lops/Nary.java @@ -32,7 +32,7 @@ import org.apache.sysml.parser.Expression.ValueType; public class Nary extends Lop { public enum OperationType { - PRINTF, CBIND, RBIND, + PRINTF, CBIND, RBIND, EVAL } private OperationType operationType; @@ -119,6 +119,7 @@ public class Nary extends Lop { case PRINTF: case CBIND: case RBIND: + case EVAL: return operationType.name().toLowerCase(); default: throw new UnsupportedOperationException( http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java b/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java index a79a522..880b698 100644 --- a/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java +++ b/src/main/java/org/apache/sysml/parser/BuiltinFunctionExpression.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.HashSet; import org.antlr.v4.runtime.ParserRuleContext; +import org.apache.sysml.conf.ConfigurationManager; import org.apache.sysml.parser.LanguageException.LanguageErrorCodes; import org.apache.sysml.runtime.util.ConvolutionUtils; import org.apache.sysml.runtime.util.UtilFunctions; @@ -379,6 +380,15 @@ public class BuiltinFunctionExpression extends DataIdentifier this.setOutput(output); switch (this.getOpCode()) { + case EVAL: + if (_args.length == 0) + raiseValidateError("Function eval should provide at least one argument, i.e., the function name.", false); + checkValueTypeParam(_args[0], ValueType.STRING); + output.setDataType(DataType.MATRIX); + output.setValueType(ValueType.DOUBLE); + output.setBlockDimensions(ConfigurationManager.getBlocksize(), + ConfigurationManager.getBlocksize()); + break; case COLSUM: case COLMAX: case COLMIN: @@ -1792,6 +1802,9 @@ public class BuiltinFunctionExpression extends DataIdentifier bifop = Expression.BuiltinFunctionOp.BITWSHIFTR; else if ( functionName.equals("ifelse") ) bifop = Expression.BuiltinFunctionOp.IFELSE; + else if (functionName.equals("eval")) { + bifop = Expression.BuiltinFunctionOp.EVAL; + } else return null; http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/parser/DMLTranslator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/DMLTranslator.java b/src/main/java/org/apache/sysml/parser/DMLTranslator.java index 2bcdde1..220be8a 100644 --- a/src/main/java/org/apache/sysml/parser/DMLTranslator.java +++ b/src/main/java/org/apache/sysml/parser/DMLTranslator.java @@ -2381,6 +2381,10 @@ public class DMLTranslator // Construct the hop based on the type of Builtin function switch (source.getOpCode()) { + case EVAL: + currBuiltinOp = new NaryOp(target.getName(), target.getDataType(), target.getValueType(), OpOpN.EVAL, processAllExpressions(source.getAllExpr(), hops)); + break; + case COLSUM: currBuiltinOp = new AggUnaryOp(target.getName(), target.getDataType(), target.getValueType(), AggOp.SUM, Direction.Col, expr); http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/parser/Expression.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/Expression.java b/src/main/java/org/apache/sysml/parser/Expression.java index ffffb36..ac30657 100644 --- a/src/main/java/org/apache/sysml/parser/Expression.java +++ b/src/main/java/org/apache/sysml/parser/Expression.java @@ -86,6 +86,7 @@ public abstract class Expression implements ParseInfo CUMSUM, DIAG, EIGEN, + EVAL, CONV2D, CONV2D_BACKWARD_FILTER, CONV2D_BACKWARD_DATA, BIAS_ADD, BIAS_MULTIPLY, MAX_POOL, AVG_POOL, MAX_POOL_BACKWARD, AVG_POOL_BACKWARD, EXP, http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java b/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java index a5169fb..c440be4 100644 --- a/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java +++ b/src/main/java/org/apache/sysml/parser/dml/DmlSyntacticValidator.java @@ -119,7 +119,7 @@ public class DmlSyntacticValidator extends CommonSyntacticValidator implements D public DmlSyntacticValidator(CustomErrorListener errorListener, Map<String,String> argVals, String sourceNamespace, Set<String> prepFunctions) { super(errorListener, argVals, sourceNamespace, prepFunctions); } - + @Override public String namespaceResolutionOp() { return "::"; } @Override public String trueStringLiteral() { return "TRUE"; } @Override public String falseStringLiteral() { return "FALSE"; } @@ -492,9 +492,9 @@ public class DmlSyntacticValidator extends CommonSyntacticValidator implements D String namespace = fnNames[0]; String functionName = fnNames[1]; ArrayList<ParameterExpression> paramExpression = getParameterExpressionList(ctx.paramExprs); - + castAsScalarDeprecationCheck(functionName, ctx); - + boolean hasLHS = ctx.targetList != null; functionCallAssignmentStatementHelper(ctx, printStatements, outputStatements, hasLHS ? ctx.targetList.dataInfo.expr : null, ctx.info, ctx.name, hasLHS ? ctx.targetList.start : null, namespace, functionName, paramExpression, hasLHS); @@ -519,7 +519,6 @@ public class DmlSyntacticValidator extends CommonSyntacticValidator implements D String functionName = names[1]; ArrayList<ParameterExpression> paramExpression = getParameterExpressionList(ctx.paramExprs); - castAsScalarDeprecationCheck(functionName, ctx); ConvertedDMLSyntax convertedSyntax = convertToDMLSyntax(ctx, namespace, functionName, paramExpression, ctx.name); @@ -714,7 +713,7 @@ public class DmlSyntacticValidator extends CommonSyntacticValidator implements D dataType = paramCtx.paramType.dataType().getText(); } - + //check and assign data type checkValidDataType(dataType, paramCtx.start); if( dataType.equalsIgnoreCase("matrix") ) http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java index 41cb709..ef0a6c0 100644 --- a/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java +++ b/src/main/java/org/apache/sysml/runtime/functionobjects/Builtin.java @@ -51,7 +51,7 @@ public class Builtin extends ValueFunction public enum BuiltinCode { SIN, COS, TAN, SINH, COSH, TANH, ASIN, ACOS, ATAN, LOG, LOG_NZ, MIN, MAX, ABS, SIGN, SQRT, EXP, PLOGP, PRINT, PRINTF, NROW, NCOL, LENGTH, ROUND, MAXINDEX, MININDEX, - STOP, CEIL, FLOOR, CUMSUM, CUMPROD, CUMMIN, CUMMAX, INVERSE, SPROP, SIGMOID } + STOP, CEIL, FLOOR, CUMSUM, CUMPROD, CUMMIN, CUMMAX, INVERSE, SPROP, SIGMOID, EVAL } public BuiltinCode bFunc; private static final boolean FASTMATH = true; @@ -81,6 +81,7 @@ public class Builtin extends ValueFunction String2BuiltinCode.put( "plogp" , BuiltinCode.PLOGP); String2BuiltinCode.put( "print" , BuiltinCode.PRINT); String2BuiltinCode.put( "printf" , BuiltinCode.PRINTF); + String2BuiltinCode.put( "eval" , BuiltinCode.EVAL); String2BuiltinCode.put( "nrow" , BuiltinCode.NROW); String2BuiltinCode.put( "ncol" , BuiltinCode.NCOL); String2BuiltinCode.put( "length" , BuiltinCode.LENGTH); http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java b/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java index de8deea..43b3895 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/CPInstructionParser.java @@ -182,7 +182,8 @@ public class CPInstructionParser extends InstructionParser String2CPInstructionType.put( "printf" , CPType.BuiltinNary); String2CPInstructionType.put( "cbind" , CPType.BuiltinNary); String2CPInstructionType.put( "rbind" , CPType.BuiltinNary); - + String2CPInstructionType.put( "eval" , CPType.BuiltinNary); + // Parameterized Builtin Functions String2CPInstructionType.put( "cdf" , CPType.ParameterizedBuiltin); String2CPInstructionType.put( "invcdf" , CPType.ParameterizedBuiltin); http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java index 1ed6055..e38fc0b 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/BuiltinNaryCPInstruction.java @@ -66,6 +66,9 @@ public abstract class BuiltinNaryCPInstruction extends CPInstruction else if( opcode.equals("cbind") || opcode.equals("rbind") ) { return new MatrixBuiltinNaryCPInstruction(null, opcode, str, outputOperand, inputOperands); + } + else if (Nary.OperationType.EVAL.name().equalsIgnoreCase(opcode)) { + return new EvalNaryCPInstruction(null, opcode, str, outputOperand, inputOperands); } throw new DMLRuntimeException("Opcode (" + opcode + ") not recognized in BuiltinMultipleCPInstruction"); http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java new file mode 100644 index 0000000..39f9755 --- /dev/null +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/EvalNaryCPInstruction.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.sysml.runtime.instructions.cp; + +import org.apache.sysml.runtime.DMLRuntimeException; +import org.apache.sysml.runtime.controlprogram.Program; +import org.apache.sysml.runtime.controlprogram.caching.FrameObject; +import org.apache.sysml.runtime.controlprogram.caching.MatrixObject; +import org.apache.sysml.runtime.controlprogram.context.ExecutionContext; +import org.apache.sysml.runtime.matrix.data.MatrixBlock; +import org.apache.sysml.runtime.matrix.operators.Operator; +import org.apache.sysml.runtime.util.DataConverter; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Eval built-in function instruction + * Note: it supports only single matrix[double] output + */ +public class EvalNaryCPInstruction extends BuiltinNaryCPInstruction { + + public EvalNaryCPInstruction(Operator op, String opcode, String istr, CPOperand output, CPOperand... inputs) { + super(op, opcode, istr, output, inputs); + } + + @Override + public void processInstruction(ExecutionContext ec) throws DMLRuntimeException { + //1. get the namespace and func + String funcName = ec.getScalarInput(inputs[0]).getStringValue(); + if( funcName.contains(Program.KEY_DELIM) ) + throw new DMLRuntimeException("Eval calls to '"+funcName+"', i.e., a function outside " + + "the default "+ "namespace, are not supported yet. Please call the function directly."); + + // bound the inputs to avoiding being deleted after the function call + CPOperand[] boundInputs = Arrays.copyOfRange(inputs, 1, inputs.length); + ArrayList<String> boundOutputNames = new ArrayList<>(); + boundOutputNames.add(output.getName()); + ArrayList<String> boundInputNames = new ArrayList<>(); + for (CPOperand input : boundInputs) { + boundInputNames.add(input.getName()); + } + + //2. copy the created output matrix + MatrixObject outputMO = new MatrixObject(ec.getMatrixObject(output.getName())); + + //3. call the function + FunctionCallCPInstruction fcpi = new FunctionCallCPInstruction( + null, funcName, boundInputs, boundInputNames, boundOutputNames, "eval func"); + fcpi.processInstruction(ec); + + //4. convert the result to matrix + Data newOutput = ec.getVariable(output); + if (newOutput instanceof MatrixObject) { + return; + } + MatrixBlock mb = null; + if (newOutput instanceof ScalarObject) { + //convert scalar to matrix + mb = new MatrixBlock(((ScalarObject) newOutput).getDoubleValue()); + } else if (newOutput instanceof FrameObject) { + //convert frame to matrix + mb = DataConverter.convertToMatrixBlock(((FrameObject) newOutput).acquireRead()); + ec.cleanupCacheableData((FrameObject) newOutput); + } + outputMO.acquireModify(mb); + outputMO.release(); + ec.setVariable(output.getName(), outputMO); + } +} http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java b/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java index 953c365..eb44f81 100644 --- a/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java +++ b/src/main/java/org/apache/sysml/runtime/instructions/cp/FunctionCallCPInstruction.java @@ -45,7 +45,7 @@ public class FunctionCallCPInstruction extends CPInstruction { private final ArrayList<String> _boundInputNames; private final ArrayList<String> _boundOutputNames; - private FunctionCallCPInstruction(String namespace, String functName, CPOperand[] boundInputs, + public FunctionCallCPInstruction(String namespace, String functName, CPOperand[] boundInputs, ArrayList<String> boundInputNames, ArrayList<String> boundOutputNames, String istr) { super(CPType.External, null, functName, istr); _functionName = functName; http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java b/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java index 6dc3053..e70faa9 100644 --- a/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java +++ b/src/test/java/org/apache/sysml/test/integration/mlcontext/MLContextTest.java @@ -89,6 +89,14 @@ import scala.collection.Seq; public class MLContextTest extends MLContextTestBase { @Test + public void testCreateDMLScriptBasedOnFileAndExecuteEvalTest() { + System.out.println("MLContextTest - create DML script based on file and execute"); + setExpectedStdOut("10"); + Script script = dmlFromFile(baseDirectory + File.separator + "eval-test.dml"); + ml.execute(script); + } + + @Test public void testCreateDMLScriptBasedOnStringAndExecute() { System.out.println("MLContextTest - create DML script based on string and execute"); String testString = "Create DML script based on string and execute"; http://git-wip-us.apache.org/repos/asf/systemml/blob/2af84960/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml ---------------------------------------------------------------------- diff --git a/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml b/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml new file mode 100644 index 0000000..7637c55 --- /dev/null +++ b/src/test/scripts/org/apache/sysml/api/mlcontext/eval-test.dml @@ -0,0 +1,55 @@ +#------------------------------------------------------------- +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +#------------------------------------------------------------- + +# product between matrix and scalar +f1 = function (matrix[double] M, double factor) return (double res) { + res = prod(M) * factor +} + +# replace the matrix with a scalar and then use calculate the product +f2 = function (matrix[double] M, double r) return (double res) { + R = replace(target=M, pattern=1, replacement=r) + res = f1(R, 10) +} + +# production of two matrix +f3 = function (matrix[double] M1, matrix[double] M2) return (matrix[double] res) { + res = M1 %*% M2 +} + +f4 = function (matrix[double] M1, matrix[double] M2) return (matrix[double] res) { + res = M1 %*% M2 +} + +# some variables +X = matrix("1 2 3 4", rows=2, cols=2) +y = 10 + +R1 = eval("f1", X, y) +R2 = eval("f2", X, y) +R3 = eval("f3", X, X) +for(i in 3:4) + R4 = eval("f"+i, X, X); + +print(toString(R1)) +print(toString(R2)) +print(toString(R3)) +print(toString(R4))
