[SYSTEMML-1732] Codegen full support for sparse-unsafe vector primitives

So far, the code generator row primitives always assumed sparse-safe
operations. This patch generalizes all existing scalar-vector and
vector-vector primitives for sparse-unsafe operations over sparse
inputs.


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

Branch: refs/heads/master
Commit: c17b8a8e331819eaa7805b715386c59603612d1c
Parents: 10c57fd
Author: Matthias Boehm <mboe...@gmail.com>
Authored: Sat Jun 24 01:27:41 2017 -0700
Committer: Matthias Boehm <mboe...@gmail.com>
Committed: Sat Jun 24 13:50:36 2017 -0700

----------------------------------------------------------------------
 .../sysml/hops/codegen/cplan/CNodeBinary.java   |  12 +-
 .../sysml/hops/codegen/cplan/CNodeRow.java      |   4 +-
 .../sysml/hops/codegen/cplan/CNodeTpl.java      |   3 +-
 .../sysml/hops/codegen/cplan/CNodeUnary.java    |   4 +-
 .../runtime/codegen/LibSpoofPrimitives.java     | 595 +++++++++++--------
 .../sysml/runtime/codegen/SpoofRowwise.java     |  31 +-
 .../functions/codegen/RowAggTmplTest.java       |  18 +-
 .../scripts/functions/codegen/rowAggPattern22.R |  32 +
 .../functions/codegen/rowAggPattern22.dml       |  28 +
 9 files changed, 435 insertions(+), 292 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
index 3771de5..8d67f26 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeBinary.java
@@ -69,7 +69,7 @@ public class CNodeBinary extends CNode
                public String getTemplate(boolean sparse, boolean scalarVector) 
{
                        switch (this) {
                                case DOT_PRODUCT:   
-                                       return sparse ? "    double %TMP% = 
LibSpoofPrimitives.dotProduct(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, %LEN%);\n" 
:
+                                       return sparse ? "    double %TMP% = 
LibSpoofPrimitives.dotProduct(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, alen);\n" :
                                                                        "    
double %TMP% = LibSpoofPrimitives.dotProduct(%IN1%, %IN2%, %POS1%, %POS2%, 
%LEN%);\n";
                                
                                //vector-scalar-add operations
@@ -88,10 +88,10 @@ public class CNodeBinary extends CNode
                                case VECT_GREATEREQUAL_ADD: {
                                        String vectName = 
getVectorPrimitiveName();
                                        if( scalarVector )
-                                               return sparse ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2v%, %OUT%, %IN2i%, %POS2%, 
%POSOUT%, %LEN%);\n" : 
+                                               return sparse ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2v%, %OUT%, %IN2i%, %POS2%, 
%POSOUT%, alen, len);\n" : 
                                                                                
"    LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2%, %OUT%, %POS2%, 
%POSOUT%, %LEN%);\n";
                                        else    
-                                               return sparse ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, 
%POSOUT%, %LEN%);\n" : 
+                                               return sparse ? "    
LibSpoofPrimitives.vect"+vectName+"Add(%IN1v%, %IN2%, %OUT%, %IN1i%, %POS1%, 
%POSOUT%, alen, len);\n" : 
                                                                                
"    LibSpoofPrimitives.vect"+vectName+"Add(%IN1%, %IN2%, %OUT%, %POS1%, 
%POSOUT%, %LEN%);\n";
                                }
                                
@@ -111,10 +111,10 @@ public class CNodeBinary extends CNode
                                case VECT_GREATEREQUAL_SCALAR: {
                                        String vectName = 
getVectorPrimitiveName();
                                        if( scalarVector )
-                                               return sparse ? "    double[] 
%TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2v%, %IN2i%, %POS2%, 
%LEN%);\n" : 
+                                               return sparse ? "    double[] 
%TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2v%, %IN2i%, %POS2%, 
alen, len);\n" : 
                                                                                
"    double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, 
%POS2%, %LEN%);\n";
                                        else    
-                                               return sparse ? "    double[] 
%TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, 
%LEN%);\n" : 
+                                               return sparse ? "    double[] 
%TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, 
alen, len);\n" : 
                                                                                
"    double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, 
%POS1%, %LEN%);\n";
                                }
                                
@@ -133,7 +133,7 @@ public class CNodeBinary extends CNode
                                case VECT_GREATEREQUAL: {
                                        String vectName = 
getVectorPrimitiveName();
                                        return sparse ? 
-                                               "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, 
%LEN%);\n" : 
+                                               "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN2%, %IN1i%, %POS1%, %POS2%, 
alen, len);\n" : 
                                                "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %IN2%, %POS1%, %POS2%, 
%LEN%);\n";
                                }
                                

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
index caf379b..7cba5f7 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeRow.java
@@ -40,10 +40,10 @@ public class CNodeRow extends CNodeTpl
                        + "  public %TMP%() {\n"
                        + "    super(RowType.%TYPE%, %CBIND0%, %VECT_MEM%);\n"
                        + "  }\n"
-                       + "  protected void genexecRowDense( double[] a, int 
ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex ) { \n"
+                       + "  protected void genexec(double[] a, int ai, 
double[][] b, double[] scalars, double[] c, int len, int rowIndex) { \n"
                        + "%BODY_dense%"
                        + "  }\n"
-                       + "  protected void genexecRowSparse( double[] avals, 
int[] aix, int ai, double[][] b, double[] scalars, double[] c, int len, int 
rowIndex ) { \n"
+                       + "  protected void genexec(double[] avals, int[] aix, 
int ai, double[][] b, double[] scalars, double[] c, int alen, int len, int 
rowIndex) { \n"
                        + "%BODY_sparse%"
                        + "  }\n"                       
                        + "}\n";

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
index 8d61588..db7ea31 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeTpl.java
@@ -137,7 +137,8 @@ public abstract class CNodeTpl extends CNode implements 
Cloneable
                        if( newNames.containsKey(dnode.getHopID()) )
                                dnode.setName(newNames.get(dnode.getHopID()));
                }
