This is an automated email from the ASF dual-hosted git repository.

mboehm7 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/systemds.git


The following commit(s) were added to refs/heads/main by this push:
     new e6eebb9c90 [SYSTEMDS-3172] Cleanup new MCSC sparse block, new tests
e6eebb9c90 is described below

commit e6eebb9c900b7de1f6e97b98386a8d88c41c071b
Author: ReneEnjilian <[email protected]>
AuthorDate: Sun Jul 14 11:48:03 2024 +0200

    [SYSTEMDS-3172] Cleanup new MCSC sparse block, new tests
    
    Closes #2049.
---
 .../apache/sysds/runtime/data/SparseBlockCOO.java  |  10 +-
 .../apache/sysds/runtime/data/SparseBlockCSR.java  |   8 +-
 .../sysds/runtime/data/SparseBlockFactory.java     |   9 +-
 .../apache/sysds/runtime/data/SparseBlockMCSC.java | 327 ++++++++++++++++++---
 .../apache/sysds/runtime/data/SparseBlockMCSR.java |  10 +-
 .../component/sparse/SparseBlockAlignment.java     |  19 +-
 .../component/sparse/SparseBlockAppendSort.java    |  71 ++---
 .../test/component/sparse/SparseBlockDelete.java   |  19 +-
 .../component/sparse/SparseBlockGetFirstIndex.java | 128 +++-----
 .../test/component/sparse/SparseBlockGetSet.java   | 104 +------
 .../component/sparse/SparseBlockIndexRange.java    |  74 +----
 .../test/component/sparse/SparseBlockIterator.java |  39 ++-
 .../component/sparse/SparseBlockMemEstimate.java   |   2 +-
 .../test/component/sparse/SparseBlockMerge.java    | 167 ++++++++++-
 .../test/component/sparse/SparseBlockScan.java     |  48 +--
 .../test/component/sparse/SparseBlockSize.java     | 200 ++++++++-----
 16 files changed, 776 insertions(+), 459 deletions(-)

diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseBlockCOO.java 
b/src/main/java/org/apache/sysds/runtime/data/SparseBlockCOO.java
index 1ad2cd57d0..d83a9263dc 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockCOO.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockCOO.java
@@ -312,15 +312,15 @@ public class SparseBlockCOO extends SparseBlock
        public long size(int rl, int ru) {
                return pos(ru) - pos(rl);
        }
