Repository: incubator-systemml
Updated Branches:
  refs/heads/master dfdd774f6 -> fcfe893f1


[SYSTEMML-510] Generalized wdivmm w/ eps all patterns

This patch with related tests extends the existing wdivmm operator by
two patterns for four operands:
   t(t(U)%%(W(U%%t(V)+x))), and (W(U%%t(V)+x)%%V, where x is a scalar (e.g., 
epsilon).
Supporting these patterns allows a DML script to contain epsilon similar to
an equivalent R script that included epsilon to prevent divide-by-zero.

Closes #77.


Project: http://git-wip-us.apache.org/repos/asf/incubator-systemml/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-systemml/commit/fcfe893f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-systemml/tree/fcfe893f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-systemml/diff/fcfe893f

Branch: refs/heads/master
Commit: fcfe893f10596407e07b80b374613fe39bcc9375
Parents: dfdd774
Author: Glenn Weidner <[email protected]>
Authored: Thu Mar 3 10:50:19 2016 -0800
Committer: Deron Eriksson <[email protected]>
Committed: Thu Mar 3 10:50:19 2016 -0800

----------------------------------------------------------------------
 docs/devdocs/MatrixMultiplicationOperators.txt  |  5 +-
 .../org/apache/sysml/hops/QuaternaryOp.java     | 28 +++---
 .../RewriteAlgebraicSimplificationDynamic.java  | 63 +++++++++++++
 .../org/apache/sysml/lops/WeightedDivMM.java    | 25 ++++--
 .../org/apache/sysml/lops/WeightedDivMMR.java   | 11 ++-
 .../cp/QuaternaryCPInstruction.java             | 18 +++-
 .../instructions/mr/QuaternaryInstruction.java  | 16 +++-
 .../spark/QuaternarySPInstruction.java          |  9 +-
 .../runtime/matrix/data/LibMatrixMult.java      | 37 +++++---
 .../sysml/runtime/matrix/data/MatrixBlock.java  |  4 +
 .../matrix/operators/QuaternaryOperator.java    | 21 +++++
 .../quaternary/WeightedDivMatrixMultTest.java   | 94 +++++++++++++++++++-
 .../functions/quaternary/WeightedDivMMLeftEps.R | 38 ++++++++
 .../quaternary/WeightedDivMMLeftEps.dml         | 32 +++++++
 .../quaternary/WeightedDivMMRightEps.R          | 38 ++++++++
 .../quaternary/WeightedDivMMRightEps.dml        | 32 +++++++
 16 files changed, 426 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/docs/devdocs/MatrixMultiplicationOperators.txt
----------------------------------------------------------------------
diff --git a/docs/devdocs/MatrixMultiplicationOperators.txt 
b/docs/devdocs/MatrixMultiplicationOperators.txt
index f10672d..9809454 100644
--- a/docs/devdocs/MatrixMultiplicationOperators.txt
+++ b/docs/devdocs/MatrixMultiplicationOperators.txt
@@ -1,6 +1,6 @@
 #####################################################################
 # TITLE: An Overview of Matrix Multiplication Operators in SystemML #
-# DATE MODIFIED: 11/21/2015                                         #
+# DATE MODIFIED: 02/20/2016                                         #
 #####################################################################
 
 In the following, we give an overview of backend-specific physical matrix 
multiplication operators in SystemML as well as their internally used matrix 
multiplication block operations.
@@ -115,7 +115,8 @@ C) CORE MATRIX MULT PRIMITIVES LibMatrixMult (incl related 
script patterns)
                (c) t(t(U)%*%(W*(U%*%t(V)))), (d) (W*(U%*%t(V)))%*%V, 
                (e) W*(U%*%t(V)), (f) t(t(U)%*%((X!=0)*(U%*%t(V)-X))),
                (g) (X!=0)*(U%*%t(V)-X)%*%V, (h) t(t(U)%*%(W*(U%*%t(V)-X))),  