-                       
+               
+               node.resetHash();
                node.setVisited();
        }
        

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java 
b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
index c560878..500b309 100644
--- a/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
+++ b/src/main/java/org/apache/sysml/hops/codegen/cplan/CNodeUnary.java
@@ -49,7 +49,7 @@ public class CNodeUnary extends CNode
                                case ROW_MINS:
                                case ROW_MAXS: {
                                        String vectName = 
StringUtils.capitalize(this.toString().substring(4,7).toLowerCase());
-                                       return sparse ? "    double %TMP% = 
LibSpoofPrimitives.vect"+vectName+"(%IN1v%, %IN1i%, %POS1%, %LEN%);\n": 
+                                       return sparse ? "    double %TMP% = 
LibSpoofPrimitives.vect"+vectName+"(%IN1v%, %IN1i%, %POS1%, alen, len);\n": 
                                                                        "    
double %TMP% = LibSpoofPrimitives.vect"+vectName+"(%IN1%, %POS1%, %LEN%);\n"; 
                                }
                        
@@ -64,7 +64,7 @@ public class CNodeUnary extends CNode
                                case VECT_FLOOR:
                                case VECT_SIGN: {
                                        String vectName = 
getVectorPrimitiveName();
-                                       return sparse ? "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN1i%, %POS1%, %LEN%);\n" : 
+                                       return sparse ? "    double[] %TMP% = 
LibSpoofPrimitives.vect"+vectName+"Write(%IN1v%, %IN1i%, %POS1%, alen, len);\n" 
: 
                                                                        "    
double[] %TMP% = LibSpoofPrimitives.vect"+vectName+"Write(%IN1%, %POS1%, 
%LEN%);\n";
                                }
                                        

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java 
b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
index d9f20ef..8fe35ff 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/LibSpoofPrimitives.java
@@ -58,23 +58,23 @@ public class LibSpoofPrimitives
        }
        
        public static void vectMultAdd(double[] a, double bval, double[] c, int 
bi, int ci, int len) {
-               if( a == null ) return;
+               if( a == null || bval == 0 ) return;
                LibMatrixMult.vectMultiplyAdd(bval, a, c, bi, ci, len);
        }
        
        public static void vectMultAdd(double bval, double[] a, double[] c, int 
bi, int ci, int len) {
-               if( a == null ) return;
+               if( a == null || bval == 0 ) return;
                LibMatrixMult.vectMultiplyAdd(bval, a, c, bi, ci, len);
        }
        
-       public static void vectMultAdd(double[] a, double bval, double[] c, 
int[] bix, int bi, int ci, int len) {
-               if( a == null ) return;
-               LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, ci, len);
+       public static void vectMultAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( a == null || bval == 0 ) return;
+               LibMatrixMult.vectMultiplyAdd(bval, a, c, aix, ai, ci, alen);
        }
        
-       public static void vectMultAdd(double bval, double[] a, double[] c, 
int[] bix, int bi, int ci, int len) {
-               if( a == null ) return;
-               LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, ci, len);
+       public static void vectMultAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( a == null || bval == 0 ) return;
+               LibMatrixMult.vectMultiplyAdd(bval, a, c, aix, ai, ci, alen);
        }
        
        public static void vectMultAdd(double[] a, double[] b, double[] c, int 
bi, int ci, int len) {
@@ -84,8 +84,9 @@ public class LibSpoofPrimitives
        }
        
        public static double[] vectMultWrite(double[] a, double bval, int bi, 
int len) {
+               if( a == null || bval == 0 ) 
+                       return allocVector(len, true);
                double[] c = allocVector(len, false);
-               if( a == null ) return c;
                LibMatrixMult.vectMultiplyWrite(bval, a, c, bi, 0, len);
                return c;
        }
@@ -95,27 +96,28 @@ public class LibSpoofPrimitives
        }
        
        public static double[] vectMultWrite(double[] a, double[] b, int ai, 
int bi, int len) {
+               if( a == null || b == null )
+                       return allocVector(len, true);
                double[] c = allocVector(len, false);
-               if( a == null || b == null ) return c;
                LibMatrixMult.vectMultiplyWrite(a, b, c, ai, bi, 0, len);
                return c;
        }
        
-       public static double[] vectMultWrite(double[] a, double bval, int[] 
bix, int bi, int len) {
+       public static double[] vectMultWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
                double[] c = allocVector(len, true);
                if( a == null ) return c;
-               LibMatrixMult.vectMultiplyAdd(bval, a, c, bix, bi, 0, len);
+               LibMatrixMult.vectMultiplyAdd(bval, a, c, aix, ai, 0, alen);
                return c;
        }
        
-       public static double[] vectMultWrite(double bval, double[] a, int[] 
bix, int bi, int len) {
-               return vectMultWrite(a, bval, bix, bi, len);
+       public static double[] vectMultWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               return vectMultWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectMultWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int len) {
-               double[] c = allocVector(len, false);
+       public static double[] vectMultWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int alen, int len) {
+               double[] c = allocVector(len, true);
                if( a == null || b == null ) return c;
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = a[j] * b[bi+aix[j]];
                return c;
        }
@@ -138,7 +140,7 @@ public class LibSpoofPrimitives
        public static double vectSum(double[] a, int ai, int len) { 
                double val = 0;
                final int bn = len%8;
-                               
+               
                //compute rest
                for( int i = ai; i < ai+bn; i++ )
                        val += a[ i ];
@@ -154,18 +156,9 @@ public class LibSpoofPrimitives
                return val; 
        } 
        