-       
+
        @Override
        public long size(int rl, int ru, int cl, int cu) {
                long nnz = 0;
-               for(int i=rl; i<ru; i++)
-                       if( !isEmpty(i) ) {
+               for(int i = rl; i < ru; i++)
+                       if(!isEmpty(i)) {
                                int start = internPosFIndexGTE(i, cl);
-                               int end = internPosFIndexGTE(i, cu);
-                               nnz += (start!=-1) ? (end-start) : 0;
+                               int end = internPosFIndexLTE(i, cu - 1);
+                               nnz += (start != -1 && end != -1) ? (end - 
start + 1) : 0;
                        }
                return nnz;
        }
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java 
b/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java
index 13e844007b..68cc6c8f86 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockCSR.java
@@ -437,11 +437,11 @@ public class SparseBlockCSR extends SparseBlock
        @Override
        public long size(int rl, int ru, int cl, int cu) {
                long nnz = 0;
-               for(int i=rl; i<ru; i++)
-                       if( !isEmpty(i) ) {
+               for(int i = rl; i < ru; i++)
+                       if(!isEmpty(i)) {
                                int start = internPosFIndexGTE(i, cl);
-                               int end = internPosFIndexGTE(i, cu);
-                               nnz += (start!=-1) ? (end-start) : 0;
+                               int end = internPosFIndexLTE(i, cu - 1);
+                               nnz += (start != -1 && end != -1) ? (end - 
start + 1) : 0;
                        }
                return nnz;
        }
diff --git 
a/src/main/java/org/apache/sysds/runtime/data/SparseBlockFactory.java 
b/src/main/java/org/apache/sysds/runtime/data/SparseBlockFactory.java
index a6297f8f5b..106dd36ba9 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockFactory.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockFactory.java
@@ -48,7 +48,12 @@ public abstract class SparseBlockFactory{
                return ret;
        }
 
-       public static SparseBlock copySparseBlock( SparseBlock.Type type, 
SparseBlock sblock, boolean forceCopy )
+       public static SparseBlock copySparseBlock(SparseBlock.Type type, 
SparseBlock sblock, boolean forceCopy) {
+               //Call this method in case 'type' is row format
+               return copySparseBlock(type, sblock, forceCopy, 1000); // 
Default clen value
+       }
+
+       public static SparseBlock copySparseBlock( SparseBlock.Type type, 
SparseBlock sblock, boolean forceCopy , int clen)
        {
                //sanity check for empty inputs
                if( sblock == null )
@@ -65,7 +70,7 @@ public abstract class SparseBlockFactory{
                        case CSR: return new SparseBlockCSR(sblock);
                        case COO: return new SparseBlockCOO(sblock);
                        case DCSR: return new SparseBlockDCSR(sblock);
-                       case MCSC: return new SparseBlockMCSC(sblock);
+                       case MCSC: return new SparseBlockMCSC(sblock, clen);
                        default:
                                throw new RuntimeException("Unexpected sparse 
block type: "+type.toString());
                }
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSC.java 
b/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSC.java
index ec744d60a7..7a12d3e7aa 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSC.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSC.java
@@ -42,13 +42,16 @@ public class SparseBlockMCSC extends SparseBlock {
 
        private SparseRow[] _columns = null;
        private int _clenInferred = -1;
+       private int _rlen = -1;
 
        public SparseBlockMCSC(SparseBlock sblock, int clen) {
                _clenInferred = clen;
+               _rlen = sblock.numRows();
                initialize(sblock);
        }
 
        public SparseBlockMCSC(SparseBlock sblock) {
+               _rlen = sblock.numRows();
                initialize(sblock);
        }
 
@@ -153,7 +156,8 @@ public class SparseBlockMCSC extends SparseBlock {
                }
        }
 
-       public SparseBlockMCSC(SparseRow[] cols, boolean deep) {
+       public SparseBlockMCSC(SparseRow[] cols, boolean deep, int rlen) {
+               _rlen = rlen;
                if(deep) {
                        _columns = new SparseRow[cols.length];
                        for(int i = 0; i < _columns.length; i++) {
@@ -171,7 +175,8 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        public SparseBlockMCSC(int rlen, int clen) {
-               this(clen);
+               _rlen = rlen;
+               _columns = new SparseRow[clen];
        }
 
        /**
@@ -239,28 +244,49 @@ public class SparseBlockMCSC extends SparseBlock {
        //SparseBlock implementation
 
        @Override
-       public void allocate(int c) {
-               if(!isAllocated(c)) {
+       public void allocate(int r) {
+               for(int i = 0; i < _columns.length; i++) {
+                       if(!isAllocatedCol(i))
+                               _columns[i] = new SparseRowVector();
+               }
+       }
+
+       public void allocateCol(int c) {
+               if(!isAllocatedCol(c)) {
                        _columns[c] = new SparseRowVector();
                }
        }
 
        @Override
-       public void allocate(int c, int nnz) {
+       public void allocate(int r, int nnz) {
+               allocate(r);
+       }
+
+       public void allocateCol(int c, int nnz) {
                if(!isAllocated(c)) {
                        _columns[c] = (nnz == 1) ? new SparseRowScalar() : new 
SparseRowVector(nnz);
                }
        }
 
        @Override
-       public void allocate(int c, int ennz, int maxnnz) {
+       public void allocate(int r, int ennz, int maxnnz) {
+               allocate(r);
+       }
+
+       public void allocateCol(int c, int ennz, int maxnnz) {
                if(!isAllocated(c)) {
                        _columns[c] = (ennz == 1) ? new SparseRowScalar() : new 
SparseRowVector(ennz, maxnnz);
                }
        }
 
        @Override
-       public void compact(int c) {
+       public void compact(int r) {
+               for(int i = 0; i < _columns.length; i++) {
+                       compactCol(i);
+               }
+       }
+
+       public void compactCol(int c) {
                if(isAllocated(c)) {
                        if(_columns[c] instanceof SparseRowVector && 
_columns[c].size() > SparseBlock.INIT_CAPACITY &&
                                _columns[c].size() * SparseBlock.RESIZE_FACTOR1 
< ((SparseRowVector) _columns[c]).capacity()) {
@@ -272,13 +298,11 @@ public class SparseBlockMCSC extends SparseBlock {
                                        _columns[c] = null;
                        }
                }
-
        }
 
        @Override
        public int numRows() {
-               // this is a column-oriented layout
-               return 0;
+               return _rlen;
        }
 
        public int numCols() {
@@ -296,7 +320,14 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public boolean isAllocated(int c) {
+       public boolean isAllocated(int r) {
+               for(SparseRow col : _columns)
+                       if(col == null)
+                               return false;
+               return true;
+       }
+
+       public boolean isAllocatedCol(int c) {
                return _columns[c] != null;
        }
 
@@ -319,8 +350,19 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public void reset(int c, int ennz, int maxnnz) {
-               if(isAllocated(c)) {
+       public void reset(int r, int ennz, int maxnnz) {
+               for(int i = 0; i < _columns.length; i++) {
+                       if(isAllocatedCol(i)) {
+                               if(_columns[i] instanceof SparseRowScalar && 
_columns[i].indexes()[0] == r)
+                                       _columns[i].set(r, 0);
+                               else if(_columns[i] instanceof SparseRowVector)
+                                       _columns[i].set(r, 0);
+                       }
+               }
+       }
+
+       public void resetCol(int c, int ennz, int maxnnz) {
+               if(isAllocatedCol(c)) {
                        _columns[c].reset(ennz, maxnnz);
                }
        }
@@ -337,13 +379,33 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public int size(int c) {
+       public int size(int r) {
+               int nnz = 0;
+               for(int i = 0; i < _columns.length; i++) {
+                       if(isAllocatedCol(i))
+                               nnz += (_columns[i].get(r) != 0) ? 1 : 0;
+               }
+               return nnz;
+       }
+
+       public int sizeCol(int c) {
                //prior check with isEmpty(r) expected
                return isAllocated(c) ? _columns[c].size() : 0;
        }
 
        @Override
-       public long size(int cl, int cu) {
+       public long size(int rl, int ru) {
+               long nnz = 0;
+               for(int i = 0; i < _columns.length; i++) {
+                       if(isAllocatedCol(i)) {
+                               for(int j = rl; j < ru; j++)
+                                       nnz += (_columns[i].get(j) != 0) ? 1 : 
0;
+                       }
+               }
+               return nnz;
+       }
+
+       public long sizeCol(int cl, int cu) {
                long nnz = 0;
                for(int i = cl; i < cu; i++) {
                        nnz += isAllocated(i) ? _columns[i].size() : 0;
@@ -355,17 +417,27 @@ public class SparseBlockMCSC extends SparseBlock {
        public long size(int rl, int ru, int cl, int cu) {
                long nnz = 0;
                for(int i = cl; i < cu; i++) {
-                       if(!isEmpty(i)) {
-                               int start = posFIndexGTE(rl, i);
-                               int end = posFIndexGTE(ru, i);
-                               nnz += (start != -1) ? (end - start) : 0;
+                       if(!isEmptyCol(i)) {
+                               int start = posFIndexGTECol(rl, i);
+                               int end = posFIndexLTECol(ru - 1, i);
+                               nnz += (start != -1 && end != -1) ? (end - 
start + 1) : 0;
                        }
                }
                return nnz;
        }
 
        @Override
-       public boolean isEmpty(int c) {
+       public boolean isEmpty(int r) {
+               for(int i = 0; i < _columns.length; i++) {
+                       if(!isAllocatedCol(i))
+                               continue;
+                       else if(_columns[i].get(r) != 0)
+                               return false;
+               }
+               return true;
+       }
+
+       public boolean isEmptyCol(int c) {
                return _columns[c] == null || _columns[c].isEmpty();
        }
 
@@ -413,26 +485,54 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public int[] indexes(int c) {
+       public int[] indexes(int r) {
+               //prior check with isEmpty(r) expected
+               int nnz = size(r);
+               int[] idx = new int[nnz];
+               int index = 0;
+               for(int i = 0; i < _columns.length; i++) {
+                       if(isAllocatedCol(i) && _columns[i].get(r) != 0) {
+                               idx[index] = i;
+                               index++;
+                       }
+               }
+               return idx;
+       }
+
+       public int[] indexesCol(int c) {
                //prior check with isEmpty(c) expected
                return _columns[c].indexes();
        }
 
        @Override
-       public double[] values(int c) {
+       public double[] values(int r) {
+               //prior check with isEmpty(r) expected
+               int nnz = size(r);
+               double[] vals = new double[nnz];
+               int index = 0;
+               for(int i = 0; i < _columns.length; i++) {
+                       if(isAllocatedCol(i) && _columns[i].get(r) != 0) {
+                               vals[index] = _columns[i].get(r);
+                               index++;
+                       }
+               }
+               return vals;
+       }
+
+       public double[] valuesCol(int c) {
                //prior check with isEmpty(c) expected
                return _columns[c].values();
        }
 
        @Override
-       public int pos(int c) {
-               //arrays per column (always start 0)
+       public int pos(int r) {
+               //arrays per row (always start 0)
                return 0;
        }
 
        @Override
        public boolean set(int r, int c, double v) {
-               if(!isAllocated(c)) {
+               if(!isAllocatedCol(c)) {
                        _columns[c] = new SparseRowScalar();
                }
                else if(_columns[c] instanceof SparseRowScalar && 
!_columns[c].isEmpty()) {
@@ -442,9 +542,17 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public void set(int c, SparseRow col, boolean deep) {
+       public void set(int r, SparseRow row, boolean deep) {
+               reset(r, 1, 1);
+               int nnz = row.size();
+               for(int i = 0; i < nnz; i++) {
+                       set(r, row.indexes()[i], row.values()[i]);
+               }
+       }
+
+       public void setCol(int c, SparseRow col, boolean deep) {
                //copy values into existing column to avoid allocation
-               if(isAllocated(c) && _columns[c] instanceof SparseRowVector &&
+               if(isAllocatedCol(c) && _columns[c] instanceof SparseRowVector 
&&
                        ((SparseRowVector) _columns[c]).capacity() >= 
col.size() && deep) {
                        ((SparseRowVector) _columns[c]).copy(col);
                        //set new sparse column (incl allocation if required)
@@ -456,7 +564,7 @@ public class SparseBlockMCSC extends SparseBlock {
 
        @Override
        public boolean add(int r, int c, double v) {
-               if(!isAllocated(c)) {
+               if(!isAllocatedCol(c)) {
                        _columns[c] = new SparseRowScalar();
                }
                else if(_columns[c] instanceof SparseRowScalar && 
!_columns[c].isEmpty()) {
@@ -485,8 +593,16 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public void setIndexRange(int c, int rl, int ru, double[] v, int vix, 
int vlen) {
-               if(!isAllocated(c)) {
+       public void setIndexRange(int r, int cl, int cu, double[] v, int vix, 
int vlen) {
+               int idx = vix;
+               for(int i = cl; i < cu; i++) {
+                       set(r, i, v[idx]);
+                       idx++;
+               }
+       }
+
+       public void setIndexRangeCol(int c, int rl, int ru, double[] v, int 
vix, int vlen) {
+               if(!isAllocatedCol(c)) {
                        _columns[c] = new SparseRowVector();
                }
                else if(_columns[c] instanceof SparseRowScalar) {
@@ -496,8 +612,14 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public void setIndexRange(int c, int rl, int ru, double[] v, int[] vix, 
int vpos, int vlen) {
-               if(!isAllocated(c)) {
+       public void setIndexRange(int r, int cl, int cu, double[] v, int[] vix, 
int vpos, int vlen) {
+               for(int i = vpos; i < (vpos + vlen); i++) {
+                       set(r, vix[i], v[i]);
+               }
+       }
+
+       public void setIndexRangeCol(int c, int rl, int ru, double[] v, int[] 
vix, int vpos, int vlen) {
+               if(!isAllocatedCol(c)) {
                        _columns[c] = new SparseRowVector();
                }
                else if(_columns[c] instanceof SparseRowScalar) {
@@ -508,7 +630,18 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public void deleteIndexRange(int c, int rl, int ru) {
+       public void deleteIndexRange(int r, int cl, int cu) {
+               for(int i = cl; i < cu; i++) {
+                       if(isAllocatedCol(i)) {
+                               if(_columns[i] instanceof SparseRowScalar && 
_columns[i].indexes()[0] == r)
+                                       _columns[i].set(r, 0);
+                               else if(_columns[i] instanceof SparseRowVector)
+                                       _columns[i].set(r, 0);
+                       }
+               }
+       }
+
+       public void deleteIndexRangeCol(int c, int rl, int ru) {
                //prior check with isEmpty(c) expected
                //different sparse row semantics: upper bound inclusive
                if(_columns[c] instanceof SparseRowScalar) {
@@ -527,26 +660,48 @@ public class SparseBlockMCSC extends SparseBlock {
        }
 
        @Override
-       public void sort(int c) {
+       public void sort(int r) {
+               //prior check with isEmpty(c) expected
+               sort();
+       }
+
+       public void sortCol(int c) {
                //prior check with isEmpty(c) expected
                _columns[c].sort();
        }
 
        @Override
        public double get(int r, int c) {
-               if(!isAllocated(c)) {
+               if(!isAllocatedCol(c)) {
                        return 0;
                }
                return _columns[c].get(r);
        }
 
        @Override
-       public SparseRow get(int c) {
+       public SparseRow get(int r) {
+               SparseRow row = (size(r) == 1) ? new SparseRowScalar() : new 
SparseRowVector(size(r));
+               double v = 0;
+               for(int i = 0; i < _columns.length; i++) {
+                       v = get(r, i);
+                       if(v != 0)
+                               row.set(i, v);
+               }
+               return row;
+       }
+
+       public SparseRow getCol(int c) {
                return _columns[c];
        }
 
        @Override
        public int posFIndexLTE(int r, int c) {
+               //prior check with isEmpty(r) expected
+               SparseRow row = get(r);
+               return ((SparseRowVector) row).searchIndexesFirstLTE(c);
+       }
+
+       public int posFIndexLTECol(int r, int c) {
                //prior check with isEmpty(c) expected
                if(_columns[c] instanceof SparseRowScalar) {
                        _columns[c] = new SparseRowVector(_columns[c]);
@@ -556,17 +711,49 @@ public class SparseBlockMCSC extends SparseBlock {
 
        @Override
        public int posFIndexGTE(int r, int c) {
+               SparseRow row = get(r);
+               return row.searchIndexesFirstGTE(c);
+       }
+
+       public int posFIndexGTECol(int r, int c) {
                return _columns[c].searchIndexesFirstGTE(r);
        }
 
        @Override
        public int posFIndexGT(int r, int c) {
+               SparseRow row = get(r);
+               return row.searchIndexesFirstGT(c);
+       }
+
+       public int posFIndexGTCol(int r, int c) {
                return _columns[c].searchIndexesFirstGT(r);
        }
 
        @Override
        public Iterator<Integer> getNonEmptyRowsIterator(int rl, int ru) {
-               throw new UnsupportedOperationException("Non-empty rows 
iterator is not supported in column layouts.");
+               return new NonEmptyRowsIteratorMCSC(rl, ru);
+       }
+
+       public class NonEmptyRowsIteratorMCSC implements Iterator<Integer> {
+               private int _rpos;
+               private final int _ru;
+
+               public NonEmptyRowsIteratorMCSC(int rl, int ru) {
+                       _rpos = rl;
+                       _ru = ru;
+               }
+
+               @Override
+               public boolean hasNext() {
+                       while(_rpos < _ru && isEmpty(_rpos))
+                               _rpos++;
+                       return _rpos < _ru;
+               }
+
+               @Override
+               public Integer next() {
+                       return _rpos++;
+               }
        }
 
        @Override
@@ -580,7 +767,7 @@ public class SparseBlockMCSC extends SparseBlock {
                sb.append("\n");
                final int colDigits = (int) 
Math.max(Math.ceil(Math.log10(nCol)), 1);
                for(int i = 0; i < nCol; i++) {
-                       if(isEmpty(i))
+                       if(isEmptyCol(i))
                                continue;
                        sb.append(String.format("%0" + colDigits + "d %s\n", i, 
_columns[i].toString()));
                }
@@ -588,7 +775,71 @@ public class SparseBlockMCSC extends SparseBlock {
                return sb.toString();
        }
 
+       /**
+        * Helper function for MCSC
+        *
+        * @return the underlying array of columns {@link SparseRow}
+        */
        public SparseRow[] getCols() {
                return _columns;
        }
+
+       /**
+        * Helper function for MCSC
+        *
+        * @return the corresponding array of rows {@link SparseRow}
+        */
+
+       public SparseRow[] getRows() {
+               SparseRow[] rows = new SparseRow[numRows()];
+               for(int i = 0; i < numRows(); i++) {
+                       rows[i] = get(i);
+               }
+               return rows;
+       }
+
+       public Iterator<Integer> getNonEmptyColumnsIterator(int cl, int cu) {
+               return new NonEmptyColumnsIteratorMCSC(cl, cu);
+       }
+
+       public class NonEmptyColumnsIteratorMCSC implements Iterator<Integer> {
+               private int _cpos;
+               private final int _cu;
+
+               public NonEmptyColumnsIteratorMCSC(int cl, int cu) {
+                       _cpos = cl;
+                       _cu = cu;
+               }
+
+               @Override
+               public boolean hasNext() {
+                       while(_cpos < _cu && isEmptyCol(_cpos)) {
+                               _cpos++;
+                       }
+                       return _cpos < _cu;
+               }
+
+               @Override
+               public Integer next() {
+                       return _cpos++;
+               }
+
+       }
+
+       @SuppressWarnings("unused")
+       private class SparseNonEmptyColumnIterable implements Iterable<Integer> 
{
+               private final int _cl; //column lower
+               private final int _cu; //column upper
+
+               protected SparseNonEmptyColumnIterable(int cl, int cu) {
+                       _cl = cl;
+                       _cu = cu;
+               }
+
+               @Override
+               public Iterator<Integer> iterator() {
+                       //use specialized non-empty row iterators of sparse 
blocks
+                       return getNonEmptyColumnsIterator(_cl, _cu);
+               }
+       }
 }
diff --git a/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java 
b/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java
index 52b5d2e338..d232a0041a 100644
--- a/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java
+++ b/src/main/java/org/apache/sysds/runtime/data/SparseBlockMCSR.java
@@ -305,15 +305,15 @@ public class SparseBlockMCSR extends SparseBlock
                        ret += isAllocated(i) ? _rows[i].size() : 0;
                return ret;
        }
-       
+
        @Override
        public long size(int rl, int ru, int cl, int cu) {
                long nnz = 0;
-               for(int i=rl; i<ru; i++)
-                       if( !isEmpty(i) ) {
+               for(int i = rl; i < ru; i++)
+                       if(!isEmpty(i)) {
                                int start = posFIndexGTE(i, cl);
-                               int end = posFIndexGTE(i, cu);
-                               nnz += (start!=-1) ? (end-start) : 0;
+                               int end = posFIndexLTE(i, cu - 1);
+                               nnz += (start != -1 && end != -1) ? (end - 
start + 1) : 0;
                        }
                return nnz;
        }
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAlignment.java
 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAlignment.java
index f6d2b73b69..41caea2e37 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAlignment.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAlignment.java
@@ -182,6 +182,21 @@ public class SparseBlockAlignment extends AutomatedTestBase
                runSparseBlockScanTest(SparseBlock.Type.DCSR, sparsity3, false);
        }
 
+       @Test
+       public void testSparseBlockMCSC1Neg()  {
+               runSparseBlockScanTest(SparseBlock.Type.MCSC, sparsity1, false);
+       }
+
+       @Test
+       public void testSparseBlockMCSC2Neg()  {
+               runSparseBlockScanTest(SparseBlock.Type.MCSC, sparsity2, false);
+       }
+
+       @Test
+       public void testSparseBlockMCSC3Neg()  {
+               runSparseBlockScanTest(SparseBlock.Type.MCSC, sparsity3, false);
+       }
+
        private void runSparseBlockScanTest( SparseBlock.Type btype, double 
sparsity, boolean positive)
        {
                try
@@ -192,10 +207,10 @@ public class SparseBlockAlignment extends 
AutomatedTestBase
                        //init sparse block
                        MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
                        SparseBlock srtmp = mbtmp.getSparseBlock();
-                       SparseBlock sblock = 
SparseBlockFactory.copySparseBlock(btype, srtmp, true);
+                       SparseBlock sblock = 
SparseBlockFactory.copySparseBlock(btype, srtmp, true, cols);
                        
                        //init second sparse block and deep copy
-                       SparseBlock sblock2 = 
SparseBlockFactory.copySparseBlock(btype, sblock, true);
+                       SparseBlock sblock2 = 
SparseBlockFactory.copySparseBlock(btype, sblock, true, cols);
                        
                        //modify second block if necessary
                        if( !positive ) {
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAppendSort.java
 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAppendSort.java
index 8c42af17af..37bdd4fb87 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAppendSort.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockAppendSort.java
@@ -230,68 +230,45 @@ public class SparseBlockAppendSort extends 
AutomatedTestBase
                                        for( int j=0; j<cols; j++ )
                                                sblock.append(i, j, A[i][j]);
                        }
-                       else if( itype == InitType.RAND_SET ) {
+                       else if(itype == InitType.RAND_SET) {
                                LongLongDoubleHashMap map = new 
LongLongDoubleHashMap();
-                               for( int i=0; i<rows; i++ )
-                                       for( int j=0; j<cols; j++ )
+                               for(int i = 0; i < rows; i++)
+                                       for(int j = 0; j < cols; j++)
                                                map.addValue(i, j, A[i][j]);
                                Iterator<ADoubleEntry> iter = map.getIterator();
-                               while( iter.hasNext() ) { //random hash order
+                               while(iter.hasNext()) { //random hash order
                                        ADoubleEntry e = iter.next();
-                                       sblock.append((int)e.getKey1(), 
(int)e.getKey2(), e.value);
+                                       sblock.append((int) e.getKey1(), (int) 
e.getKey2(), e.value);
                                }
-                       }       
-                       
+                       }
+
                        //sort appended values
                        sblock.sort();
-                       
+
                        //check for correct number of non-zeros
-                       int[] rnnz = new int[rows];
-                       int nnz = 0;
-                       int[] cnnz = new int[cols];
-                       for( int i=0; i<rows; i++ ) {
-                               for( int j=0; j<cols; j++ ) {
-                                       cnnz[j] += (A[i][j] != 0) ? 1 : 0;
+                       int[] rnnz = new int[rows]; int nnz = 0;
+                       for(int i = 0; i < rows; i++) {
+                               for(int j = 0; j < cols; j++)
                                        rnnz[i] += (A[i][j] != 0) ? 1 : 0;
-                               }
                                nnz += rnnz[i];
                        }
-                       if( nnz != sblock.size() )
-                               Assert.fail("Wrong number of non-zeros: 
"+sblock.size()+", expected: "+nnz);
+
+                       if(nnz != sblock.size())
+                               Assert.fail("Wrong number of non-zeros: " + 
sblock.size() + ", expected: " + nnz);
 
                        //check correct isEmpty return
-                       if(sblock instanceof SparseBlockMCSC) {
-                               for(int i = 0; i < cols; i++)
-                                       if(sblock.isEmpty(i) != (cnnz[i] == 0))
-                                               Assert.fail("Wrong 
isEmpty(column) result for row nnz: " + cnnz[i]);
-                       }
-                       else {
-                               for(int i = 0; i < rows; i++)
-                                       if(sblock.isEmpty(i) != (rnnz[i] == 0))
-                                               Assert.fail("Wrong isEmpty(row) 
result for row nnz: " + rnnz[i]);
-                       }
+                       for(int i = 0; i < rows; i++)
+                               if(sblock.isEmpty(i) != (rnnz[i] == 0))
+                                       Assert.fail("Wrong isEmpty(row) result 
for row nnz: " + rnnz[i]);
 
                        //check correct values
-                       if(sblock instanceof SparseBlockMCSC) {
-                               for(int i = 0; i < cols; i++) {
-                                       if(sblock.isEmpty(i)) continue;
-                                       for(int j = 0; j < rows; j++) {
-                                               double tmp = sblock.get(j, i);
-                                               if(tmp != A[j][i])
-                                                       Assert.fail("Wrong get 
value for cell (" + i + "," + j + "): " + tmp + ", expected: " +
-                                                               A[i][j]);
-                                       }
-                               }
-                       }
-                       else {
-                               for(int i = 0; i < rows; i++) {
-                                       if(sblock.isEmpty(i)) continue;
-                                       for(int j = 0; j < cols; j++) {
-                                               double tmp = sblock.get(i, j);
-                                               if(tmp != A[i][j])
-                                                       Assert.fail("Wrong get 
value for cell (" + i + "," + j + "): " + tmp + ", expected: " +
-                                                               A[i][j]);
-                                       }
+                       for(int i = 0; i < rows; i++) {
+                               if(sblock.isEmpty(i))
+                                       continue;
+                               for(int j = 0; j < cols; j++) {
+                                       double tmp = sblock.get(i, j);
+                                       if(tmp != A[i][j])
+                                               Assert.fail("Wrong get value 
for cell (" + i + "," + j + "): " + tmp + ", expected: " + A[i][j]);
                                }
                        }
                }
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockDelete.java 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockDelete.java
index 9862659779..7ac63c0cee 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockDelete.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockDelete.java
@@ -111,6 +111,21 @@ public class SparseBlockDelete extends AutomatedTestBase
        public void testSparseBlockDCSR3()  {
                runSparseBlockDeleteTest(SparseBlock.Type.DCSR, sparsity3);
        }
+
+       @Test
+       public void testSparseBlockMCSC1()  {
+               runSparseBlockDeleteTest(SparseBlock.Type.MCSC, sparsity1);
+       }
+
+       @Test
+       public void testSparseBlockMCSC2()  {
+               runSparseBlockDeleteTest(SparseBlock.Type.MCSC, sparsity2);
+       }
+
+       @Test
+       public void testSparseBlockMCSC3()  {
+               runSparseBlockDeleteTest(SparseBlock.Type.MCSC, sparsity3);
+       }
        
        private void runSparseBlockDeleteTest( SparseBlock.Type btype, double 
sparsity)
        {
@@ -122,7 +137,7 @@ public class SparseBlockDelete extends AutomatedTestBase
                        //init sparse block
                        MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
                        SparseBlock srtmp = mbtmp.getSparseBlock();             
        
-                       SparseBlock sblock = 
SparseBlockFactory.copySparseBlock(btype, srtmp, true);
+                       SparseBlock sblock = 
SparseBlockFactory.copySparseBlock(btype, srtmp, true, cols);
                        
                        //delete range per row via set
                        for( int i=0; i<rows; i++ )
@@ -163,4 +178,4 @@ public class SparseBlockDelete extends AutomatedTestBase
                        throw new RuntimeException(ex);
                }
        }
-}
\ No newline at end of file
+}
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetFirstIndex.java
 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetFirstIndex.java
index 1ad84df759..5816ba6b26 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetFirstIndex.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetFirstIndex.java
@@ -287,80 +287,69 @@ public class SparseBlockGetFirstIndex extends 
AutomatedTestBase
                try
                {
                        //data generation
-                       double[][] A = getRandomMatrix(rows, cols, -10, 10, 
sparsity, 3456); 
-                       
+                       double[][] A = getRandomMatrix(rows, cols, -10, 10, 
sparsity, 3456);
+
                        //init sparse block
                        SparseBlock sblock = null;
                        MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
                        SparseBlock srtmp = mbtmp.getSparseBlock();
-                       switch( btype ) {
-                               case MCSR: sblock = new SparseBlockMCSR(srtmp); 
break;
-                               case CSR: sblock = new SparseBlockCSR(srtmp); 
break;
-                               case COO: sblock = new SparseBlockCOO(srtmp); 
break;
-                               case DCSR: sblock = new SparseBlockDCSR(srtmp); 
break;
-                               case MCSC: sblock = new SparseBlockMCSC(srtmp, 
cols); break;
+                       switch(btype) {
+                               case MCSR:
+                                       sblock = new SparseBlockMCSR(srtmp);
+                                       break;
+                               case CSR:
+                                       sblock = new SparseBlockCSR(srtmp);
+                                       break;
+                               case COO:
+                                       sblock = new SparseBlockCOO(srtmp);
+                                       break;
+                               case DCSR:
+                                       sblock = new SparseBlockDCSR(srtmp);
+                                       break;
+                               case MCSC:
+                                       sblock = new SparseBlockMCSC(srtmp, 
cols);
+                                       break;
                        }
-                       
+
                        //check for correct number of non-zeros
-                       int[] rnnz = new int[rows]; int nnz = 0;
-                       int[] cnnz =new int[cols];
-                       for( int i=0; i<rows; i++ ) {
-                               for( int j=0; j<cols; j++ ) {
-                                       cnnz[j] += (A[i][j] != 0) ? 1 : 0;
+                       int[] rnnz = new int[rows];
+                       int nnz = 0;
+                       for(int i = 0; i < rows; i++) {
+                               for(int j = 0; j < cols; j++)
                                        rnnz[i] += (A[i][j] != 0) ? 1 : 0;
-                               }
                                nnz += rnnz[i];
                        }
-                       if( nnz != sblock.size() )
-                               Assert.fail("Wrong number of non-zeros: 
"+sblock.size()+", expected: "+nnz);
+
+                       if(nnz != sblock.size())
+                               Assert.fail("Wrong number of non-zeros: " + 
sblock.size() + ", expected: " + nnz);
 
                        //check correct isEmpty return
-                       if(sblock instanceof SparseBlockMCSC) {
-                               for(int i = 0; i < cols; i++)
-                                       if(sblock.isEmpty(i) != (cnnz[i] == 0))
-                                               Assert.fail("Wrong isEmpty(col) 
result for row nnz: " + cnnz[i]);
-                       }
-                       else {
-                               for(int i = 0; i < rows; i++)
-                                       if(sblock.isEmpty(i) != (rnnz[i] == 0))
-                                               Assert.fail("Wrong isEmpty(row) 
result for row nnz: " + rnnz[i]);
-                       }
+                       for(int i = 0; i < rows; i++)
+                               if(sblock.isEmpty(i) != (rnnz[i] == 0))
+                                       Assert.fail("Wrong isEmpty(row) result 
for row nnz: " + rnnz[i]);
 
                        //check correct index values
-                       if(sblock instanceof SparseBlockMCSC){
-                               for (int i = 0; i < cols; i++) {
-                                       int ix = getFirstIxCol(A, i, i, itype);
-                                       int sixpos = -1;
-                                       switch (itype) {
-                                               case GT: sixpos = 
sblock.posFIndexGT(i, i); break;
-                                               case GTE: sixpos = 
sblock.posFIndexGTE(i, i); break;
-                                               case LTE: sixpos = 
sblock.posFIndexLTE(i, i); break;
-                                       }
-                                       int six = (sixpos >= 0) ?
-                                               sblock.indexes(i)[sblock.pos(i) 
+ sixpos] : -1;
-                                       if (six != ix) {
-                                               Assert.fail("Wrong index 
returned by index probe (" +
-                                                       itype.toString() + "," 
+ i + "): " + six + ", expected: " + ix);
-                                       }
+                       for(int i = 0; i < rows; i++) {
+                               int ix = getFirstIx(A, i, i, itype);
+                               int sixpos = -1;
+                               switch(itype) {
+                                       case GT:
+                                               sixpos = sblock.posFIndexGT(i, 
i);
+                                               break;
+                                       case GTE:
+                                               sixpos = sblock.posFIndexGTE(i, 
i);
+                                               break;
+                                       case LTE:
+                                               sixpos = sblock.posFIndexLTE(i, 
i);
+                                               break;
                                }
-                       }
-                       else{
-                               for( int i=0; i<rows; i++ ) {
-                                       int ix = getFirstIx(A, i, i, itype);
-                                       int sixpos = -1;
-                                       switch( itype ) {
-                                               case GT: sixpos = 
sblock.posFIndexGT(i, i); break;
-                                               case GTE: sixpos = 
sblock.posFIndexGTE(i, i); break;
-                                               case LTE: sixpos = 
sblock.posFIndexLTE(i, i); break;
-                                       }
-                                       int six = (sixpos>=0) ?
-                                               
sblock.indexes(i)[sblock.pos(i)+sixpos] : -1;
-                                       if( six != ix ) {
-                                               Assert.fail("Wrong index 
returned by index probe ("+
-                                                               
itype.toString()+","+i+"): "+six+", expected: "+ix);
-                                       }
+                               int six = (sixpos >= 0) ? 
sblock.indexes(i)[sblock.pos(i) + sixpos] : -1;
+                               if(six != ix) {
+                                       Assert.fail("Wrong index returned by 
index probe (" + itype.toString() + "," + i + "): " +
+                                               six + ", expected: " + ix);
                                }
                        }
+
                }
                catch(Exception ex) {
                        ex.printStackTrace();
@@ -391,27 +380,4 @@ public class SparseBlockGetFirstIndex extends 
AutomatedTestBase
                return -1;
        }
 
-       private static int getFirstIxCol(double[][] A, int rix, int cix, 
IndexType type) {
-               if(type == IndexType.GT) {
-                       for(int j = rix + 1; j < rows; j++)
-                               if(A[j][cix] != 0)
-                                       return j;
-                       return -1;
-               }
-               else if(type == IndexType.GTE) {
-                       for(int j = rix; j < rows; j++)
-                               if(A[j][cix] != 0)
-                                       return j;
-                       return -1;
-               }
-               else if(type == IndexType.LTE) {
-                       for(int j = rix; j >= 0; j--)
-                               if(A[j][cix] != 0)
-                                       return j;
-                       return -1;
-               }
-
-               return -1;
-       }
-
 }
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetSet.java 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetSet.java
index bb284d34a4..2f357d3c8a 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetSet.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockGetSet.java
@@ -244,47 +244,47 @@ public class SparseBlockGetSet extends AutomatedTestBase
 
        @Test
        public void testSparseBlockMCSC1Bulk()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity1, InitType.BULK);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity1, 
InitType.BULK);
        }
 
        @Test
        public void testSparseBlockMCSC2Bulk()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity2, InitType.BULK);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity2, 
InitType.BULK);
        }
 
        @Test
        public void testSparseBlockMCSC3Bulk()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity3, InitType.BULK);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity3, 
InitType.BULK);
        }
 
        @Test
        public void testSparseBlockMCSC1Seq()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity1, InitType.SEQ_SET);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity1, 
InitType.SEQ_SET);
        }
 
        @Test
        public void testSparseBlockMCSC2Seq()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity2, InitType.SEQ_SET);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity2, 
InitType.SEQ_SET);
        }
 
        @Test
        public void testSparseBlockMCSC3Seq()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity3, InitType.SEQ_SET);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity3, 
InitType.SEQ_SET);
        }
 
        @Test
        public void testSparseBlockMCSC1Rand()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity1, InitType.RAND_SET);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity1, 
InitType.RAND_SET);
        }
 
        @Test
        public void testSparseBlockMCSC2Rand()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity2, InitType.RAND_SET);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity2, 