-               (i) (W*(U%*%t(V)-X)%*%V
+               (i) (W*(U%*%t(V)-X)%*%V,
+               (j) t(t(U)%*%(W/(U%*%t(V)+x))), (k) (W/(U%*%t(V)+x))%*%V
   - sequential / multi-threaded (same block ops, par over rows in X)           
      
   - all dense, sparse-dense factors, sparse/dense-* x 9 patterns
 

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/hops/QuaternaryOp.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/QuaternaryOp.java 
b/src/main/java/org/apache/sysml/hops/QuaternaryOp.java
index 6cfd32c..b011b8e 100644
--- a/src/main/java/org/apache/sysml/hops/QuaternaryOp.java
+++ b/src/main/java/org/apache/sysml/hops/QuaternaryOp.java
@@ -819,10 +819,10 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                //MR operator selection, part1
                double m1Size = OptimizerUtils.estimateSize(U.getDim1(), 
U.getDim2()); //size U
                double m2Size = OptimizerUtils.estimateSize(V.getDim1(), 
V.getDim2()); //size V
-               boolean isMapWsloss = (!wtype.hasFourInputs() &&
+               boolean isMapWdivmm = ((!wtype.hasFourInputs() || 
wtype.hasScalar()) &&
                                m1Size+m2Size < 
OptimizerUtils.getRemoteMemBudgetMap(true)); 
                
-               if( !FORCE_REPLICATION && isMapWsloss ) //broadcast
+               if( !FORCE_REPLICATION && isMapWdivmm ) //broadcast
                {
                        //partitioning of U
                        boolean needPartU = !U.dimsKnown() || U.getDim1() * 
U.getDim2() > DistributedCacheInput.PARTITION_SIZE;
@@ -842,7 +842,7 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                                setLineNumbers(lV);     
                        }
                        
-                       //map-side wsloss always with broadcast
+                       //map-side wdivmm always with broadcast
                        Lop wdivmm = new WeightedDivMM( W.constructLops(), lU, 
lV, X.constructLops(), 
                                        DataType.MATRIX, ValueType.DOUBLE, 
wtype, ExecType.MR);
                        setOutputDimensions(wdivmm);
@@ -861,7 +861,7 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                        setLineNumbers(grpW);
                        
                        Lop grpX = X.constructLops();
-                       if( wtype.hasFourInputs() )
+                       if( wtype.hasFourInputs() && (X.getDataType() != 
DataType.SCALAR) )
                                grpX = new Group(grpX, 
Group.OperationTypes.Sort, DataType.MATRIX, ValueType.DOUBLE);
                        grpX.getOutputParameters().setDimensions(X.getDim1(), 
X.getDim2(), X.getRowsInBlock(), X.getColsInBlock(), X.getNnz());
                        setLineNumbers(grpX);
@@ -921,7 +921,7 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                                lV = grpV;
                        }
                        
-                       //reduce-side wsloss w/ or without broadcast
+                       //reduce-side wdivmm w/ or without broadcast
                        Lop wdivmm = new WeightedDivMMR( grpW, lU, lV, grpX, 
                                        DataType.MATRIX, ValueType.DOUBLE, 
wtype, cacheU, cacheV, ExecType.MR);
                        setOutputDimensions(wdivmm);
@@ -970,12 +970,12 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                //MR operator selection, part1
                double m1Size = OptimizerUtils.estimateSize(U.getDim1(), 
U.getDim2()); //size U
                double m2Size = OptimizerUtils.estimateSize(V.getDim1(), 
V.getDim2()); //size V
-               boolean isMapWsloss = (!wtype.hasFourInputs() && m1Size+m2Size 
< memBudgetExec
+               boolean isMapWdivmm = ((!wtype.hasFourInputs() || 
wtype.hasScalar()) && m1Size+m2Size < memBudgetExec
                                && 2*m1Size<memBudgetLocal && 
2*m2Size<memBudgetLocal); 
                
-               if( !FORCE_REPLICATION && isMapWsloss ) //broadcast
+               if( !FORCE_REPLICATION && isMapWdivmm ) //broadcast
                {
-                       //map-side wsloss always with broadcast
+                       //map-side wdivmm always with broadcast
                        Lop wdivmm = new WeightedDivMM( W.constructLops(), 
U.constructLops(), V.constructLops(), 
                                        X.constructLops(), DataType.MATRIX, 
ValueType.DOUBLE, wtype, ExecType.SPARK);
                        setOutputDimensions(wdivmm);
@@ -989,7 +989,7 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                        boolean cacheV = !FORCE_REPLICATION && ((!cacheU && 
m2Size < memBudgetExec ) 
                                                || (cacheU && m1Size+m2Size < 
memBudgetExec)) && 2*m2Size < memBudgetLocal;
                        
-                       //reduce-side wsloss w/ or without broadcast
+                       //reduce-side wdivmm w/ or without broadcast
                        Lop wdivmm = new WeightedDivMMR( 
                                        W.constructLops(), U.constructLops(), 
V.constructLops(), X.constructLops(),
                                        DataType.MATRIX, ValueType.DOUBLE, 
wtype, cacheU, cacheV, ExecType.SPARK);
@@ -1507,7 +1507,11 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                                else if( _minus )
                                        return WDivMMType.MULT_MINUS_RIGHT;
                                else
-                                       return _mult ? WDivMMType.MULT_RIGHT : 
WDivMMType.DIV_RIGHT;            
+                                       return _mult ? WDivMMType.MULT_RIGHT : 
WDivMMType.DIV_RIGHT;
+                       case 3: //LEFT w/EPS
+                               return WDivMMType.DIV_LEFT_EPS;
+                       case 4: //RIGHT w/EPS
+                               return WDivMMType.DIV_RIGHT_EPS;
                }
                
                return null;
@@ -1561,7 +1565,7 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                                        MatrixCharacteristics mcW = 
memo.getAllInputStats(getInput().get(0));
                                        ret = new long[]{mcW.getRows(), 
mcW.getCols(), mcW.getNonZeros()};      
                                }
-                               if( _baseType == 1 ) { //left (w/ transpose)
+                               if( _baseType == 1 || _baseType == 3 ) { //left 
(w/ transpose or w/ epsilon)
                                        MatrixCharacteristics mcV = 
memo.getAllInputStats(getInput().get(2));
                                        ret = new long[]{mcV.getRows(), 
mcV.getCols(), -1};
                                }
@@ -1639,7 +1643,7 @@ public class QuaternaryOp extends Hop implements 
MultiThreadedHop
                                        setDim2( inW.getDim2() );
                                        setNnz( inW.getNnz() ); 
                                }
-                               else if( _baseType == 1 ){ //left (w/ transpose)
+                               else if( _baseType == 1 || _baseType == 3 ){ 
//left (w/ transpose or w/ epsilon)
                                        Hop inV = getInput().get(2);
                                        setDim1( inV.getDim1() );
                                        setDim2( inV.getDim2() );               
                

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
 
b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
index 68f3a30..f23f87d 100644
--- 
a/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
+++ 
b/src/main/java/org/apache/sysml/hops/rewrite/RewriteAlgebraicSimplificationDynamic.java
@@ -1871,6 +1871,39 @@ public class RewriteAlgebraicSimplificationDynamic 
extends HopRewriteRule
                                }
                        }       
                        
+                       //Pattern 1e) t(U) %*% (W/(U%*%t(V) + x))
+                       if( !appliedPattern
+                               && right instanceof BinaryOp && 
((BinaryOp)right).getOp() == LOOKUP_VALID_WDIVMM_BINARY[1] //DIV
+                               && 
HopRewriteUtils.isEqualSize(right.getInput().get(0), right.getInput().get(1)) 
//prevent mv
+                               && right.getInput().get(1) instanceof BinaryOp
+                               && ((BinaryOp) right.getInput().get(1)).getOp() 
== Hop.OpOp2.PLUS
+                               && 
right.getInput().get(1).getInput().get(1).getDataType() == DataType.SCALAR
+                               && 
HopRewriteUtils.isSingleBlock(right.getInput().get(1).getInput().get(0).getInput().get(0),true)
 ) //BLOCKSIZE CONSTRAINT
+                       {
+                               Hop W = right.getInput().get(0); 
+                               Hop U = 
right.getInput().get(1).getInput().get(0).getInput().get(0);
+                               Hop V = 
right.getInput().get(1).getInput().get(0).getInput().get(1);
+                               Hop X = 
right.getInput().get(1).getInput().get(1);
+                               
+                               if( HopRewriteUtils.isTransposeOfItself(left, 
U) ) 
+                               {
+                                       if( 
!HopRewriteUtils.isTransposeOperation(V) )
+                                               V = 
HopRewriteUtils.createTranspose(V);
+                                       else 
+                                               V = V.getInput().get(0);
+                                       
+                                       hnew = new QuaternaryOp(hi.getName(), 
DataType.MATRIX, ValueType.DOUBLE, 
+                                                         OpOp4.WDIVMM, W, U, 
V, X, 3, false, false); // 3=>DIV_LEFT_EPS
+                                       
HopRewriteUtils.setOutputBlocksizes(hnew, W.getRowsInBlock(), 
W.getColsInBlock());
+                                       
+                                       //add output transpose for efficient 
target indexing (redundant t() removed by other rewrites)
+                                       hnew = 
HopRewriteUtils.createTranspose(hnew);
+                                       
+                                       appliedPattern = true;
+                                       LOG.debug("Applied 
simplifyWeightedDivMM1e (line "+hi.getBeginLine()+")");                         
             
+                               }
+                       }       
+                       
                        //Pattern 2) (W/(U%*%t(V))) %*% V
                        //alternative pattern: (W*(U%*%t(V))) %*% V
                        if( !appliedPattern
@@ -1900,6 +1933,36 @@ public class RewriteAlgebraicSimplificationDynamic 
extends HopRewriteRule
                                }
                        }
                        
+                       //Pattern 2e) (W/(U%*%t(V) + x)) %*% V
+                       if( !appliedPattern
+                               && left instanceof BinaryOp && 
((BinaryOp)left).getOp() == LOOKUP_VALID_WDIVMM_BINARY[1] //DIV
+                               && 
HopRewriteUtils.isEqualSize(left.getInput().get(0), left.getInput().get(1)) 
//prevent mv
+                               && left.getInput().get(1) instanceof BinaryOp
+                               && ((BinaryOp) left.getInput().get(1)).getOp() 
== Hop.OpOp2.PLUS
+                               && 
left.getInput().get(1).getInput().get(1).getDataType() == DataType.SCALAR
+                               && 
HopRewriteUtils.isSingleBlock(left.getInput().get(1).getInput().get(0).getInput().get(0),true)
 ) //BLOCKSIZE CONSTRAINT
+                       {
+                               Hop W = left.getInput().get(0); 
+                               Hop U = 
left.getInput().get(1).getInput().get(0).getInput().get(0);
+                               Hop V = 
left.getInput().get(1).getInput().get(0).getInput().get(1);
+                               Hop X = 
left.getInput().get(1).getInput().get(1);
+                               
+                               if( HopRewriteUtils.isTransposeOfItself(right, 
V) ) 
+                               {
+                                       if( 
!HopRewriteUtils.isTransposeOperation(V) )
+                                               V = right;
+                                       else 
+                                               V = V.getInput().get(0);
+                                       
+                                       hnew = new QuaternaryOp(hi.getName(), 
DataType.MATRIX, ValueType.DOUBLE, 
+                                                         OpOp4.WDIVMM, W, U, 
V, X, 4, false, false); // 4=>DIV_RIGHT_EPS
+                                       
HopRewriteUtils.setOutputBlocksizes(hnew, W.getRowsInBlock(), 
W.getColsInBlock());
+
+                                       appliedPattern = true;
+                                       LOG.debug("Applied 
simplifyWeightedDivMM2e (line "+hi.getBeginLine()+")");      
+                               }
+                       }
+                       
                        //Pattern 3) t(U) %*% ((X!=0)*(U%*%t(V)-X))
                        if( !appliedPattern
                                && right instanceof BinaryOp && 
((BinaryOp)right).getOp()==LOOKUP_VALID_WDIVMM_BINARY[0] //MULT

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/lops/WeightedDivMM.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/lops/WeightedDivMM.java 
b/src/main/java/org/apache/sysml/lops/WeightedDivMM.java
index 94f5c19..19a167d 100644
--- a/src/main/java/org/apache/sysml/lops/WeightedDivMM.java
+++ b/src/main/java/org/apache/sysml/lops/WeightedDivMM.java
@@ -38,6 +38,8 @@ public class WeightedDivMM extends Lop
        public enum WDivMMType {
                DIV_LEFT,                       //t(t(U) %*% (W / U%*%t(V)))
                DIV_RIGHT,                      //(W / U%*%t(V)) %*% V
+               DIV_LEFT_EPS,           //t(t(U) %*% (W / (U%*%t(V) + x)))
+               DIV_RIGHT_EPS,          //(W / (U%*%t(V) + x)) %*% V
                MULT_BASIC,                     //(W * U%*%t(V))
                MULT_LEFT,                      //t(t(U) %*% (W * U%*%t(V)))
                MULT_RIGHT,                     //(W * U%*%t(V)) %*% V
@@ -51,7 +53,7 @@ public class WeightedDivMM extends Lop
                        return (this == MULT_BASIC);
                }
                public boolean isLeft() {
-                       return (this == DIV_LEFT || this == MULT_LEFT 
+                       return (this == DIV_LEFT || this == DIV_LEFT_EPS || 
this == MULT_LEFT 
                                        || this == MULT_MINUS_LEFT || this == 
MULT_MINUS_4_LEFT);
                }
                public boolean isRight() {
@@ -66,7 +68,11 @@ public class WeightedDivMM extends Lop
                                        || this == MULT_MINUS_4_LEFT || this == 
MULT_MINUS_4_RIGHT);
                }
                public boolean hasFourInputs() {
-                       return (this == MULT_MINUS_4_LEFT || this == 
MULT_MINUS_4_RIGHT);
+                       return (this == MULT_MINUS_4_LEFT || this == 
MULT_MINUS_4_RIGHT 
+                                       || this == DIV_LEFT_EPS || this == 
DIV_RIGHT_EPS);
+               }
+               public boolean hasScalar() {
+                       return (this == DIV_LEFT_EPS || this == DIV_RIGHT_EPS);
                }
                
                public MatrixCharacteristics computeOutputCharacteristics(long 
Xrlen, long Xclen, long rank) {
@@ -145,10 +151,12 @@ public class WeightedDivMM extends Lop
        {
                StringBuilder sb = new StringBuilder();
                
-               sb.append(getExecType());
+               final ExecType et = getExecType();
+               
+               sb.append(et);
                
                sb.append(Lop.OPERAND_DELIMITOR);
-               if( getExecType() == ExecType.CP )
+               if( et == ExecType.CP )
                        sb.append(OPCODE_CP);
                else
                        sb.append(OPCODE);
@@ -163,7 +171,12 @@ public class WeightedDivMM extends Lop
                sb.append( getInputs().get(2).prepInputOperand(input3));
                
                sb.append(Lop.OPERAND_DELIMITOR);
-               sb.append( getInputs().get(3).prepInputOperand(input4));
+               if ( (et == ExecType.MR) && (getInputs().get(3).getDataType() 
== DataType.SCALAR) ) {
+                       sb.append( 
getInputs().get(3).prepScalarInputOperand(et));
+               }
+               else {
+                       sb.append( getInputs().get(3).prepInputOperand(input4));
+               }
                
                sb.append(Lop.OPERAND_DELIMITOR);
                sb.append( prepOutputOperand(output));
@@ -172,7 +185,7 @@ public class WeightedDivMM extends Lop
                sb.append(_weightsType);
                
                //append degree of parallelism
-               if( getExecType()==ExecType.CP ) {
+               if( et == ExecType.CP ) {
                        sb.append( OPERAND_DELIMITOR );
                        sb.append( _numThreads );
                }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/lops/WeightedDivMMR.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/lops/WeightedDivMMR.java 
b/src/main/java/org/apache/sysml/lops/WeightedDivMMR.java
index 790d90d..cb5bccb 100644
--- a/src/main/java/org/apache/sysml/lops/WeightedDivMMR.java
+++ b/src/main/java/org/apache/sysml/lops/WeightedDivMMR.java
@@ -107,7 +107,9 @@ public class WeightedDivMMR extends Lop
        {
                StringBuilder sb = new StringBuilder();
                
-               sb.append(getExecType());
+               final ExecType et = getExecType();
+               
+               sb.append(et);
                
                sb.append(Lop.OPERAND_DELIMITOR);
                sb.append(OPCODE);
@@ -122,7 +124,12 @@ public class WeightedDivMMR extends Lop
                sb.append( getInputs().get(2).prepInputOperand(input3));
                
                sb.append(Lop.OPERAND_DELIMITOR);
-               sb.append( getInputs().get(3).prepInputOperand(input4));
+               if ( (et == ExecType.MR) && (getInputs().get(3).getDataType() 
== DataType.SCALAR) ) {
+                       sb.append( 
getInputs().get(3).prepScalarInputOperand(et));
+               }
+               else {
+                       sb.append( getInputs().get(3).prepInputOperand(input4));
+               }
                
                sb.append(Lop.OPERAND_DELIMITOR);
                sb.append( prepOutputOperand(output));

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/runtime/instructions/cp/QuaternaryCPInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/QuaternaryCPInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/QuaternaryCPInstruction.java
index 535684c..2e069f2 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/cp/QuaternaryCPInstruction.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/cp/QuaternaryCPInstruction.java
@@ -24,6 +24,7 @@ import org.apache.sysml.lops.WeightedSigmoid.WSigmoidType;
 import org.apache.sysml.lops.WeightedSquaredLoss.WeightsType;
 import org.apache.sysml.lops.WeightedCrossEntropy.WCeMMType;
 import org.apache.sysml.lops.WeightedUnaryMM.WUMMType;
+import org.apache.sysml.parser.Expression.DataType;
 import org.apache.sysml.runtime.DMLRuntimeException;
 import org.apache.sysml.runtime.DMLUnsupportedOperationException;
 import org.apache.sysml.runtime.controlprogram.context.ExecutionContext;
@@ -124,7 +125,14 @@ public class QuaternaryCPInstruction extends 
ComputationCPInstruction
                MatrixBlock matBlock3 = ec.getMatrixInput(input3.getName());
                MatrixBlock matBlock4 = null;
                if( qop.hasFourInputs() ) {
-                       matBlock4 = ec.getMatrixInput(input4.getName());
+                       if (input4.getDataType() == DataType.SCALAR) {
+                               matBlock4 = new MatrixBlock(1, 1, false);
+                               final double eps = 
ec.getScalarInput(input4.getName(), input4.getValueType(), 
input4.isLiteral()).getDoubleValue();
+                               matBlock4.quickSetValue(0, 0, eps);
+                       }
+                       else {
+                               matBlock4 = ec.getMatrixInput(input4.getName());
+                       }
                }
                
                //core execute
@@ -136,12 +144,16 @@ public class QuaternaryCPInstruction extends 
ComputationCPInstruction
                ec.releaseMatrixInput(input3.getName());
                if( qop.wtype1 != null || qop.wtype4 != null ) { //wsloss/wcemm
                        if( qop.wtype1 != null && qop.wtype1.hasFourInputs() )
-                               ec.releaseMatrixInput(input4.getName());
+                               if (input4.getDataType() == DataType.MATRIX) {
+                                       ec.releaseMatrixInput(input4.getName());
+                               }
                        ec.setVariable(output.getName(), new 
DoubleObject(out.getValue(0, 0)));
                }
                else { //wsigmoid / wdivmm / wumm
                        if( qop.wtype3 != null && qop.wtype3.hasFourInputs() )
-                               ec.releaseMatrixInput(input4.getName());
+                               if (input4.getDataType() == DataType.MATRIX) {
+                                       ec.releaseMatrixInput(input4.getName());
+                               }
                        ec.setMatrixOutput(output.getName(), (MatrixBlock)out);
                }
        }       

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/runtime/instructions/mr/QuaternaryInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/mr/QuaternaryInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/mr/QuaternaryInstruction.java
index 58aa63d..4064378 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/mr/QuaternaryInstruction.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/mr/QuaternaryInstruction.java
@@ -97,7 +97,7 @@ public class QuaternaryInstruction extends MRInstruction 
implements IDistributed
        }
        
        public byte getInput4() {
-               return _input3;
+               return _input4;
        }
 
        /**
@@ -215,17 +215,19 @@ public class QuaternaryInstruction extends MRInstruction 
implements IDistributed
                        //parse instruction parts (without exec type)
                        String[] parts = 
InstructionUtils.getInstructionParts(str);
                        
+                       final WDivMMType wtype = WDivMMType.valueOf(parts[6]);
+                       
                        byte in1 = Byte.parseByte(parts[1]);
                        byte in2 = Byte.parseByte(parts[2]);
                        byte in3 = Byte.parseByte(parts[3]);
-                       byte in4 = Byte.parseByte(parts[4]);
+                       byte in4 = wtype.hasScalar() ? -1 : 
Byte.parseByte(parts[4]);
                        byte out = Byte.parseByte(parts[5]);
                        
                        //in mappers always through distcache, in reducers 
through distcache/shuffle
                        boolean cacheU = isRed ? Boolean.parseBoolean(parts[7]) 
: true;
                        boolean cacheV = isRed ? Boolean.parseBoolean(parts[8]) 
: true;
                        
-                       return new QuaternaryInstruction(new 
QuaternaryOperator(WDivMMType.valueOf(parts[6])), in1, in2, in3, in4, out, 
cacheU, cacheV, str);
+                       return new QuaternaryInstruction(new 
QuaternaryOperator(wtype), in1, in2, in3, in4, out, cacheU, cacheV, str);
                }
                else //wsigmoid / wcemm
                {
@@ -333,8 +335,14 @@ public class QuaternaryInstruction extends MRInstruction 
implements IDistributed
                                MatrixValue Xij = inVal;
                                
                                //get Wij if existing (null of WeightsType.NONE 
or WSigmoid any type)
-                               IndexedMatrixValue iWij = 
cachedValues.getFirst(_input4); 
+                               IndexedMatrixValue iWij = (_input4 != -1) ? 
cachedValues.getFirst(_input4) : null; 
                                MatrixValue Wij = (iWij!=null) ? 
iWij.getValue() : null;
+                               if (null == Wij && qop.hasFourInputs()) {
+                                       MatrixBlock mb = new MatrixBlock(1, 1, 
false);
+                                       String[] parts = 
InstructionUtils.getInstructionParts(instString);
+                                       mb.quickSetValue(0, 0, 
Double.valueOf(parts[4]));
+                                       Wij = mb;
+                               }
                                
                                //get Ui and Vj, potentially through 
distributed cache
                                MatrixValue Ui = (!_cacheU) ? 
cachedValues.getFirst(_input2).getValue()     //U

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/runtime/instructions/spark/QuaternarySPInstruction.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/instructions/spark/QuaternarySPInstruction.java
 
b/src/main/java/org/apache/sysml/runtime/instructions/spark/QuaternarySPInstruction.java
index 3792743..11595ba 100644
--- 
a/src/main/java/org/apache/sysml/runtime/instructions/spark/QuaternarySPInstruction.java
+++ 
b/src/main/java/org/apache/sysml/runtime/instructions/spark/QuaternarySPInstruction.java
@@ -168,7 +168,9 @@ public class QuaternarySPInstruction extends 
ComputationSPInstruction
                        boolean cacheU = isRed ? Boolean.parseBoolean(parts[7]) 
: true;
                        boolean cacheV = isRed ? Boolean.parseBoolean(parts[8]) 
: true;
                
-                       return new QuaternarySPInstruction(new 
QuaternaryOperator(WDivMMType.valueOf(parts[6])), in1, in2, in3, in4, out, 
cacheU, cacheV, opcode, str);
+                       final WDivMMType wt = WDivMMType.valueOf(parts[6]);
+                       QuaternaryOperator qop = (wt.hasScalar() ? new 
QuaternaryOperator(wt, Double.parseDouble(in4.getName())) : new 
QuaternaryOperator(wt));
+                       return new QuaternarySPInstruction(qop, in1, in2, in3, 
in4, out, cacheU, cacheV, opcode, str);
                } 
                else //map/redwsigmoid, map/redwcemm
                {
@@ -249,7 +251,7 @@ public class QuaternarySPInstruction extends 
ComputationSPInstruction
                        PartitionedBroadcastMatrix bc2 = _cacheV ? 
sec.getBroadcastForVariable( input3.getName() ) : null;
                        JavaPairRDD<MatrixIndexes,MatrixBlock> inU = (!_cacheU) 
? sec.getBinaryBlockRDDHandleForVariable( input2.getName() ) : null;
                        JavaPairRDD<MatrixIndexes,MatrixBlock> inV = (!_cacheV) 
? sec.getBinaryBlockRDDHandleForVariable( input3.getName() ) : null;
-                       JavaPairRDD<MatrixIndexes,MatrixBlock> inW = 
qop.hasFourInputs() ? 
+                       JavaPairRDD<MatrixIndexes,MatrixBlock> inW = 
(qop.hasFourInputs() && !_input4.isLiteral()) ? 
                                        sec.getBinaryBlockRDDHandleForVariable( 
_input4.getName() ) : null;
 
                        //preparation of transposed and replicated U
@@ -281,6 +283,9 @@ public class QuaternarySPInstruction extends 
ComputationSPInstruction
                        else if( inU == null && inV != null && inW != null )
                                out = in.join(inV).join(inW)
                                        .mapToPair(new 
RDDQuaternaryFunction3(qop, bc1, bc2));
+                       else if( inU == null && inV == null && inW == null ) {
+                               out = in.mapPartitionsToPair(new 
RDDQuaternaryFunction1(qop, bc1, bc2), false);
+                       }
                        //function call w/ four rdd inputs
                        else //need keys in case of wdivmm 
                                out = in.join(inU).join(inV).join(inW)

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
index 52e6b3f..682f272 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/LibMatrixMult.java
@@ -2576,6 +2576,8 @@ public class LibMatrixMult
                final boolean mult = wt.isMult();
                final boolean minus = wt.isMinus();
                final boolean four = wt.hasFourInputs();
+               final boolean scalar = wt.hasScalar();
+               final double eps = scalar ? mX.quickGetValue(0, 0) : 0;
                final int n = mW.clen;
                final int cd = mU.clen;
                
@@ -2604,7 +2606,10 @@ public class LibMatrixMult
                                                        if( basic ) 
                                                                c[ix+j] = 
w[ix+j] * dotProduct(u, v, uix, vix, cd);     
                                                        else if( four ) 
//left/right 
-                                                               wdivmm(w[ix+j], 
x[ix+j], u, v, c, uix, vix, left, cd);
+                                                               if (scalar)
+                                                                       
wdivmm(w[ix+j], eps, u, v, c, uix, vix, left, scalar, cd);
+                                                               else
+                                                                       
wdivmm(w[ix+j], x[ix+j], u, v, c, uix, vix, left, scalar, cd);
                                                        else //left/right 
minus/default
                                                                wdivmm(w[ix+j], 
u, v, c, uix, vix, left, mult, minus, cd);
                                                }
@@ -2631,6 +2636,8 @@ public class LibMatrixMult
                final boolean mult = wt.isMult();
                final boolean minus = wt.isMinus();
                final boolean four = wt.hasFourInputs();
+               final boolean scalar = wt.hasScalar();
+               final double eps = scalar ? mX.quickGetValue(0, 0) : 0;
                final int cd = mU.clen;
                
                SparseBlock w = mW.sparseBlock;
@@ -2660,12 +2667,18 @@ public class LibMatrixMult
                                                //O(n) where n is nnz in w/x 
                                                double[] xvals = x.values(i);
                                                for( ; k<wpos+wlen && 
wix[k]<cu; k++ )
-                                                       wdivmm(wval[k], 
xvals[k], u, v, c, uix, wix[k]*cd, left, cd);
+                                                       if (scalar)
+                                                               wdivmm(wval[k], 
eps, u, v, c, uix, wix[k]*cd, left, scalar, cd);
+                                                       else
+                                                               wdivmm(wval[k], 
xvals[k], u, v, c, uix, wix[k]*cd, left, scalar, cd);
                                        }
                                        else {
                                                //O(n log m) where n/m are nnz 
in w/x
                                                for( ; k<wpos+wlen && 
wix[k]<cu; k++ )
-                                                       wdivmm(wval[k], 
x.get(i, wix[k]), u, v, c, uix, wix[k]*cd, left, cd);
+                                                       if (scalar)
+                                                               wdivmm(wval[k], 
eps, u, v, c, uix, wix[k]*cd, left, scalar, cd);
+                                                       else
+                                                               wdivmm(wval[k], 
x.get(i, wix[k]), u, v, c, uix, wix[k]*cd, left, scalar, cd);
                                        }
                                }
                                else { //left/right minus default
@@ -2698,6 +2711,8 @@ public class LibMatrixMult
                final boolean mult = wt.isMult();
                final boolean minus = wt.isMinus();
                final boolean four = wt.hasFourInputs();
+               final boolean scalar = wt.hasScalar();
+               final double eps = scalar ? mX.quickGetValue(0, 0) : 0;
                final int n = mW.clen; 
                final int cd = mU.clen;
 
@@ -2723,8 +2738,8 @@ public class LibMatrixMult
                                                        ret.appendValue(i, 
wix[k], uvij);
                                                }
                                                else if( four ) { //left/right
-                                                       double xij = 
mX.quickGetValue(i, wix[k]);
-                                                       wdivmm(wval[k], xij, 
mU, mV, c, i, wix[k], left, cd);
+                                                       double xij = scalar ? 
eps : mX.quickGetValue(i, wix[k]);
+                                                       wdivmm(wval[k], xij, 
mU, mV, c, i, wix[k], left, scalar, cd);
                                                }
                                                else { //left/right 
minus/default
                                                        wdivmm(wval[k], mU, mV, 
c, i, wix[k], left, mult, minus, cd);
@@ -2744,8 +2759,8 @@ public class LibMatrixMult
                                                        c[ix+j] = 
dotProductGeneric(mU,mV, i, j, cd);
                                                }
                                                else if( four ) { //left/right
-                                                       double xij = 
mX.quickGetValue(i, j);
-                                                       wdivmm(w[ix+j], xij, 
mU, mV, c, i, j, left, cd);
+                                                       double xij = scalar ? 
eps : mX.quickGetValue(i, j);
+                                                       wdivmm(w[ix+j], xij, 
mU, mV, c, i, j, left, scalar, cd);
                                                }
                                                else { //left/right 
minus/default
                                                        wdivmm(w[ix+j], mU, mV, 
c, i, j, left, mult, minus, cd);
@@ -3654,13 +3669,13 @@ public class LibMatrixMult
         * @param left
         * @param len
         */
-       private static void wdivmm( final double wij, final double xij, 
double[] u, double[] v, double[] c, final int uix, final int vix, final boolean 
left, final int len )
+       private static void wdivmm( final double wij, final double xij, 
double[] u, double[] v, double[] c, final int uix, final int vix, final boolean 
left, final boolean scalar, final int len )
        {
                //compute dot product over ui vj 
                double uvij = dotProduct(u, v, uix, vix, len);
                
                //compute core wdivmm  
-               double tmpval = wij * (uvij - xij);
+               double tmpval = scalar ? wij / (uvij + xij) : wij * (uvij - 
xij);
                
                //prepare inputs for final mm
                int bix = left ? uix : vix;
@@ -3714,13 +3729,13 @@ public class LibMatrixMult
         * @param left
         * @param len
         */
-       private static void wdivmm( final double wij, final double xij, 
MatrixBlock u, MatrixBlock v, double[] c, final int uix, final int vix, final 
boolean left, final int len )
+       private static void wdivmm( final double wij, final double xij, 
MatrixBlock u, MatrixBlock v, double[] c, final int uix, final int vix, final 
boolean left, final boolean scalar, final int len )
        {
                //compute dot product over ui vj 
                double uvij = dotProductGeneric(u, v, uix, vix, len);
                
                //compute core wdivmm
-               double wtmp = wij * (uvij - xij);
+               double wtmp = scalar ? wij / (uvij + xij) : wij * (uvij - xij);
                
                //prepare inputs for final mm
                int bix = left ? uix : vix;

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java 
b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
index ddafe99..49fb9b0 100644
--- a/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
+++ b/src/main/java/org/apache/sysml/runtime/matrix/data/MatrixBlock.java
@@ -5792,6 +5792,10 @@ public class MatrixBlock extends MatrixValue implements 
Externalizable
                else if( qop.wtype3 != null ){ //wdivmm
                        //note: for wdivmm-minus X and W interchanged because W 
always present 
                        MatrixBlock W = qop.wtype3.hasFourInputs() ? 
checkType(wm) : null;
+                       if( qop.getScalar() != 0 ) {
+                               W = new MatrixBlock(1, 1, false);
+                               W.quickSetValue(0, 0, qop.getScalar());
+                       }
                        if( k > 1 )
                                LibMatrixMult.matrixMultWDivMM(X, U, V, W, R, 
qop.wtype3, k);
                        else

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/main/java/org/apache/sysml/runtime/matrix/operators/QuaternaryOperator.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/matrix/operators/QuaternaryOperator.java
 
b/src/main/java/org/apache/sysml/runtime/matrix/operators/QuaternaryOperator.java
index 78ec7af..2fee897 100644
--- 
a/src/main/java/org/apache/sysml/runtime/matrix/operators/QuaternaryOperator.java
+++ 
b/src/main/java/org/apache/sysml/runtime/matrix/operators/QuaternaryOperator.java
@@ -43,6 +43,8 @@ public class QuaternaryOperator extends Operator
        
        public ValueFunction fn;
        
+       private double eps = 0;
+
        /**
         * wsloss
         * 
@@ -72,6 +74,16 @@ public class QuaternaryOperator extends Operator
        }
        
        /**
+        * wdivmm w/epsilon
+        * 
+        * @param wt
+        */
+       public QuaternaryOperator( WDivMMType wt, double epsilon) {
+               wtype3 = wt;
+               eps = epsilon;
+       }
+       
+       /**
         * wcemm
         * 
         * @param wt
@@ -105,4 +117,13 @@ public class QuaternaryOperator extends Operator
                return (wtype1 != null && wtype1.hasFourInputs())
                        || (wtype3 != null && wtype3.hasFourInputs());
        }
+       
+       /**
+        * 
+        * @return epsilon
+        */
+       public double getScalar() {
+               return eps;
+       }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/test/java/org/apache/sysml/test/integration/functions/quaternary/WeightedDivMatrixMultTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/quaternary/WeightedDivMatrixMultTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/quaternary/WeightedDivMatrixMultTest.java
index 3704678..aa7e667 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/quaternary/WeightedDivMatrixMultTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/quaternary/WeightedDivMatrixMultTest.java
@@ -56,10 +56,13 @@ public class WeightedDivMatrixMultTest extends 
AutomatedTestBase
        private final static String TEST_NAME7 = "WeightedDivMMMultMinusRight";
        private final static String TEST_NAME8 = "WeightedDivMM4MultMinusLeft";
        private final static String TEST_NAME9 = "WeightedDivMM4MultMinusRight";
+       private final static String TEST_NAME10 = "WeightedDivMMLeftEps";
+       private final static String TEST_NAME11 = "WeightedDivMMRightEps";
        private final static String TEST_DIR = "functions/quaternary/";
        private final static String TEST_CLASS_DIR = TEST_DIR + 
WeightedDivMatrixMultTest.class.getSimpleName() + "/";
        
        private final static double eps = 1e-6;
+       private final static double div_eps = 0.1;
        
        private final static int rows = 1201;
        private final static int cols = 1103;
@@ -80,6 +83,8 @@ public class WeightedDivMatrixMultTest extends 
AutomatedTestBase
                addTestConfiguration(TEST_NAME7,new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME7,new String[]{"R"}));
                addTestConfiguration(TEST_NAME8,new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME8,new String[]{"R"}));
                addTestConfiguration(TEST_NAME9,new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME9,new String[]{"R"}));
+               addTestConfiguration(TEST_NAME10,new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME10,new String[]{"R"}));
+               addTestConfiguration(TEST_NAME11,new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME11,new String[]{"R"}));
        
                if (TEST_CACHE_ENABLED) {
                        setOutAndExpectedDeletionDisabled(true);
@@ -465,6 +470,88 @@ public class WeightedDivMatrixMultTest extends 
AutomatedTestBase
                runWeightedDivMMTest(TEST_NAME9, false, true, true, 
ExecType.SPARK);
        }
        
+       //c) testcases for wdivmm w/ DIVIDE LEFT/RIGHT with Epsilon
+       
+       @Test
+       public void testWeightedDivMMLeftEpsDenseCP() {
+               runWeightedDivMMTest(TEST_NAME10, false, true, false, 
ExecType.CP);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsSparseCP() {
+               runWeightedDivMMTest(TEST_NAME10, true, true, false, 
ExecType.CP);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsDenseCP() {
+               runWeightedDivMMTest(TEST_NAME11, false, true, false, 
ExecType.CP);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsSparseCP() {
+               runWeightedDivMMTest(TEST_NAME11, true, true, false, 
ExecType.CP);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsDenseMR() {
+               runWeightedDivMMTest(TEST_NAME10, false, true, false, 
ExecType.MR);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsSparseMR() {
+               runWeightedDivMMTest(TEST_NAME10, true, true, false, 
ExecType.MR);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsDenseMRRep() {
+               runWeightedDivMMTest(TEST_NAME10, false, true, true, 
ExecType.MR);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsDenseMR() {
+               runWeightedDivMMTest(TEST_NAME11, false, true, false, 
ExecType.MR);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsSparseMR() {
+               runWeightedDivMMTest(TEST_NAME11, true, true, false, 
ExecType.MR);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsDenseMRRep() {
+               runWeightedDivMMTest(TEST_NAME11, false, true, true, 
ExecType.MR);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsDenseSP() {
+               runWeightedDivMMTest(TEST_NAME10, false, true, false, 
ExecType.SPARK);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsSparseSP() {
+               runWeightedDivMMTest(TEST_NAME10, true, true, false, 
ExecType.SPARK);
+       }
+       
+       @Test
+       public void testWeightedDivMMLeftEpsDenseSPRep() {
+               runWeightedDivMMTest(TEST_NAME10, false, true, true, 
ExecType.SPARK);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsDenseSP() {
+               runWeightedDivMMTest(TEST_NAME11, false, true, false, 
ExecType.SPARK);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsSparseSP() {
+               runWeightedDivMMTest(TEST_NAME11, true, true, false, 
ExecType.SPARK);
+       }
+       
+       @Test
+       public void testWeightedDivMMRightEpsDenseSPRep() {
+               runWeightedDivMMTest(TEST_NAME11, false, true, true, 
ExecType.SPARK);
+       }
+
        /**
         * 
         * @param sparseM1
@@ -494,7 +581,8 @@ public class WeightedDivMatrixMultTest extends 
AutomatedTestBase
                {
                        boolean basic = testname.equals(TEST_NAME3);
                        boolean left = testname.equals(TEST_NAME1) || 
testname.equals(TEST_NAME4) 
-                                       || testname.equals(TEST_NAME6) || 
testname.equals(TEST_NAME8);
+                                       || testname.equals(TEST_NAME6) || 
testname.equals(TEST_NAME8)
+                                       || testname.equals(TEST_NAME10);
                        double sparsity = (sparse) ? spSparse : spDense;
                        String TEST_NAME = testname;
                        String TEST_CACHE_DIR = TEST_CACHE_ENABLED ? 
@@ -507,10 +595,10 @@ public class WeightedDivMatrixMultTest extends 
AutomatedTestBase
                        String HOME = SCRIPT_DIR + TEST_DIR;
                        fullDMLScriptName = HOME + TEST_NAME + ".dml";
                        programArgs = new String[]{"-stats", "-explain", 
"runtime", "-args",
-                               input("W"), input("U"), input("V"), output("R") 
};
+                               input("W"), input("U"), input("V"), 
output("R"), Double.toString(div_eps) };
                        
                        fullRScriptName = HOME + TEST_NAME + ".R";
-                       rCmd = "Rscript" + " " + fullRScriptName + " " + 
inputDir() + " " + expectedDir();
+                       rCmd = "Rscript" + " " + fullRScriptName + " " + 
inputDir() + " " + expectedDir() + " " + div_eps;
        
                        //generate actual dataset 
                        double[][] W = getRandomMatrix(rows, cols, 0, 1, 
sparsity, 7); 

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.R 
b/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.R
new file mode 100644
index 0000000..75ebff8
--- /dev/null
+++ b/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.R
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+
+args <- commandArgs(TRUE)
+options(digits=22)
+
+library("Matrix")
+
+W = as.matrix(readMM(paste(args[1], "W.mtx", sep="")))
+U = as.matrix(readMM(paste(args[1], "U.mtx", sep="")))
+V = as.matrix(readMM(paste(args[1], "V.mtx", sep="")))
+
+x = as.numeric(args[3])
+
+R = t(t(U) %*% (W/(U%*%t(V) + x)));
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "R", sep="")); 
+
+

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.dml 
b/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.dml
new file mode 100644
index 0000000..6bc843b
--- /dev/null
+++ b/src/test/scripts/functions/quaternary/WeightedDivMMLeftEps.dml
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+
+
+W = read($1);
+U = read($2);
+V = read($3);
+
+x = $5;
+
+R = t(t(U) %*% (W/(U%*%t(V) + x)));
+
+write(R, $4);

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.R 
b/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.R
new file mode 100644
index 0000000..8cf786e
--- /dev/null
+++ b/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.R
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+
+args <- commandArgs(TRUE)
+options(digits=22)
+
+library("Matrix")
+
+W = as.matrix(readMM(paste(args[1], "W.mtx", sep="")))
+U = as.matrix(readMM(paste(args[1], "U.mtx", sep="")))
+V = as.matrix(readMM(paste(args[1], "V.mtx", sep="")))
+
+x = as.numeric(args[3])
+
+R = (W/(U%*%t(V) + x)) %*% V;
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "R", sep="")); 
+
+

http://git-wip-us.apache.org/repos/asf/incubator-systemml/blob/fcfe893f/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.dml 
b/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.dml
new file mode 100644
index 0000000..de68463
--- /dev/null
+++ b/src/test/scripts/functions/quaternary/WeightedDivMMRightEps.dml
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+
+
+W = read($1);
+U = read($2);
+V = read($3);
+
+x = $5;
+
+R = (W/(U%*%t(V) + x)) %*% V;
+
+write(R, $4);


Reply via email to