-       /**
-        * Computes c = sum(A), where A is a sparse vector. 
-        * 
-        * @param avals sparse input vector A values A
-        * @param aix sparse input vector A column indexes
-        * @param ai start position in A
-        * @param len number of processed elements
-        * @return sum value
-        */
-       public static double vectSum(double[] avals, int[] aix, int ai, int 
len) {
+       public static double vectSum(double[] avals, int[] aix, int ai, int 
alen, int len) {
                //forward to dense as column indexes not required here
-               return vectSum(avals, ai, len);
+               return vectSum(avals, ai, alen);
        }
        
        public static double vectMin(double[] a, int ai, int len) { 
@@ -175,11 +168,9 @@ public class LibSpoofPrimitives
                return val; 
        }
        
-       public static double vectMin(double[] avals, int[] aix, int ai, int 
len) {
-               double val = Double.MAX_VALUE;
-               for( int i = ai; i < ai+len; i++ )
-                       val = Math.min(avals[aix[i]], val);
-               return val;
+       public static double vectMin(double[] avals, int[] aix, int ai, int 
alen, int len) {
+               double val = vectMin(avals, ai, alen);
+               return (alen<len) ? Math.min(val, 0) : val;
        }
        
        public static double vectMax(double[] a, int ai, int len) { 
@@ -189,11 +180,9 @@ public class LibSpoofPrimitives
                return val; 
        } 
        
-       public static double vectMax(double[] avals, int[] aix, int ai, int 
len) {
-               double val = -Double.MAX_VALUE;
-               for( int i = ai; i < ai+len; i++ )
-                       val = Math.max(avals[aix[i]], val);
-               return val;
+       public static double vectMax(double[] avals, int[] aix, int ai, int 
alen, int len) {
+               double val = vectMax(avals, ai, alen);
+               return (alen<len) ? Math.max(val, 0) : val;
        }
        
        //custom vector div
@@ -208,54 +197,54 @@ public class LibSpoofPrimitives
                        c[ci] +=  bval / a[j];
        }
 
-       public static void vectDivAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectDivAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += a[j] / bval;
        }
        
-       public static void vectDivAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectDivAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += bval / a[j];
        }
        
        public static double[] vectDivWrite(double[] a, double bval, int ai, 
int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = a[ai] / bval;
+               for( int j = 0; j < len; j++)
+                       c[j] = a[ai+j] / bval;
                return c;
        }
        
        public static double[] vectDivWrite(double bval, double[] a, int ai, 
int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = bval / a[ai];
+               for( int j = 0; j < len; j++)
+                       c[j] = bval / a[ai + j];
                return c;
        }
        
-       public static double[] vectDivWrite(double[] a, double[] b, int ai, int 
bi, int len) {
+       public static double[] vectDivWrite(double[] a, double[] b, int ai, int 
bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++, bi++)
-                       c[j] = a[ai] / b[bi];
+               for( int j = 0; j < len; j++)
+                       c[j] = a[ai + j] / b[bi + j];
                return c;
        }
 
-       public static double[] vectDivWrite(double[] a, double bval, int[] aix, 
int ai, int len) {
+       public static double[] vectDivWrite(double[] a, double bval, int[] aix, 
int ai, int alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = a[j] / bval;
                return c;
        }
        
-       public static double[] vectDivWrite(double bval, double[] a, int[] aix, 
int ai, int len) {
+       public static double[] vectDivWrite(double bval, double[] a, int[] aix, 
int ai, int alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = bval / a[j];
                return c;
        }
        
-       public static double[] vectDivWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int len) {
+       public static double[] vectDivWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = a[j] / b[bi+aix[j]];
                return c;
        }
@@ -272,55 +261,63 @@ public class LibSpoofPrimitives
                        c[ci] +=  bval - a[j];
        }
 
-       public static void vectMinusAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += a[j] - bval;
+       public static void vectMinusAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval != 0 ) //subtract bval if necessary
+                       for( int j = ci; j < ci+len; j++ )
+                               c[j] -= bval;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += a[j];
        }
        
-       public static void vectMinusAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += bval - a[j];
+       public static void vectMinusAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval != 0 ) //add bval is necessary
+                       for( int j = ci; j < ci+len; j++ )
+                               c[j] += bval;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] -= a[j];
        }
        
        public static double[] vectMinusWrite(double[] a, double bval, int ai, 
int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = a[ai] - bval;
+               for( int j = 0; j < len; j++)
+                       c[j] = a[ai + j] - bval;
                return c;
        }
        
        public static double[] vectMinusWrite(double bval, double[] a, int ai, 
int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = bval - a[ai];
+               for( int j = 0; j < len; j++)
+                       c[j] = bval - a[ai + j];
                return c;
        }
        
        public static double[] vectMinusWrite(double[] a, double[] b, int ai, 
int bi, int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++, bi++)
-                       c[j] = a[ai] - b[bi];
+               for( int j = 0; j < len; j++)
+                       c[j] = a[ai + j] - b[bi + j];
                return c;
        }
        
-       public static double[] vectMinusWrite(double[] a, double bval, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = a[j] - bval;
+       public static double[] vectMinusWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
+               double[] c = allocVector(len, true, -bval);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] += a[j];
                return c;
        }
        
-       public static double[] vectMinusWrite(double bval, double[] a, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = bval - a[j];
+       public static double[] vectMinusWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               double[] c = allocVector(len, true, bval);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] -= a[j];
                return c;
        }
        
-       public static double[] vectMinusWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int len) {
+       public static double[] vectMinusWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = a[j] - b[bi+aix[j]];
+               for( int j = 0; j < len; j++ )
+                       c[j] = -b[bi+j];
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] += a[j];
                return c;
        }
        
@@ -334,19 +331,21 @@ public class LibSpoofPrimitives
                LibMatrixMult.vectAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectPlusAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += a[j] + bval;
+       public static void vectPlusAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               for( int j = ci; j < ci+len; j++ )
+                       c[j] += bval;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += a[j];
        }
        
-       public static void vectPlusAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectPlusAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectPlusAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectPlusAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectPlusWrite(double[] a, double bval, int ai, 
int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = a[ai] + bval;
+               for( int j = 0; j < len; j++)
+                       c[j] = a[ai + j] + bval;
                return c;
        }
        
@@ -356,26 +355,27 @@ public class LibSpoofPrimitives
        
        public static double[] vectPlusWrite(double[] a, double[] b, int ai, 
int bi, int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = a[ai] + b[bi];
+               for( int j = 0; j < len; j++)
+                       c[j] = a[ai+j] + b[bi+j];
                return c;
        }
 
-       public static double[] vectPlusWrite(double[] a, double bval, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = a[j] + bval;
+       public static double[] vectPlusWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
+               double[] c = allocVector(len, true, bval);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] += a[j];
                return c;
        }
        