InitType.RAND_SET);
        }
 
        @Test
        public void testSparseBlockMCSC3Rand()  {
-               runSparseBlockGetSetColumnTest(SparseBlock.Type.MCSC, 
sparsity3, InitType.RAND_SET);
+               runSparseBlockGetSetTest(SparseBlock.Type.MCSC, sparsity3, 
InitType.RAND_SET);
        }
        
        private void runSparseBlockGetSetTest( SparseBlock.Type btype, double 
sparsity, InitType itype)
@@ -310,10 +310,6 @@ public class SparseBlockGetSet extends AutomatedTestBase
                                        case MCSC: sblock = new 
SparseBlockMCSC(rows, cols); break;
                                }
 
-                               if(sblock instanceof SparseBlockMCSC){
-
-                               }
-
                                if(itype == InitType.SEQ_SET) {
                                        for( int i=0; i<rows; i++ )
                                                for( int j=0; j<cols; j++ )
@@ -368,86 +364,4 @@ public class SparseBlockGetSet extends AutomatedTestBase
                }
        }
 
-       @SuppressWarnings("incomplete-switch")
-       private void runSparseBlockGetSetColumnTest(SparseBlock.Type btype, 
double sparsity, InitType itype)
-       {
-               try {
-                       //data generation
-                       double[][] A = getRandomMatrix(rows, cols, -10, 10, 
sparsity, 7654321);
-
-                       //init sparse block
-                       SparseBlockMCSC sblock = null;
-                       if(itype == InitType.BULK) {
-                               MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
-                               SparseBlock srtmp = mbtmp.getSparseBlock();
-                               switch(btype) {
-                                       case MCSC:
-                                               sblock = new 
SparseBlockMCSC(srtmp, cols);
-                                               break;
-                               }
-                       }
-                       else if(itype == InitType.SEQ_SET || itype == 
InitType.RAND_SET) {
-                               switch(btype) {
-                                       case MCSC:
-                                               sblock = new 
SparseBlockMCSC(rows, cols);
-                                               break;
-                               }
-
-                               if(itype == InitType.SEQ_SET) {
-                                       for(int i = 0; i < cols; i++)
-                                               for(int j = 0; j < rows; j++)
-                                                       sblock.append(j, i, 
A[j][i]);
-                               }
-                               else if(itype == InitType.RAND_SET) {
-                                       LongLongDoubleHashMap map = new 
LongLongDoubleHashMap();
-                                       for(int i = 0; i < cols; i++)
-                                               for(int j = 0; j < rows; j++)
-                                                       map.addValue(j, i, 
A[j][i]);
-                                       Iterator<ADoubleEntry> iter = 
map.getIterator();
-                                       while(iter.hasNext()) { //random hash 
order
-                                               ADoubleEntry e = iter.next();
-                                               int r = (int) e.getKey1();
-                                               int c = (int) e.getKey2();
-                                               sblock.set(r, c, e.value);
-                                       }
-                               }
-                       }
-
-                       //check basic meta data
-                       if(sblock.numCols() != cols)
-                               Assert.fail("Wrong number of cols: " + 
sblock.numCols() + ", expected: " + cols);
-
-                       //check for correct number of non-zeros
-                       int[] cnnz = new int[cols];
-                       int nnz = 0;
-                       for(int i = 0; i < cols; i++) {
-                               for(int j = 0; j < rows; j++)
-                                       cnnz[i] += (A[j][i] != 0) ? 1 : 0;
-                               nnz += cnnz[i];
-                       }
-                       if(nnz != sblock.size())
-                               Assert.fail("Wrong number of non-zeros: " + 
sblock.size() + ", expected: " + nnz);
-
-                       //check correct isEmpty return
-                       for(int i = 0; i < cols; i++)
-                               if(sblock.isEmpty(i) != (cnnz[i] == 0))
-                                       Assert.fail("Wrong isEmpty(col) result 
for row nnz: " + cnnz[i] + "(column: " + i + ")");
-
-                       //check correct values
-                       for(int i = 0; i < cols; i++)
-                               if(!sblock.isEmpty(i))
-                                       for(int j = 0; j < rows; j++) {
-                                               double tmp = sblock.get(j, i);
-                                               if(tmp != A[j][i])
-                                                       Assert.fail(
-                                                               "Wrong get 
value for cell (" + i + "," + j + "): " + tmp + ", expected: " + A[j][i]);
-                                       }
-
-               }
-               catch(Exception ex) {
-                       ex.printStackTrace();
-                       throw new RuntimeException(ex);
-               }
-       }
-
 }
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIndexRange.java
 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIndexRange.java
index 4a87f0d129..d51f9d1f6d 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIndexRange.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIndexRange.java
@@ -43,8 +43,6 @@ public class SparseBlockIndexRange extends AutomatedTestBase
        private final static int cols = 549;    
        private final static int cl = 245;
        private final static int cu = 425;
-       private final static int rl = 245;
-       private final static int ru = 525;
        private final static double sparsity1 = 0.12;
        private final static double sparsity2 = 0.22;
        private final static double sparsity3 = 0.32;
@@ -181,32 +179,32 @@ public class SparseBlockIndexRange extends 
AutomatedTestBase
 
        @Test
        public void testSparseBlockMCSC1Delete()  {
-               runSparseBlockIndexRangeColumnTest(SparseBlock.Type.MCSC, 
sparsity1, UpdateType.DELETE);
+               runSparseBlockIndexRangeTest(SparseBlock.Type.MCSC, sparsity1, 
UpdateType.DELETE);
        }
 
        @Test
        public void testSparseBlockMCSC2Delete()  {
-               runSparseBlockIndexRangeColumnTest(SparseBlock.Type.MCSC, 
sparsity2, UpdateType.DELETE);
+               runSparseBlockIndexRangeTest(SparseBlock.Type.MCSC, sparsity2, 
UpdateType.DELETE);
        }
 
        @Test
        public void testSparseBlockMCSC3Delete()  {
-               runSparseBlockIndexRangeColumnTest(SparseBlock.Type.MCSC, 
sparsity3, UpdateType.DELETE);
+               runSparseBlockIndexRangeTest(SparseBlock.Type.MCSC, sparsity3, 
UpdateType.DELETE);
        }
 
        @Test
        public void testSparseBlockMCSC1Insert()  {
-               runSparseBlockIndexRangeColumnTest(SparseBlock.Type.MCSC, 
sparsity1, UpdateType.INSERT);
+               runSparseBlockIndexRangeTest(SparseBlock.Type.MCSC, sparsity1, 
UpdateType.INSERT);
        }
 
        @Test
        public void testSparseBlockMCSC2Insert()  {
-               runSparseBlockIndexRangeColumnTest(SparseBlock.Type.MCSC, 
sparsity2, UpdateType.INSERT);
+               runSparseBlockIndexRangeTest(SparseBlock.Type.MCSC, sparsity2, 
UpdateType.INSERT);
        }
 
        @Test
        public void testSparseBlockMCSC3Insert()  {
-               runSparseBlockIndexRangeColumnTest(SparseBlock.Type.MCSC, 
sparsity3, UpdateType.INSERT);
+               runSparseBlockIndexRangeTest(SparseBlock.Type.MCSC, sparsity3, 
UpdateType.INSERT);
        }
        
        private void runSparseBlockIndexRangeTest( SparseBlock.Type btype, 
double sparsity, UpdateType utype)
@@ -278,64 +276,4 @@ public class SparseBlockIndexRange extends 
AutomatedTestBase
                }
        }
 
-       @SuppressWarnings("incomplete-switch")
-       private void runSparseBlockIndexRangeColumnTest(SparseBlock.Type btype, 
double sparsity, UpdateType utype) {
-               try {
-                       //data generation
-                       double[][] A = getRandomMatrix(rows, cols, -10, 10, 
sparsity, 456);
-
-                       //init sparse block
-                       SparseBlock sblock = null;
-                       MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
-                       SparseBlock srtmp = mbtmp.getSparseBlock();
-                       switch(btype) {
-                               case MCSC:
-                                       sblock = new SparseBlockMCSC(srtmp, 
cols);
-                                       break;
-                       }
-
-                       //delete range per row via set
-                       if(utype == UpdateType.DELETE) {
-                               for(int i = 0; i < cols; i++) {
-                                       sblock.deleteIndexRange(i, rl, ru);
-                                       for(int j = rl; j < ru; j++) {
-                                               A[j][i] = 0;  // Fill 
column-wise with zeros
-                                       }
-                               }
-                       }
-                       else if(utype == UpdateType.INSERT) {
-                               double[] vals = new double[ru - rl];
-                               for(int j = rl; j < ru; j++)
-                                       vals[j - rl] = j;
-                               for(int i = 0; i < cols; i++) {
-                                       sblock.setIndexRange(i, rl, ru, vals, 
0, ru - rl);
-                                       for(int j = rl; j < ru; j++) {
-                                               A[j][i] = vals[j - rl];  // 
Update the matrix column-wise
-                                       }
-                               }
-                       }
-
-                       //check for correct number of non-zeros
-                       int[] cnnz = new int[cols];
-                       int nnz = 0;
-                       for(int i = 0; i < cols; i++) {
-                               for(int j = 0; j < rows; j++)
-                                       cnnz[i] += (A[j][i] != 0) ? 1 : 0;
-                               nnz += cnnz[i];
-                       }
-                       if(nnz != sblock.size())
-                               Assert.fail("Wrong number of non-zeros: " + 
sblock.size() + ", expected: " + nnz);
-
-                       //check correct isEmpty return
-                       for(int i = 0; i < cols; i++)
-                               if(sblock.isEmpty(i) != (cnnz[i] == 0))
-                                       Assert.fail("Wrong isEmpty(col) result 
for row nnz: " + cnnz[i]);
-
-                       //TODO: Add 'check correct values', requires Iterator
-               }
-               catch(Exception ex) {
-                       ex.printStackTrace();
-                       throw new RuntimeException(ex);
-               }
-       }
 }
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIterator.java 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIterator.java
index 0039d5ac1e..736f981025 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIterator.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockIterator.java
@@ -172,6 +172,36 @@ public class SparseBlockIterator extends AutomatedTestBase 
{
                runSparseBlockIteratorTest(SparseBlock.Type.DCSR, sparsity3, 
true);
        }
 