-       public static double[] vectPlusWrite(double bval, double[] a, int[] 
aix, int ai, int len) {
-               return vectPlusWrite(a, bval, aix, ai, len);
+       public static double[] vectPlusWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               return vectPlusWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectPlusWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int len) {
+       public static double[] vectPlusWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = a[j] + b[bi+aix[j]];
+               System.arraycopy(b, bi, c, 0, len);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] += a[j];
                return c;
        }
        
@@ -391,14 +391,19 @@ public class LibSpoofPrimitives
                        c[ci] += Math.pow(bval, a[j]);
        }
 
-       public static void vectPowAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += Math.pow(a[j], bval);
+       public static void vectPowAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval == 0 ) //handle 0^0=1
+                       for( int j=0; j<len; j++ )
+                               c[ci + j] += 1;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += Math.pow(a[j], bval) - 1;
        }
        
-       public static void vectPowAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += Math.pow(bval, a[j]);
+       public static void vectPowAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               for( int j=0; j<len; j++ )
+                       c[ci + j] += 1;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += Math.pow(bval, a[j]) - 1;
        }
        
        public static double[] vectPowWrite(double[] a, double bval, int ai, 
int len) {
@@ -422,16 +427,17 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectPowWrite(double[] a, double bval, int[] aix, 
int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = Math.pow(a[j], bval);
+       public static double[] vectPowWrite(double[] a, double bval, int[] aix, 
int ai, int alen, int len) {
+               double init = (bval == 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = Math.pow(a[j], bval) - init;
                return c;
        }
        
-       public static double[] vectPowWrite(double bval, double[] a, int[] aix, 
int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+       public static double[] vectPowWrite(double bval, double[] a, int[] aix, 
int ai, int alen, int len) {
+               double[] c = allocVector(len, true, 1);
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = Math.pow(bval, a[j]);
                return c;
        }
@@ -447,13 +453,16 @@ public class LibSpoofPrimitives
                vectMinAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectMinAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += Math.min(a[j], bval);
+       public static void vectMinAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval < 0 )
+                       for( int j=0; j<len; j++ )
+                               c[ci +j] += bval;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += (bval >= 0) ? Math.min(a[j], bval) : 
0;
        }
        
-       public static void vectMinAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectMinAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectMinAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectMinAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectMinWrite(double[] a, double bval, int ai, 
int len) {
@@ -474,21 +483,22 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectMinWrite(double[] a, double bval, int[] aix, 
int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+       public static double[] vectMinWrite(double[] a, double bval, int[] aix, 
int ai, int alen, int len) {
+               double[] c = allocVector(len, true, bval);
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = Math.min(a[j], bval);
                return c;
        }
        
-       public static double[] vectMinWrite(double bval, double[] a, int[] aix, 
int ai, int len) {
-               return vectMinWrite(a, bval, aix, ai, len);
+       public static double[] vectMinWrite(double bval, double[] a, int[] aix, 
int ai, int alen, int len) {
+               return vectMinWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectMinWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int len) {
+       public static double[] vectMinWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = Math.min(a[j], b[bi+aix[j]]);
+               System.arraycopy(b, bi, c, 0, len);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = Math.min(a[j], c[aix[j]]);
                return c;
        }
        
@@ -503,13 +513,16 @@ public class LibSpoofPrimitives
                vectMaxAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectMaxAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += Math.max(a[j], bval);
+       public static void vectMaxAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval > 0 )
+                       for( int j=0; j<len; j++ )
+                               c[ci + j] += bval;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += (bval <= 0) ? Math.max(a[j], bval) : 
0;
        }
        
-       public static void vectMaxAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectMaxAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectMaxAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectMaxAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectMaxWrite(double[] a, double bval, int ai, 
int len) {
@@ -530,47 +543,50 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectMaxWrite(double[] a, double bval, int[] aix, 
int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+       public static double[] vectMaxWrite(double[] a, double bval, int[] aix, 
int ai, int alen, int len) {
+               double[] c = allocVector(len, true, bval);
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = Math.max(a[j], bval);
                return c;
        }
        
-       public static double[] vectMaxWrite(double bval, double[] a, int[] aix, 
int ai, int len) {
-               return vectMaxWrite(a, bval, aix, ai, len);
+       public static double[] vectMaxWrite(double bval, double[] a, int[] aix, 
int ai, int alen, int len) {
+               return vectMaxWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectMaxWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int len) {
+       public static double[] vectMaxWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = Math.max(a[j], b[bi+aix[j]]);
+               System.arraycopy(b, bi, c, 0, len);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = Math.max(a[j], c[aix[j]]);
                return c;
        }
 
        //custom exp
        
        public static void vectExpAdd(double[] a, double[] c, int ai, int ci, 
int len) {
-               for( int j = ai; j < ai+len; j++, ci++)
-                       c[ci] +=  FastMath.exp(a[j]);
+               for( int j = 0; j < len; j++)
+                       c[ci+j] +=  FastMath.exp(a[ai+j]);
        }
 
-       public static void vectExpAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += FastMath.exp(a[j]);
+       public static void vectExpAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j=ci; j<ci+len; j++ ) //exp(0)=1
+                       c[j] += 1;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += FastMath.exp(a[j]) - 1;
        }
        
        public static double[] vectExpWrite(double[] a, int ai, int len) {
                double[] c = allocVector(len, false);
-               for( int j = 0; j < len; j++, ai++)
-                       c[j] = FastMath.exp(a[ai]);
+               for( int j = 0; j < len; j++)
+                       c[j] = FastMath.exp(a[ai+j]);
                return c;
        }
 
-       public static double[] vectExpWrite(double[] a, int[] aix, int ai, int 
len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = FastMath.exp(a[j]);
+       public static double[] vectExpWrite(double[] a, int[] aix, int ai, int 
alen, int len) {
+               double[] c = allocVector(len, true, 1); //exp(0)=1
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = FastMath.exp(a[j]) - 1;
                return c;
        }
 
@@ -578,11 +594,11 @@ public class LibSpoofPrimitives
        
        public static void vectLogAdd(double[] a, double[] c, int ai, int ci, 
int len) {
                for( int j = ai; j < ai+len; j++, ci++)
-                       c[ci] +=  FastMath.log(a[j]);
+                       c[ci] += FastMath.log(a[j]);
        }
 
-       public static void vectLogAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectLogAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += FastMath.log(a[j]);
        }
        
@@ -593,9 +609,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectLogWrite(double[] a, int[] aix, int ai, int 
len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+       public static double[] vectLogWrite(double[] a, int[] aix, int ai, int 
alen, int len) {
+               double[] c = allocVector(len, true, Double.NEGATIVE_INFINITY);
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = FastMath.log(a[j]);
                return c;
        }
@@ -607,8 +623,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  Math.abs(a[j]);
        }
 
-       public static void vectAbsAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectAbsAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += Math.abs(a[j]);
        }
        
@@ -619,9 +635,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectAbsWrite(double[] a, int[] aix, int ai, int 
len) {
+       public static double[] vectAbsWrite(double[] a, int[] aix, int ai, int 
alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = Math.abs(a[j]);
                return c;
        }
@@ -633,8 +649,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  Math.round(a[j]);
        }
 
-       public static void vectRoundAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectRoundAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += Math.round(a[j]);
        }
        
@@ -645,9 +661,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectRoundWrite(double[] a, int[] aix, int ai, 
int len) {
+       public static double[] vectRoundWrite(double[] a, int[] aix, int ai, 
int alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = Math.round(a[j]);
                return c;
        }
@@ -659,8 +675,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  FastMath.ceil(a[j]);
        }
 
-       public static void vectCeilAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectCeilAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += FastMath.ceil(a[j]);
        }
        
@@ -671,9 +687,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectCeilWrite(double[] a, int[] aix, int ai, int 
len) {
+       public static double[] vectCeilWrite(double[] a, int[] aix, int ai, int 
alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = FastMath.ceil(a[j]);
                return c;
        }
@@ -685,8 +701,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  FastMath.floor(a[j]);
        }
 
-       public static void vectFloorAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectFloorAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += FastMath.floor(a[j]);
        }
        