+       @Test
+       public void testSparseBlockMCSC1Full() {
+               runSparseBlockIteratorTest(SparseBlock.Type.MCSC, sparsity1, 
false);
+       }
+
+       @Test
+       public void testSparseBlockMCSC2Full() {
+               runSparseBlockIteratorTest(SparseBlock.Type.MCSC, sparsity2, 
false);
+       }
+
+       @Test
+       public void testSparseBlockMCSC3Full() {
+               runSparseBlockIteratorTest(SparseBlock.Type.MCSC, sparsity3, 
false);
+       }
+
+       @Test
+       public void testSparseBlockMCSC1Partial() {
+               runSparseBlockIteratorTest(SparseBlock.Type.MCSC, sparsity1, 
true);
+       }
+
+       @Test
+       public void testSparseBlockMCSC2Partial() {
+               runSparseBlockIteratorTest(SparseBlock.Type.MCSC, sparsity2, 
true);
+       }
+
+       @Test
+       public void testSparseBlockMCSC3Partial() {
+               runSparseBlockIteratorTest(SparseBlock.Type.MCSC, sparsity3, 
true);
+       }
+
        private void runSparseBlockIteratorTest(SparseBlock.Type btype, double 
sparsity, boolean partial) {
                try {
                        //data generation
@@ -181,7 +211,7 @@ public class SparseBlockIterator extends AutomatedTestBase {
                        MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
                        SparseBlock srtmp = mbtmp.getSparseBlock();
                        SparseBlock sblock = 
SparseBlockFactory.copySparseBlock(btype, srtmp, true);
-                       
+
                        //check for correct number of non-zeros
                        int[] rnnz = new int[rows];
                        int nnz = 0;
@@ -215,9 +245,9 @@ public class SparseBlockIterator extends AutomatedTestBase {
                        // check iterator over non-zero rows
                        List<Integer> manualNonZeroRows = new ArrayList<>();
                        List<Integer> iteratorNonZeroRows = new ArrayList<>();
-                       Iterator<Integer> iterRows = !partial ?
-                               sblock.getNonEmptyRowsIterator(0, rows) :
-                               sblock.getNonEmptyRowsIterator(rl, rows);
+                       Iterator<Integer> iterRows = !partial
+                               ? sblock.getNonEmptyRowsIterator(0, rows)
+                               : sblock.getNonEmptyRowsIterator(rl, rows);
 
                        for(int i = rl; i < rows; i++)
                                if(!sblock.isEmpty(i))
@@ -230,6 +260,7 @@ public class SparseBlockIterator extends AutomatedTestBase {
                        if(!manualNonZeroRows.equals(iteratorNonZeroRows)) {
                                Assert.fail("Verification of iterator over 
non-zero rows failed.");
                        }
+
                }
                catch(Exception ex) {
                        ex.printStackTrace();
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMemEstimate.java
 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMemEstimate.java
index 36dc077fb0..1c0c2aa7c5 100644
--- 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMemEstimate.java
+++ 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMemEstimate.java
@@ -98,7 +98,7 @@ public class SparseBlockMemEstimate extends AutomatedTestBase
                }
                else { //ultra-sparse (pref COO)
                        if( memMCSC < memCOO )
-                               Assert.fail("SparseBlockMCS memory estimate 
smaller than SparseBlockCOO estimate.");
+                               Assert.fail("SparseBlockMCSC memory estimate 
smaller than SparseBlockCOO estimate.");
                        if( memMCSR < memCOO )
                                Assert.fail("SparseBlockMCSR memory estimate 
smaller than SparseBlockCOO estimate.");
                        if( memCSR < memCOO )
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMerge.java 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMerge.java
index e5681e294e..7c061eaf27 100644
--- a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMerge.java
+++ b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockMerge.java
@@ -122,6 +122,26 @@ public class SparseBlockMerge extends AutomatedTestBase
        public void testMergeMCSR_DCSR_3()  {
                runSparseBlockMergeTest(SparseBlock.Type.MCSR, 
SparseBlock.Type.DCSR, sparsity3);
        }
+
+       @Test
+       public void testMergeMCSR_MCSC_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSR, 
SparseBlock.Type.MCSC, sparsity0);
+       }
+
+       @Test
+       public void testMergeMCSR_MCSC_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSR, 
SparseBlock.Type.MCSC, sparsity1);
+       }
+
+       @Test
+       public void testMergeMCSR_MCSC_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSR, 
SparseBlock.Type.MCSC, sparsity2);
+       }
+
+       @Test
+       public void testMergeMCSR_MCSC_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSR, 
SparseBlock.Type.MCSC, sparsity3);
+       }
        
        @Test
        public void testMergeCSR_CSR_0()  {
@@ -202,6 +222,26 @@ public class SparseBlockMerge extends AutomatedTestBase
        public void testMergeCSR_COO_3()  {
                runSparseBlockMergeTest(SparseBlock.Type.CSR, 
SparseBlock.Type.COO, sparsity3);
        }
+
+       @Test
+       public void testMergeCSR_MCSC_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.CSR, 
SparseBlock.Type.MCSC, sparsity0);
+       }
+
+       @Test
+       public void testMergeCSR_MCSC_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.CSR, 
SparseBlock.Type.MCSC, sparsity1);
+       }
+
+       @Test
+       public void testMergeCSR_MCSC_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.CSR, 
SparseBlock.Type.MCSC, sparsity2);
+       }
+
+       @Test
+       public void testMergeCSR_MCSC_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.CSR, 
SparseBlock.Type.MCSC, sparsity3);
+       }
        
        @Test
        public void testMergeCOO_COO_0()  {
@@ -283,6 +323,26 @@ public class SparseBlockMerge extends AutomatedTestBase
                runSparseBlockMergeTest(SparseBlock.Type.COO, 
SparseBlock.Type.DCSR, sparsity3);
        }
 
+       @Test
+       public void testMergeCOO_MCSC_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.COO, 
SparseBlock.Type.MCSC, sparsity0);
+       }
+
+       @Test
+       public void testMergeCOO_MCSC_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.COO, 
SparseBlock.Type.MCSC, sparsity1);
+       }
+
+       @Test
+       public void testMergeCOO_MCSC_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.COO, 
SparseBlock.Type.MCSC, sparsity2);
+       }
+
+       @Test
+       public void testMergeCOO_MCSC_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.COO, 
SparseBlock.Type.MCSC, sparsity3);
+       }
+
        @Test
        public void testMergeDCSR_DCSR_0()  {
                runSparseBlockMergeTest(SparseBlock.Type.DCSR, 
SparseBlock.Type.DCSR, sparsity0);
@@ -363,7 +423,108 @@ public class SparseBlockMerge extends AutomatedTestBase
                runSparseBlockMergeTest(SparseBlock.Type.DCSR, 
SparseBlock.Type.COO, sparsity3);
        }
 
-       
+       @Test
+       public void testMergeDCSR_MCSC_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.DCSR, 
SparseBlock.Type.MCSC, sparsity0);
+       }
+
+       @Test
+       public void testMergeDCSR_MCSC_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.DCSR, 
SparseBlock.Type.MCSC, sparsity1);
+       }
+
+       @Test
+       public void testMergeDCSR_MCSC_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.DCSR, 
SparseBlock.Type.MCSC, sparsity2);
+       }
+
+       @Test
+       public void testMergeDCSR_MCSC_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.DCSR, 
SparseBlock.Type.MCSC, sparsity3);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSC_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSC, sparsity0);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSC_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSC, sparsity1);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSC_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSC, sparsity2);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSC_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSC, sparsity3);
+       }
+
+       @Test
+       public void testMergeMCSC_CSR_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.CSR, sparsity0);
+       }
+
+       @Test
+       public void testMergeMCSC_CSR_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.CSR, sparsity1);
+       }
+
+       @Test
+       public void testMergeMCSC_CSR_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.CSR, sparsity2);
+       }
+
+       @Test
+       public void testMergeMCSC_CSR_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.CSR, sparsity3);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSR_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSR, sparsity0);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSR_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSR, sparsity1);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSR_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSR, sparsity2);
+       }
+
+       @Test
+       public void testMergeMCSC_MCSR_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.MCSR, sparsity3);
+       }
+
+       @Test
+       public void testMergeMCSC_COO_0()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.COO, sparsity0);
+       }
+
+       @Test
+       public void testMergeMCSC_COO_1()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.COO, sparsity1);
+       }
+
+       @Test
+       public void testMergeMCSC_COO_2()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.COO, sparsity2);
+       }
+
+       @Test
+       public void testMergeMCSC_COO_3()  {
+               runSparseBlockMergeTest(SparseBlock.Type.MCSC, 
SparseBlock.Type.COO, sparsity3);
+       }
+
+
+
        private void runSparseBlockMergeTest( SparseBlock.Type btype1, 
SparseBlock.Type btype2, double sparsity)
        {
                try
@@ -387,8 +548,8 @@ public class SparseBlockMerge extends AutomatedTestBase
                        MatrixBlock mb1 = 
DataConverter.convertToMatrixBlock(B1);
                        MatrixBlock mb2 = 
DataConverter.convertToMatrixBlock(B2);
                        long nnz = mb1.getNonZeros() + mb2.getNonZeros();
-                       
mb1.setSparseBlock(SparseBlockFactory.copySparseBlock(btype1, 
mb1.getSparseBlock(), false));
-                       
mb2.setSparseBlock(SparseBlockFactory.copySparseBlock(btype2, 
mb2.getSparseBlock(), false));
+                       
mb1.setSparseBlock(SparseBlockFactory.copySparseBlock(btype1, 
mb1.getSparseBlock(), false, cols));
+                       
mb2.setSparseBlock(SparseBlockFactory.copySparseBlock(btype2, 
mb2.getSparseBlock(), false, cols));
                        
                        //execute merge
                        mb1 = mb1.merge(mb2, false);
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockScan.java 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockScan.java
index 98fe32792e..8163b49a6e 100644
--- a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockScan.java
+++ b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockScan.java
@@ -142,48 +142,32 @@ public class SparseBlockScan extends AutomatedTestBase
                        
                        //check for correct number of non-zeros
                        int[] rnnz = new int[rows]; int nnz = 0;
-                       int[] cnnz = new int[cols];
-                       for( int i=0; i<rows; i++ ) {
-                               for( int j=0; j<cols; j++ ) {
+                       for(int i = 0; i < rows; i++) {
+                               for(int j = 0; j < cols; j++)
                                        rnnz[i] += (A[i][j] != 0) ? 1 : 0;
-                                       cnnz[j] += (A[i][j] != 0) ? 1 : 0;
-                               }
                                nnz += rnnz[i];
                        }
-                       if( nnz != sblock.size() )
-                               Assert.fail("Wrong number of non-zeros: 
"+sblock.size()+", expected: "+nnz);
-               
+
+                       if(nnz != sblock.size())
+                               Assert.fail("Wrong number of non-zeros: " + 
sblock.size() + ", expected: " + nnz);
+
                        //check correct isEmpty return
-                       if(sblock instanceof SparseBlockMCSC) {
-                               for(int i = 0; i < cols; i++)
-                                       if(sblock.isEmpty(i) != (cnnz[i] == 0))
-                                               Assert.fail("Wrong isEmpty(col) 
result for column nnz: " + cnnz[i]);
-                       }
-                       else {
-                               for(int i = 0; i < rows; i++)
-                                       if(sblock.isEmpty(i) != (rnnz[i] == 0))
-                                               Assert.fail("Wrong isEmpty(row) 
result for row nnz: " + rnnz[i]);
-                       }
-               
+                       for(int i = 0; i < rows; i++)
+                               if(sblock.isEmpty(i) != (rnnz[i] == 0))
+                                       Assert.fail("Wrong isEmpty(row) result 
for row nnz: " + rnnz[i]);
+
                        //check correct values
-                       int limit = rows;
-                       if(sblock instanceof SparseBlockMCSC)
-                               limit = cols;
                        int count = 0;
-                       for( int i=0; i<limit; i++) {
+                       for(int i = 0; i < rows; i++) {
                                int alen = sblock.size(i);
                                int apos = sblock.pos(i);
                                int[] aix = sblock.indexes(i);
                                double[] avals = sblock.values(i);
-                               for( int j=0; j<alen; j++ ) {
-                                       if(sblock instanceof SparseBlockMCSC){
-                                               if( avals[apos+j] != 
A[aix[apos+j]][i] )
-                                                       Assert.fail("Wrong 
value returned by scan: "+avals[apos+j]+", expected: "+A[i][apos+aix[j]]);
-                                       } else {
-                                               if( avals[apos+j] != 
A[i][aix[apos+j]] )
-                                                       Assert.fail("Wrong 
value returned by scan: "+avals[apos+j]+", expected: "+A[i][apos+aix[j]]);
-                                       }
-                                       count++;                
+                               for(int j = 0; j < alen; j++) {
+                                       if(avals[apos + j] != A[i][aix[apos + 
j]])
+                                               Assert.fail(
+                                                       "Wrong value returned 
by scan: " + avals[apos + j] + ", expected: " + A[i][apos + aix[j]]);
+                                       count++;
                                }
                        }
                        if( count != nnz )
diff --git 
a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockSize.java 
b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockSize.java
index 0a917a9d65..edc84098ca 100644
--- a/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockSize.java
+++ b/src/test/java/org/apache/sysds/test/component/sparse/SparseBlockSize.java
@@ -36,15 +36,15 @@ import org.apache.sysds.test.TestUtils;
  */
 public class SparseBlockSize extends AutomatedTestBase 
 {
-       private final static int rows = 324;
-       private final static int cols = 123;
-       private final static int rl = 31;
-       private final static int ru = 100;
-       private final static int cl = 30;
-       private final static int cu = 80;
-       private final static double sparsity1 = 0.12;
-       private final static double sparsity2 = 0.22;
-       private final static double sparsity3 = 0.32;
+       private final static int _rows = 324;
+       private final static int _cols = 123;
+       private final static int _rl = 31;
+       private final static int _ru = 100;
+       private final static int _cl = 30;
+       private final static int _cu = 80;
+       private final static double _sparsity1 = 0.12;
+       private final static double _sparsity2 = 0.22;
+       private final static double _sparsity3 = 0.32;
        
        @Override
        public void setUp() {
@@ -53,154 +53,190 @@ public class SparseBlockSize extends AutomatedTestBase
        
        @Test
        public void testSparseBlockMCSR1()  {
-               runSparseBlockSizeTest(SparseBlock.Type.MCSR, sparsity1);
+               runSparseBlockSizeTest(SparseBlock.Type.MCSR, _sparsity1);
        }
        
        @Test
        public void testSparseBlockMCSR2()  {
-               runSparseBlockSizeTest(SparseBlock.Type.MCSR, sparsity2);
+               runSparseBlockSizeTest(SparseBlock.Type.MCSR, _sparsity2);
        }
        
        @Test
        public void testSparseBlockMCSR3()  {
-               runSparseBlockSizeTest(SparseBlock.Type.MCSR, sparsity3);
+               runSparseBlockSizeTest(SparseBlock.Type.MCSR, _sparsity3);
        }
        
        @Test
        public void testSparseBlockCSR1()  {
-               runSparseBlockSizeTest(SparseBlock.Type.CSR, sparsity1);
+               runSparseBlockSizeTest(SparseBlock.Type.CSR, _sparsity1);
        }
        
        @Test
        public void testSparseBlockCSR2()  {
-               runSparseBlockSizeTest(SparseBlock.Type.CSR, sparsity2);
+               runSparseBlockSizeTest(SparseBlock.Type.CSR, _sparsity2);
        }
        
        @Test
        public void testSparseBlockCSR3()  {
-               runSparseBlockSizeTest(SparseBlock.Type.CSR, sparsity3);
+               runSparseBlockSizeTest(SparseBlock.Type.CSR, _sparsity3);
        }
        
        @Test
        public void testSparseBlockCOO1()  {
-               runSparseBlockSizeTest(SparseBlock.Type.COO, sparsity1);
+               runSparseBlockSizeTest(SparseBlock.Type.COO, _sparsity1);
        }
        
        @Test
        public void testSparseBlockCOO2()  {
-               runSparseBlockSizeTest(SparseBlock.Type.COO, sparsity2);
+               runSparseBlockSizeTest(SparseBlock.Type.COO, _sparsity2);
        }
        
        @Test
        public void testSparseBlockCOO3()  {
-               runSparseBlockSizeTest(SparseBlock.Type.COO, sparsity3);
+               runSparseBlockSizeTest(SparseBlock.Type.COO, _sparsity3);
        }
 
        @Test
        public void testSparseBlockDCSR1()  {
-               runSparseBlockSizeTest(SparseBlock.Type.DCSR, sparsity1);
+               runSparseBlockSizeTest(SparseBlock.Type.DCSR, _sparsity1);
        }
 
        @Test
        public void testSparseBlockDCSR2()  {
-               runSparseBlockSizeTest(SparseBlock.Type.DCSR, sparsity2);
+               runSparseBlockSizeTest(SparseBlock.Type.DCSR, _sparsity2);
        }
 
        @Test
        public void testSparseBlockDCSR3()  {
-               runSparseBlockSizeTest(SparseBlock.Type.DCSR, sparsity3);
+               runSparseBlockSizeTest(SparseBlock.Type.DCSR, _sparsity3);
        }
 
        @Test
        public void testSparseBlockMCSC1(){
-               runSparseBlockSizeTest(SparseBlock.Type.MCSC, sparsity1);
+               runSparseBlockSizeTest(SparseBlock.Type.MCSC, _sparsity1);
        }
 
        @Test
        public void testSparseBlockMCSC2(){
-               runSparseBlockSizeTest(SparseBlock.Type.MCSC, sparsity2);
+               runSparseBlockSizeTest(SparseBlock.Type.MCSC, _sparsity2);
        }
 
        @Test
        public void testSparseBlockMCSC3(){
-               runSparseBlockSizeTest(SparseBlock.Type.MCSC, sparsity3);
+               runSparseBlockSizeTest(SparseBlock.Type.MCSC, _sparsity3);
+       }
+       
+       @Test
+       public void testSparseBlockMCSRFixed1(){
+               double[][] A = getFixedData1();
+               runSparseBlockSizeTest(A, 0, 4, 0, 6, SparseBlock.Type.MCSR);
+       }
+       
+       @Test
+       public void testSparseBlockCSRFixed1(){
+               double[][] A = getFixedData1();
+               runSparseBlockSizeTest(A, 0, 4, 0, 6, SparseBlock.Type.CSR);
+       }
+       
+       @Test
+       public void testSparseBlockCOOFixed1(){
+               double[][] A = getFixedData1();
+               runSparseBlockSizeTest(A, 0, 4, 0, 6, SparseBlock.Type.COO);
+       }
+       
+       @Test
+       public void testSparseBlockMCSRFixed2(){
+               double[][] A = getFixedData2();
+               runSparseBlockSizeTest(A, 0, 4, 2, 4, SparseBlock.Type.MCSR);
+       }
+       
+       @Test
+       public void testSparseBlockCSRFixed2(){
+               double[][] A = getFixedData2();
+               runSparseBlockSizeTest(A, 0, 4, 2, 4, SparseBlock.Type.CSR);
+       }
+       
+       @Test
+       public void testSparseBlockCOOFixed2(){
+               double[][] A = getFixedData2();
+               runSparseBlockSizeTest(A, 0, 4, 2, 4, SparseBlock.Type.COO);
+       }
+       
+       @Test
+       public void testSparseBlockMCSRFixed3(){
+               double[][] A = getFixedData3();
+               runSparseBlockSizeTest(A, 0, 4, 3, 3, SparseBlock.Type.MCSR);
+       }
+       
+       @Test
+       public void testSparseBlockCSRFixed3(){
+               double[][] A = getFixedData3();
+               runSparseBlockSizeTest(A, 0, 4, 3, 3, SparseBlock.Type.CSR);
+       }
+       
+       @Test
+       public void testSparseBlockCOOFixed3(){
+               double[][] A = getFixedData3();
+               runSparseBlockSizeTest(A, 0, 4, 3, 3, SparseBlock.Type.COO);
+       }
+       
+       private void runSparseBlockSizeTest(SparseBlock.Type btype, double 
sparsity) {
+               double[][] A = getRandomMatrix(_rows, _cols, -10, 10, sparsity, 
123); 
+               runSparseBlockSizeTest(A, _rl, _ru, _cl, _cu, btype);
        }
 
-       private void runSparseBlockSizeTest( SparseBlock.Type btype, double 
sparsity)
+       private void runSparseBlockSizeTest(double[][] A,
+               int rl, int ru, int cl, int cu, SparseBlock.Type btype)
        {
                try
                {
-                       //data generation
-                       double[][] A = getRandomMatrix(rows, cols, -10, 10, 
sparsity, 123); 
-                       
                        //init sparse block
                        SparseBlock sblock = null;
                        MatrixBlock mbtmp = 
DataConverter.convertToMatrixBlock(A);
+                       int rows= mbtmp.getNumRows();
+                       int cols= mbtmp.getNumColumns();
+                       if( !mbtmp.isInSparseFormat() )
+                               mbtmp.denseToSparse(true);
                        SparseBlock srtmp = mbtmp.getSparseBlock();
                        switch( btype ) {
                                case MCSR: sblock = new SparseBlockMCSR(srtmp); 
break;
                                case CSR: sblock = new SparseBlockCSR(srtmp); 
break;
                                case COO: sblock = new SparseBlockCOO(srtmp); 
break;
                                case DCSR: sblock = new SparseBlockDCSR(srtmp); 
break;
-                               case MCSC: sblock = new SparseBlockMCSC(srtmp); 
break;
+                               case MCSC: sblock = new SparseBlockMCSC(srtmp, 
cols); break;
                        }
                        
                        //prepare summary statistics nnz
                        int[] rnnz = new int[rows];
-                       int[] cnnz = new int[cols];
                        int nnz = 0;
                        int nnz2 = 0;
                        for( int i=0; i<rows; i++ ) {
                                for( int j=0; j<cols; j++ ) {
-                                       cnnz[j] += (A[i][j]!=0) ? 1 : 0;
                                        rnnz[i] += (A[i][j]!=0) ? 1 : 0;
-                                       nnz2 += (i>=rl && j>=cl && i<ru && j<cu 
&& A[i][j]!=0) ? 1 : 0;
+                                       nnz2 += (i >= rl && j >= cl && i < ru 
&& j < cu && A[i][j] != 0) ? 1 : 0;
                                }
                                nnz += rnnz[i];
                        }
-                       
+
                        //check full block nnz
-                       if( nnz != sblock.size() )
-                               Assert.fail("Wrong number of non-zeros: 
"+sblock.size()+", expected: "+nnz);
+                       if(nnz != sblock.size())
+                               Assert.fail("Wrong number of non-zeros: " + 
sblock.size() + ", expected: " + nnz);
 
                        //check row nnz
-                       //for MCSC we check columns
-                       if(sblock instanceof SparseBlockMCSC) {
-                               for(int i = 0; i < cols; i++)
-                                       if(sblock.size(i) != cnnz[i]) {
-                                               Assert.fail("Wrong number of 
column non-zeros (" + i + "): " + sblock.size(i) + ", expected: " +
-                                                       cnnz[i]);
-                                       }
-                       }
-                       else {
-                               for(int i = 0; i < rows; i++)
-                                       if(sblock.size(i) != rnnz[i]) {
-                                               Assert.fail(
-                                                       "Wrong number of row 
non-zeros (" + i + "): " + sblock.size(i) + ", expected: " + rnnz[i]);
-                                       }
-                       }
+                       for(int i = 0; i < rows; i++)
+                               if(sblock.size(i) != rnnz[i])
+                                       Assert.fail("Wrong number of row 
non-zeros (" + i + "): " + sblock.size(i) + ", expected: " + rnnz[i]);
+
+                       //check two row nnz
+                       for(int i = 1; i < rows; i++)
+                               if(sblock.size(i - 1, i + 1) != rnnz[i - 1] + 
rnnz[i]) {
+                                       Assert.fail("Wrong number of row block 
non-zeros (" + (i - 1) + "," + (i + 1) + "): " +
+                                               sblock.size(i - 1, i + 1) + ", 
expected: " + rnnz[i - 1] + rnnz[i]);
+                               }
 
-                       //check for two column nnz
-                       if(sblock instanceof SparseBlockMCSC) {
-                               for(int i = 1; i < cols; i++)
-                                       if(sblock.size(i - 1, i + 1) != cnnz[i 
- 1] + cnnz[i]) {
-                                               Assert.fail("Wrong number of 
column block non-zeros (" + (i - 1) + "," + (i + 1) + "): " +
-                                                       sblock.size(i - 1, i + 
1) + ", expected: " + cnnz[i - 1] + cnnz[i]);
-                                       }
-                       }
-                       else {
-                               //check two row nnz
-                               for(int i = 1; i < rows; i++)
-                                       if(sblock.size(i - 1, i + 1) != rnnz[i 
- 1] + rnnz[i]) {
-                                               Assert.fail("Wrong number of 
row block non-zeros (" + (i - 1) + "," + (i + 1) + "): " +
-                                                       sblock.size(i - 1, i + 
1) + ", expected: " + rnnz[i - 1] + rnnz[i]);
-                                       }
-                       }
-                       
                        //check index range nnz
-                       if( sblock.size(rl, ru, cl, cu) != nnz2 )
-                               Assert.fail("Wrong number of range non-zeros: " 
+
-                                               sblock.size(rl, ru, cl, cu)+", 
expected: "+nnz2);
+                       if(sblock.size(rl, ru, cl, cu) != nnz2)
+                               Assert.fail("Wrong number of range non-zeros: " 
+ sblock.size(rl, ru, cl, cu) + ", expected: " + nnz2);
 
                }
                catch(Exception ex) {
@@ -208,4 +244,28 @@ public class SparseBlockSize extends AutomatedTestBase
                        throw new RuntimeException(ex);
                }
        }
+       
+       private double[][] getFixedData1(){
+               return new double[][]
+                       {{10, 20, 0, 0, 0, 0},
+                       {0, 30, 0, 40, 0, 0},
+                       {0, 0, 50, 60, 70, 0},
+                       {0, 0, 0, 0, 0, 80}};
+       }
+       
+       private double[][] getFixedData2(){
+               return new double[][]
+                       {{10, 10, 0, 0, 0, 20},
+                       {10, 10, 0, 0, 0, 20},
+                       {10, 10, 0, 0, 0, 20},
+                       {10, 10, 0, 0, 0, 20}};
+       }
+       
+       private double[][] getFixedData3(){
+               return new double[][]
+                       {{10, 10, 0, 15, 0, 20},
+                       {10, 10, 0, 15, 0, 20},
+                       {10, 10, 0, 15, 0, 20},
+                       {10, 10, 0, 15, 0, 20}};
+       }
 }

Reply via email to