@@ -697,9 +713,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectFloorWrite(double[] a, int[] aix, int ai, 
int len) {
+       public static double[] vectFloorWrite(double[] a, int[] aix, int ai, 
int alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = FastMath.floor(a[j]);
                return c;
        }
@@ -711,8 +727,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  FastMath.signum(a[j]);
        }
 
-       public static void vectSignAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectSignAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += FastMath.signum(a[j]);
        }
        
@@ -723,9 +739,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectSignWrite(double[] a, int[] aix, int ai, int 
len) {
+       public static double[] vectSignWrite(double[] a, int[] aix, int ai, int 
alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = FastMath.signum(a[j]);
                return c;
        }
@@ -737,8 +753,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  a[j] * a[j];
        }
 
-       public static void vectPow2Add(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectPow2Add(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += a[j] * a[j];
        }
        
@@ -749,9 +765,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectPow2Write(double[] a, int[] aix, int ai, int 
len) {
+       public static double[] vectPow2Write(double[] a, int[] aix, int ai, int 
alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = a[j] * a[j];
                return c;
        }
@@ -763,8 +779,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  a[j] + a[j];
        }
 
-       public static void vectMult2Add(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectMult2Add(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += a[j] + a[j];
        }
        
@@ -775,9 +791,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectMult2Write(double[] a, int[] aix, int ai, 
int len) {
+       public static double[] vectMult2Write(double[] a, int[] aix, int ai, 
int alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = a[j] + a[j];
                return c;
        }
@@ -789,8 +805,8 @@ public class LibSpoofPrimitives
                        c[ci] +=  Math.sqrt(a[j]);
        }
 
-       public static void vectSqrtAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
+       public static void vectSqrtAdd(double[] a, double[] c, int[] aix, int 
ai, int ci, int alen, int len) {
+               for( int j = ai; j < ai+alen; j++ )
                        c[ci + aix[j]] += Math.sqrt(a[j]);
        }
        
@@ -801,9 +817,9 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectSqrtWrite(double[] a, int[] aix, int ai, int 
len) {
+       public static double[] vectSqrtWrite(double[] a, int[] aix, int ai, int 
alen, int len) {
                double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = Math.sqrt(a[j]);
                return c;
        }
@@ -819,13 +835,17 @@ public class LibSpoofPrimitives
                vectEqualAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectEqualAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += (a[j] == bval) ? 1 : 0;
+       public static void vectEqualAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval == 0 )
+                       for( int j=0; j<len; j++ )
+                               c[j] += 1;
+               else            
+                       for( int j = ai; j < ai+alen; j++ )
+                               c[ci + aix[j]] += (a[j] == bval) ? 1 : 0;
        }
        
-       public static void vectEqualAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectEqualAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectEqualAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectEqualAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectEqualWrite(double[] a, double bval, int ai, 
int len) {
@@ -846,20 +866,24 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectEqualWrite(double[] a, double bval, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = (a[j] == bval) ? 1 : 0;
+       public static double[] vectEqualWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
+               double init = (bval == 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
+               if( bval != 0 )
+                       for( int j = ai; j < ai+alen; j++ )
+                               c[aix[j]] = (a[j] == bval) ? 1 : 0;
                return c;
        }
        
-       public static double[] vectEqualWrite(double bval, double[] a, int[] 
aix, int ai, int len) {
-               return vectEqualWrite(a, bval, aix, ai, len);
+       public static double[] vectEqualWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               return vectEqualWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectEqualWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int len) {
+       public static double[] vectEqualWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j=0; j<len; j++ )
+                       c[j] = (b[bi+j]==0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = (a[j] == b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
@@ -875,13 +899,17 @@ public class LibSpoofPrimitives
                vectNotequalAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectNotequalAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += (a[j] != bval) ? 1 : 0;
+       public static void vectNotequalAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen,  int len) {
+               if( bval != 0 )
+                       for( int j=0; j<len; j++ )
+                               c[j] += 1;
+               double init = (bval != 0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += ((a[j] != bval) ? 1 : 0) - init;
        }
        
-       public static void vectNotequalAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectNotequalAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectNotequalAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectNotequalAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectNotequalWrite(double[] a, double bval, int 
ai, int len) {
@@ -902,20 +930,23 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectNotequalWrite(double[] a, double bval, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = (a[j] != bval) ? 1 : 0;
+       public static double[] vectNotequalWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
+               double init = (bval != 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = ((a[j] != bval) ? 1 : 0) - init;
                return c;
        }
        
-       public static double[] vectNotequalWrite(double bval, double[] a, int[] 
aix, int ai, int len) {
-               return vectNotequalWrite(a, bval, aix, ai, len);
+       public static double[] vectNotequalWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               return vectNotequalWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectNotequalWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int len) {
+       public static double[] vectNotequalWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j=0; j<len; j++ )
+                       c[j] = (b[bi+j]!=0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = (a[j] != b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
@@ -931,13 +962,17 @@ public class LibSpoofPrimitives
                vectGreaterequalAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectLessAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += (a[j] < bval) ? 1 : 0;
+       public static void vectLessAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval > 0 )
+                       for( int j=0; j<len; j++ )
+                               c[j] += 1;
+               double init = (bval > 0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += ((a[j] < bval) ? 1 : 0) - init;
        }
        
-       public static void vectLessAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectGreaterequalAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectLessAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectGreaterequalAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectLessWrite(double[] a, double bval, int ai, 
int len) {
@@ -958,20 +993,23 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectLessWrite(double[] a, double bval, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = (a[j] < bval) ? 1 : 0;
+       public static double[] vectLessWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
+               double init = (bval > 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = (a[j] < bval) ? 1 : 0 - init;
                return c;
        }
        
-       public static double[] vectLessWrite(double bval, double[] a, int[] 
aix, int ai, int len) {
-               return vectGreaterequalWrite(a, bval, aix, ai, len);
+       public static double[] vectLessWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               return vectGreaterequalWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectLessWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int len) {
+       public static double[] vectLessWrite(double[] a, double[] b, int[] aix, 
int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j=0; j<len; j++ )
+                       c[j] = ( 0 < b[bi+j] ) ? 1 : 0; 
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = (a[j] < b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
@@ -987,13 +1025,17 @@ public class LibSpoofPrimitives
                vectGreaterAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectLessequalAdd(double[] a, double bval, double[] 
c, int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += (a[j] <= bval) ? 1 : 0;
+       public static void vectLessequalAdd(double[] a, double bval, double[] 
c, int[] aix, int ai, int ci, int alen, int len) {
+               if( bval >= 0 )
+                       for( int j=0; j<len; j++ )
+                               c[j] += 1;
+               double init = (bval >= 0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += ((a[j] <= bval) ? 1 : 0) - init;
        }
        
-       public static void vectLessequalAdd(double bval, double[] a, double[] 
c, int[] aix, int ai, int ci, int len) {
-               vectGreaterAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectLessequalAdd(double bval, double[] a, double[] 
c, int[] aix, int ai, int ci, int alen, int len) {
+               vectGreaterAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectLessequalWrite(double[] a, double bval, int 
ai, int len) {
@@ -1014,20 +1056,23 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectLessequalWrite(double[] a, double bval, 
int[] aix, int ai, int len) {
-               double[] c = allocVector(len, true);
+       public static double[] vectLessequalWrite(double[] a, double bval, 
int[] aix, int ai, int alen, int len) {
+               double init = (bval >= 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
                for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = (a[j] <= bval) ? 1 : 0;
+                       c[aix[j]] = ((a[j] <= bval) ? 1 : 0) - init;
                return c;
        }
        
-       public static double[] vectLessequalWrite(double bval, double[] a, 
int[] aix, int ai, int len) {
-               return vectGreaterWrite(a, bval, aix, ai, len);
+       public static double[] vectLessequalWrite(double bval, double[] a, 
int[] aix, int ai, int alen, int len) {
+               return vectGreaterWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectLessequalWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int len) {
+       public static double[] vectLessequalWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j=0; j<len; j++ )
+                       c[j] = ( 0 <= b[bi+j] ) ? 1 : 0; 
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = (a[j] <= b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
@@ -1043,13 +1088,17 @@ public class LibSpoofPrimitives
                vectLessequalAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectGreaterAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += (a[j] > bval) ? 1 : 0;
+       public static void vectGreaterAdd(double[] a, double bval, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               if( bval < 0 )
+                       for( int j=0; j<len; j++ )
+                               c[j] += 1;
+               double init = (bval < 0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += ((a[j] > bval) ? 1 : 0) - init;
        }
        
-       public static void vectGreaterAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int len) {
-               vectLessequalAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectGreaterAdd(double bval, double[] a, double[] c, 
int[] aix, int ai, int ci, int alen, int len) {
+               vectLessequalAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectGreaterWrite(double[] a, double bval, int 
ai, int len) {
@@ -1070,20 +1119,23 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectGreaterWrite(double[] a, double bval, int[] 
aix, int ai, int len) {
-               double[] c = allocVector(len, true);
-               for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = (a[j] > bval) ? 1 : 0;
+       public static double[] vectGreaterWrite(double[] a, double bval, int[] 
aix, int ai, int alen, int len) {
+               double init = (bval < 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
+               for( int j = ai; j < ai+alen; j++ )
+                       c[aix[j]] = ((a[j] > bval) ? 1 : 0) - init;
                return c;
        }
        
-       public static double[] vectGreaterWrite(double bval, double[] a, int[] 
aix, int ai, int len) {
-               return vectLessequalWrite(a, bval, aix, ai, len);
+       public static double[] vectGreaterWrite(double bval, double[] a, int[] 
aix, int ai, int alen, int len) {
+               return vectLessequalWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectGreaterWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int len) {
+       public static double[] vectGreaterWrite(double[] a, double[] b, int[] 
aix, int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j=0; j<len; j++ )
+                       c[j] = ( 0 > b[bi+j] ) ? 1 : 0; 
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = (a[j] > b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
@@ -1099,13 +1151,17 @@ public class LibSpoofPrimitives
                vectLessAdd(a, bval, c, ai, ci, len);
        }
 
-       public static void vectGreaterequalAdd(double[] a, double bval, 
double[] c, int[] aix, int ai, int ci, int len) {
-               for( int j = ai; j < ai+len; j++ )
-                       c[ci + aix[j]] += (a[j] >= bval) ? 1 : 0;
+       public static void vectGreaterequalAdd(double[] a, double bval, 
double[] c, int[] aix, int ai, int ci, int alen, int len) {
+               if( bval <= 0 )
+                       for( int j=0; j<len; j++ )
+                               c[j] += 1;
+               double init = (bval <= 0) ? 1 : 0;
+               for( int j = ai; j < ai+alen; j++ )
+                       c[ci + aix[j]] += ((a[j] >= bval) ? 1 : 0) - init;
        }
        
-       public static void vectGreaterequalAdd(double bval, double[] a, 
double[] c, int[] aix, int ai, int ci, int len) {
-               vectLessAdd(a, bval, c, aix, ai, ci, len);
+       public static void vectGreaterequalAdd(double bval, double[] a, 
double[] c, int[] aix, int ai, int ci, int alen, int len) {
+               vectLessAdd(a, bval, c, aix, ai, ci, alen, len);
        }
        
        public static double[] vectGreaterequalWrite(double[] a, double bval, 
int ai, int len) {
@@ -1126,20 +1182,23 @@ public class LibSpoofPrimitives
                return c;
        }
 
-       public static double[] vectGreaterequalWrite(double[] a, double bval, 
int[] aix, int ai, int len) {
-               double[] c = allocVector(len, true);
+       public static double[] vectGreaterequalWrite(double[] a, double bval, 
int[] aix, int ai, int alen, int len) {
+               double init = (bval < 0) ? 1 : 0;
+               double[] c = allocVector(len, true, init);
                for( int j = ai; j < ai+len; j++ )
-                       c[aix[j]] = (a[j] >= bval) ? 1 : 0;
+                       c[aix[j]] = ((a[j] >= bval) ? 1 : 0) - init;
                return c;
        }
        
-       public static double[] vectGreaterequalWrite(double bval, double[] a, 
int[] aix, int ai, int len) {
-               return vectLessWrite(a, bval, aix, ai, len);
+       public static double[] vectGreaterequalWrite(double bval, double[] a, 
int[] aix, int ai, int alen, int len) {
+               return vectLessWrite(a, bval, aix, ai, alen, len);
        }
        
-       public static double[] vectGreaterequalWrite(double[] a, double[] b, 
int[] aix, int ai, int bi, int len) {
+       public static double[] vectGreaterequalWrite(double[] a, double[] b, 
int[] aix, int ai, int bi, int alen, int len) {
                double[] c = allocVector(len, false);
-               for( int j = ai; j < ai+len; j++ )
+               for( int j=0; j<len; j++ )
+                       c[j] = ( 0 >= b[bi+j] ) ? 1 : 0; 
+               for( int j = ai; j < ai+alen; j++ )
                        c[aix[j]] = (a[j] >= b[bi+aix[j]]) ? 1 : 0;
                return c;
        }
@@ -1170,11 +1229,19 @@ public class LibSpoofPrimitives
        }
        
        private static double[] allocVector(int len, boolean reset) {
+               return allocVector(len, reset, 0);
+       }
+       
+       private static double[] allocVector(int len, boolean reset, double 
resetVal) {
                LinkedList<double[]> list = memPool.get();
                
                //sanity check for missing setup
-               if( list.isEmpty() )
-                       return new double[len];
+               if( list.isEmpty() ) {
+                       double[] tmp = new double[len];
+                       if( reset && resetVal != 0 )
+                               Arrays.fill(tmp, resetVal);
+                       return tmp;
+               }
                
                //get and re-queue first entry
                double[] tmp = list.removeFirst();
@@ -1182,7 +1249,7 @@ public class LibSpoofPrimitives
                
                //reset vector if required
                if( reset )
-                       Arrays.fill(tmp, 0);
+                       Arrays.fill(tmp, resetVal);
                return tmp;
        }
 }

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java 
b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
index 104a1bf..611e4ad 100644
--- a/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
+++ b/src/main/java/org/apache/sysml/runtime/codegen/SpoofRowwise.java
@@ -132,7 +132,7 @@ public abstract class SpoofRowwise extends SpoofOperator
                        executeDense(a.getDenseBlock(), b, scalars, c, n, 0, m);
                else
                        executeSparse(a.getSparseBlock(), b, scalars, c, n, 0, 
m);
-       
+               
                //post-processing
                if( allocTmp )
                        LibSpoofPrimitives.cleanupThreadLocalMemory();
@@ -220,29 +220,26 @@ public abstract class SpoofRowwise extends SpoofOperator
                
                for( int i=rl, aix=rl*n; i<ru; i++, aix+=n ) {
                        //call generated method
-                       genexecRowDense( a, aix, b, scalars, c, n, i );
+                       genexec( a, aix, b, scalars, c, n, i );
                }
        }
        
        private void executeSparse(SparseBlock sblock, double[][] b, double[] 
scalars, double[] c, int n, int rl, int ru) 
        {
-               if( sblock == null )
-                       return;
-               
                SparseRow empty = new SparseRowVector(1);
                for( int i=rl; i<ru; i++ ) {
-                       if( !sblock.isEmpty(i) ) {
+                       if( sblock!=null && !sblock.isEmpty(i) ) {
                                double[] avals = sblock.values(i);
                                int[] aix = sblock.indexes(i);
                                int apos = sblock.pos(i);
                                int alen = sblock.size(i);
                                
                                //call generated method
-                               genexecRowSparse(avals, aix, apos, b, scalars, 
c, alen, i);
+                               genexec(avals, aix, apos, b, scalars, c, alen, 
n, i);
                        }
                        else
-                               genexecRowSparse(empty.values(), 
-                                       empty.indexes(), 0, b, scalars, c, 0, 
i);       
+                               genexec(empty.values(), 
+                                       empty.indexes(), 0, b, scalars, c, 0, 
n, i);    
                }
        }
        
@@ -254,7 +251,7 @@ public abstract class SpoofRowwise extends SpoofOperator
                if( !a.isInSparseFormat() ) { //DENSE
                        Iterator<double[]> iter = a.getDenseRowIterator(rl, ru);
                        for( int i=rl; iter.hasNext(); i++ ) {
-                               genexecRowDense(iter.next(), 0, b, scalars, c, 
n, i);
+                               genexec(iter.next(), 0, b, scalars, c, n, i);
                        }
                }
                else { //SPARSE
@@ -263,20 +260,22 @@ public abstract class SpoofRowwise extends SpoofOperator
                        for( int i=rl; iter.hasNext(); i++ ) {
                                SparseRow row = iter.next();
                                if( !row.isEmpty() )
-                                       genexecRowSparse(row.values(), 
-                                               row.indexes(), 0, b, scalars, 
c, row.size(), i);
+                                       genexec(row.values(), 
+                                               row.indexes(), 0, b, scalars, 
c, row.size(), n, i);
                                else
-                                       genexecRowSparse(empty.values(), 
-                                               empty.indexes(), 0, b, scalars, 
c, 0, i);
+                                       genexec(empty.values(), 
+                                               empty.indexes(), 0, b, scalars, 
c, 0, n, i);
                        }
                }
        }
        
        //methods to be implemented by generated operators of type 
SpoofRowAggrgate 
        
-       protected abstract void genexecRowDense( double[] a, int ai, double[][] 
b, double[] scalars, double[] c, int len, int rowIndex );
+       protected abstract void genexec(double[] a, int ai, 
+               double[][] b, double[] scalars, double[] c, int len, int 
rowIndex);
        
-       protected abstract void genexecRowSparse( double[] avals, int[] aix, 
int ai, double[][] b, double[] scalars, double[] c, int len, int rowIndex );
+       protected abstract void genexec(double[] avals, int[] aix, int ai, 
+               double[][] b, double[] scalars, double[] c, int alen, int n, 
int rowIndex);
 
        
        /**

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
index f867e18..614d6e0 100644
--- 
a/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
+++ 
b/src/test/java/org/apache/sysml/test/integration/functions/codegen/RowAggTmplTest.java
@@ -57,6 +57,7 @@ public class RowAggTmplTest extends AutomatedTestBase
        private static final String TEST_NAME19 = TEST_NAME+"19"; //MLogreg - 
rowwise dag
        private static final String TEST_NAME20 = TEST_NAME+"20"; //1 / (1 - (A 
/ rowSums(A)))
        private static final String TEST_NAME21 = TEST_NAME+"21"; 
//sum(X/rowSums(X))
+       private static final String TEST_NAME22 = TEST_NAME+"22"; 
//((7+X)+(X-7)+exp(X))/(rowMins(X)+0.5) 
        
        private static final String TEST_DIR = "functions/codegen/";
        private static final String TEST_CLASS_DIR = TEST_DIR + 
RowAggTmplTest.class.getSimpleName() + "/";
@@ -68,7 +69,7 @@ public class RowAggTmplTest extends AutomatedTestBase
        @Override
        public void setUp() {
                TestUtils.clearAssertionInformation();
-               for(int i=1; i<=21; i++)
+               for(int i=1; i<=22; i++)
                        addTestConfiguration( TEST_NAME+i, new 
TestConfiguration(TEST_CLASS_DIR, TEST_NAME+i, new String[] { String.valueOf(i) 
}) );
        }
        
@@ -387,6 +388,21 @@ public class RowAggTmplTest extends AutomatedTestBase
                testCodegenIntegration( TEST_NAME21, false, ExecType.SPARK );
        }
        
+       @Test   
+       public void testCodegenRowAggRewrite22CP() {
+               testCodegenIntegration( TEST_NAME22, true, ExecType.CP );
+       }
+       
+       @Test
+       public void testCodegenRowAgg22CP() {
+               testCodegenIntegration( TEST_NAME22, false, ExecType.CP );
+       }
+       
+       @Test
+       public void testCodegenRowAgg22SP() {
+               testCodegenIntegration( TEST_NAME22, false, ExecType.SPARK );
+       }
+       
        private void testCodegenIntegration( String testname, boolean rewrites, 
ExecType instType )
        {       
                boolean oldFlag = OptimizerUtils.ALLOW_ALGEBRAIC_SIMPLIFICATION;

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/test/scripts/functions/codegen/rowAggPattern22.R
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/rowAggPattern22.R 
b/src/test/scripts/functions/codegen/rowAggPattern22.R
new file mode 100644
index 0000000..97f0b27
--- /dev/null
+++ b/src/test/scripts/functions/codegen/rowAggPattern22.R
@@ -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.
+#
+#-------------------------------------------------------------
+
+args<-commandArgs(TRUE)
+options(digits=22)
+library("Matrix")
+library("matrixStats")
+
+X = matrix(seq(1,3000), 60, 50, byrow=TRUE)/10000;
+X[,5:45] = matrix(0, 60, 41);
+
+R = ((7+X)+(X-7)+(X^2<=7))/((rowMaxs(X)%*%matrix(1,1,50))+0.5)
+
+writeMM(as(R, "CsparseMatrix"), paste(args[2], "S", sep="")); 

http://git-wip-us.apache.org/repos/asf/systemml/blob/c17b8a8e/src/test/scripts/functions/codegen/rowAggPattern22.dml
----------------------------------------------------------------------
diff --git a/src/test/scripts/functions/codegen/rowAggPattern22.dml 
b/src/test/scripts/functions/codegen/rowAggPattern22.dml
new file mode 100644
index 0000000..5e3968a
--- /dev/null
+++ b/src/test/scripts/functions/codegen/rowAggPattern22.dml
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+
+X = matrix(seq(1,3000), 60, 50)/10000;
+X[,5:45] = matrix(0, 60, 41);
+
+R = ((7+X)+(X-7)+(X^2<=7))/(rowMaxs(X)+0.5)
+
+write(R, $1)

Reply via email to