Merge pull request #4 from DataSketches/remove_mtj

Remove MTJ code
diff --git a/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOps.java b/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOps.java
index 078f4b9..b0dfcf1 100644
--- a/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOps.java
+++ b/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOps.java
@@ -52,10 +52,6 @@
         mo = new MatrixOpsImplOjAlgo(n, d, algo, k);
         break;
 
-      case MTJ:
-        mo = new MatrixOpsImplMTJ(n, d, algo, k);
-        break;
-
       default:
         throw new IllegalArgumentException("Unknown MatrixType: " + A.getMatrixType().toString());
     }
diff --git a/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOpsImplMTJ.java b/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOpsImplMTJ.java
deleted file mode 100644
index eebf1f9..0000000
--- a/src/main/java/com/yahoo/sketches/vector/decomposition/MatrixOpsImplMTJ.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Portions derived from LGPL'd Matrix Toolkit for Java:
- * https://github.com/fommil/matrix-toolkits-java/blob/master/src/main/java/no/uib/cipr/matrix/SVD.java
- */
-
-package com.yahoo.sketches.vector.decomposition;
-
-import java.util.concurrent.ThreadLocalRandom;
-
-import org.netlib.util.intW;
-
-import com.github.fommil.netlib.BLAS;
-import com.github.fommil.netlib.LAPACK;
-import com.yahoo.sketches.vector.matrix.Matrix;
-import com.yahoo.sketches.vector.matrix.MatrixImplMTJ;
-import com.yahoo.sketches.vector.matrix.MatrixType;
-import no.uib.cipr.matrix.DenseMatrix;
-import no.uib.cipr.matrix.MatrixEntry;
-import no.uib.cipr.matrix.NotConvergedException;
-import no.uib.cipr.matrix.QR;
-import no.uib.cipr.matrix.SVD;
-import no.uib.cipr.matrix.SymmDenseEVD;
-import no.uib.cipr.matrix.UpperSymmDenseMatrix;
-import no.uib.cipr.matrix.sparse.CompDiagMatrix;
-import no.uib.cipr.matrix.sparse.LinkedSparseMatrix;
-
-/**
- * Computes singular value decompositions
- */
-class MatrixOpsImplMTJ extends MatrixOps {
-
-  /**
-   * The singular values
-   */
-  private final double[] sv_;
-
-  /**
-   * Singular vectors, sparse version of singular value matrix
-   */
-  private DenseMatrix Vt_;
-  private CompDiagMatrix S_;
-
-  /**
-   * Work arrays for full SVD
-   */
-  private double[] work_;
-  private int[] iwork_;
-
-  /**
-   * Work arrays for SISVD
-   */
-  private DenseMatrix block_;
-  private DenseMatrix T_;
-
-  /**
-   * Work objects for SymmEVD
-   */
-  private SymmDenseEVD evd_;
-  private LinkedSparseMatrix rotS_;
-
-  /**
-   * Creates an empty MatrixOps
-   *
-   * @param n Number of rows in matrix
-   * @param d Number of columns in matrix
-   * @param algo SVD algorithm to apply
-   * @param k Target number of dimensions for any reduction operations
-   */
-  //MatrixOpsImplMTJ(final MatrixImplMTJ A, final SVDAlgo algo, final int k) {
-  MatrixOpsImplMTJ(final int n, final int d, final SVDAlgo algo, final int k) {
-    super(n, d, algo, k);
-
-    // Allocate space for the decomposition
-    sv_ = new double[Math.min(n_, d_)];
-    Vt_ = null; // lazy allocation
-  }
-
-  @Override
-  void svd(final Matrix A, final boolean computeVectors) {
-    assert A.getMatrixType() == MatrixType.MTJ;
-
-    if (A.getNumRows() != n_) {
-      throw new IllegalArgumentException("A.numRows() != n_");
-    } else if (A.getNumColumns() != d_) {
-      throw new IllegalArgumentException("A.numColumns() != d_");
-    }
-
-    if (computeVectors && Vt_ == null) {
-      Vt_ = new DenseMatrix(n_, d_);
-
-      final int[] diag = {0}; // only need the main diagonal
-      S_ = new CompDiagMatrix(n_, n_, diag);
-    }
-
-    switch (algo_) {
-      case FULL:
-        // make a copy if not computing vectors to avoid changing the data
-        final DenseMatrix mtx = computeVectors ? (DenseMatrix) A.getRawObject()
-                : new DenseMatrix((DenseMatrix) A.getRawObject());
-        computeFullSVD(mtx, computeVectors);
-        return;
-
-      case SISVD:
-        computeSISVD((DenseMatrix) A.getRawObject(), computeVectors);
-        return;
-
-      case SYM:
-        computeSymmEigSVD((DenseMatrix) A.getRawObject(), computeVectors);
-        return;
-
-      default:
-        throw new RuntimeException("SVDAlgo type not (yet?) supported: " + algo_.toString());
-    }
-  }
-
-  // Because exact SVD destroys A, need to reconstruct it for MTJ
-  @Override
-  public double[] getSingularValues(final Matrix A) {
-    svd(A, false);
-    return getSingularValues();
-  }
-
-  @Override
-  public double[] getSingularValues() {
-    return sv_;
-  }
-
-  @Override
-  Matrix getVt() {
-    return MatrixImplMTJ.wrap(Vt_);
-  }
-
-  @Override
-  double reduceRank(final Matrix A) {
-    svd(A, true);
-
-    double svAdjustment = 0.0;
-    S_.zero();
-
-    if (sv_.length >= k_) {
-      double medianSVSq = sv_[k_ - 1]; // (l_/2)th item, not yet squared
-      medianSVSq *= medianSVSq;
-      svAdjustment += medianSVSq; // always track, even if not using compensative mode
-      for (int i = 0; i < k_ - 1; ++i) {
-        final double val = sv_[i];
-        final double adjSqSV = val * val - medianSVSq;
-        S_.set(i, i, adjSqSV < 0 ? 0.0 : Math.sqrt(adjSqSV));
-      }
-      for (int i = k_ - 1; i < S_.numColumns(); ++i) {
-        S_.set(i, i, 0.0);
-      }
-      //nextZeroRow_ = k_;
-    } else {
-      for (int i = 0; i < sv_.length; ++i) {
-        S_.set(i, i, sv_[i]);
-      }
-      for (int i = sv_.length; i < S_.numColumns(); ++i) {
-        S_.set(i, i, 0.0);
-      }
-      //nextZeroRow_ = sv_.length;
-      throw new RuntimeException("Running with d < 2k not yet supported");
-    }
-
-    // store the result back in A
-    S_.mult(Vt_, (DenseMatrix) A.getRawObject());
-
-    return svAdjustment;
-  }
-
-  @Override
-  Matrix applyAdjustment(final Matrix A, final double svAdjustment) {
-    // copy A before decomposing
-    final DenseMatrix result = new DenseMatrix((DenseMatrix) A.getRawObject(), true);
-    svd(Matrix.wrap(result), true);
-
-    for (int i = 0; i < k_ - 1; ++i) {
-      final double val = sv_[i];
-      final double adjSV = Math.sqrt(val * val + svAdjustment);
-      S_.set(i, i, adjSV);
-    }
-    for (int i = k_ - 1; i < S_.numColumns(); ++i) {
-      S_.set(i, i, 0.0);
-    }
-
-    S_.mult(Vt_, result);
-
-    return Matrix.wrap(result);
-  }
-
-  private void allocateSpaceFullSVD(final boolean vectors) {
-    // Find workspace requirements
-    iwork_ = new int[8 * Math.min(n_, d_)];
-
-    // Query optimal workspace
-    final double[] workSize = new double[1];
-    final intW info = new intW(0);
-    LAPACK.getInstance().dgesdd("S", n_, d_, new double[0],
-            n_, new double[0], new double[0], n_,
-            new double[0], n_, workSize, -1, iwork_, info);
-
-    // Allocate workspace
-    int lwork;
-    if (info.val != 0) {
-      if (vectors) {
-        lwork = 3
-                * Math.min(n_, d_)
-                * Math.min(n_, d_)
-                + Math.max(
-                Math.max(n_, d_),
-                4 * Math.min(n_, d_) * Math.min(n_, d_) + 4
-                        * Math.min(n_, d_));
-      } else {
-        lwork = 3
-                * Math.min(n_, d_)
-                * Math.min(n_, d_)
-                + Math.max(
-                Math.max(n_, d_),
-                5 * Math.min(n_, d_) * Math.min(n_, d_) + 4
-                        * Math.min(n_, d_));
-      }
-    } else {
-      lwork = (int) workSize[0];
-    }
-
-    lwork = Math.max(lwork, 1);
-    work_ = new double[lwork];
-  }
-
-  private void allocateSpaceSISVD() {
-    block_ = new DenseMatrix(d_, k_);
-    T_ = new DenseMatrix(n_, k_);
-    // TODO: should allocate space for QR and final SVD here?
-  }
-
-  private void allocateSpaceSymmEigSVD() {
-    T_ = new DenseMatrix(n_, n_);
-    rotS_ = new LinkedSparseMatrix(n_, n_); // only need if computing vectors, but only O(n_) size
-    evd_ = new SymmDenseEVD(n_, true, true);
-  }
-
-  private void computeFullSVD(final DenseMatrix A, final boolean computeVectors) {
-    if (work_ == null) {
-      allocateSpaceFullSVD(computeVectors);
-    }
-
-    final intW info = new intW(0);
-    final String jobType = computeVectors ? "S" : "N";
-    LAPACK.getInstance().dgesdd(jobType, n_, d_, A.getData(),
-            n_, sv_, new double[0],
-            n_, computeVectors ? Vt_.getData() : new double[0],
-            n_, work_, work_.length, iwork_, info);
-
-    if (info.val > 0) {
-      throw new RuntimeException("Did not converge after a maximum number of iterations");
-    } else if (info.val < 0) {
-      throw new IllegalArgumentException();
-    }
-  }
-
-  private void computeSISVD(final DenseMatrix A, final boolean computeVectors) {
-    if (block_ == null) {
-      allocateSpaceSISVD();
-    }
-
-    // want block_ filled as ~Normal(0,1))
-    final ThreadLocalRandom rand = ThreadLocalRandom.current();
-    for (MatrixEntry entry : block_) {
-      entry.set(rand.nextGaussian());
-    }
-    // TODO: in-line QR with direct LAPACK call
-    final QR qr = new QR(block_.numRows(), block_.numColumns());
-    block_ = qr.factor(block_).getQ(); // important for numeric stability
-
-    for (int i = 0; i < numSISVDIter_; ++i) {
-      A.mult(block_, T_);
-      A.transAmult(T_, block_);
-      block_ = qr.factor(block_).getQ(); // again, for stability
-    }
-
-    // Rayleigh-Ritz postprocessing
-    A.mult(block_, T_);
-
-    // TODO: use LAPACK directly
-    final SVD svd = new SVD(T_.numRows(), T_.numColumns(), computeVectors);
-    try {
-      svd.factor(T_);
-    } catch (final NotConvergedException e) {
-      throw new RuntimeException(e.getMessage());
-    }
-    System.arraycopy(svd.getS(), 0, sv_, 0, svd.getS().length); // sv_ is final
-
-    if (computeVectors) {
-      // V^T = (block * V^T)^T = (V^T)^T * block^T
-      // using BLAS directly since Vt is (n_ x d_) but result here is only (k_ x d_)
-      BLAS.getInstance().dgemm("T", "T", k_, d_, k_,
-              1.0, svd.getVt().getData(), k_, block_.getData(), d_,
-              0.0, Vt_.getData(), n_);
-    }
-  }
-
-  private void computeSymmEigSVD(final DenseMatrix A, final boolean computeVectors) {
-    if (T_ == null) {
-      allocateSpaceSymmEigSVD();
-    }
-
-    // want left singular vectors U, aka eigenvectors of AA^T -- so compute that
-    A.transBmult(A, T_);
-    try {
-      // TODO: direct LAPACK call lets us get only the top k values/vectors rather than all
-      evd_.factor(new UpperSymmDenseMatrix(T_, false));
-    } catch (final NotConvergedException e) {
-      throw new RuntimeException(e.getMessage());
-    }
-
-    // TODO: can we only use k_ values?
-    // EVD gives values low-to-high; SVD does high-to-low and we want that order. Reverse
-    // the list when extracting SVs from eigenvalues, and generate a diagonal rotation matrix
-    // to save on an extra matrix multiply if we need to compute vectors later.
-    final double[] ev = evd_.getEigenvalues();
-    for (int i = 0; i < ev.length; ++i) {
-      final double val = Math.sqrt(ev[i]);
-      sv_[n_ - i - 1] = val;
-      if (val > 0) {
-        rotS_.set(n_ - i - 1, i, 1 / val);
-      }
-    }
-
-    if (computeVectors) {
-      rotS_.transBmult(evd_.getEigenvectors(), T_);
-      T_.mult(A, Vt_);
-    }
-  }
-
-}
diff --git a/src/main/java/com/yahoo/sketches/vector/matrix/Matrix.java b/src/main/java/com/yahoo/sketches/vector/matrix/Matrix.java
index d6b6de2..a1eb8ef 100644
--- a/src/main/java/com/yahoo/sketches/vector/matrix/Matrix.java
+++ b/src/main/java/com/yahoo/sketches/vector/matrix/Matrix.java
@@ -12,7 +12,6 @@
 
 import com.yahoo.memory.Memory;
 import com.yahoo.sketches.vector.MatrixFamily;
-import no.uib.cipr.matrix.DenseMatrix;
 
 /**
  * Provides an implementation-agnostic wrapper around Matrix classes.
@@ -36,8 +35,6 @@
     switch (type) {
       case OJALGO:
         return MatrixImplOjAlgo.heapifyInstance(srcMem);
-      case MTJ:
-        return MatrixImplMTJ.heapifyInstance(srcMem);
       default:
         return null;
     }
@@ -54,8 +51,6 @@
       return null;
     } else if (mtx instanceof PrimitiveDenseStore) {
       return MatrixImplOjAlgo.wrap((PrimitiveDenseStore) mtx);
-    } else if (mtx instanceof DenseMatrix) {
-      return MatrixImplMTJ.wrap((DenseMatrix) mtx);
     }
     else {
       throw new IllegalArgumentException("wrap() does not currently support "
diff --git a/src/main/java/com/yahoo/sketches/vector/matrix/MatrixBuilder.java b/src/main/java/com/yahoo/sketches/vector/matrix/MatrixBuilder.java
index 73f0751..cbc7a39 100644
--- a/src/main/java/com/yahoo/sketches/vector/matrix/MatrixBuilder.java
+++ b/src/main/java/com/yahoo/sketches/vector/matrix/MatrixBuilder.java
@@ -45,11 +45,8 @@
       case OJALGO:
         return MatrixImplOjAlgo.newInstance(numRows, numCols);
 
-      case MTJ:
-        return MatrixImplMTJ.newInstance(numRows, numCols);
-
       default:
-        throw new IllegalArgumentException("OJALGO and MTJ are currently the only supported MatrixTypes");
+        throw new IllegalArgumentException("OJALGO is currently the only supported MatrixTypes");
     }
   }
 }
diff --git a/src/main/java/com/yahoo/sketches/vector/matrix/MatrixImplMTJ.java b/src/main/java/com/yahoo/sketches/vector/matrix/MatrixImplMTJ.java
deleted file mode 100644
index 5834b1a..0000000
--- a/src/main/java/com/yahoo/sketches/vector/matrix/MatrixImplMTJ.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright 2017, Yahoo! Inc.
- * Licensed under the terms of the Apache License 2.0. See LICENSE file at the project root
- * for terms.
- */
-
-package com.yahoo.sketches.vector.matrix;
-
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.COMPACT_FLAG_MASK;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractFamilyID;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractFlags;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractNumColumns;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractNumColumnsUsed;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractNumRows;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractNumRowsUsed;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractPreLongs;
-import static com.yahoo.sketches.vector.matrix.MatrixPreambleUtil.extractSerVer;
-
-import com.yahoo.memory.Memory;
-import com.yahoo.memory.WritableMemory;
-import com.yahoo.sketches.vector.MatrixFamily;
-import no.uib.cipr.matrix.DenseMatrix;
-
-public final class MatrixImplMTJ extends Matrix {
-  private DenseMatrix mtx_;
-
-  private MatrixImplMTJ(final int numRows, final int numCols) {
-    mtx_ = new DenseMatrix(numRows, numCols);
-    numRows_ = numRows;
-    numCols_ = numCols;
-  }
-
-  private MatrixImplMTJ(final DenseMatrix mtx) {
-    mtx_ = mtx;
-    numRows_ = mtx.numRows();
-    numCols_ = mtx.numColumns();
-  }
-
-  static Matrix newInstance(final int numRows, final int numCols) {
-    return new MatrixImplMTJ(numRows, numCols);
-  }
-
-  static Matrix heapifyInstance(final Memory srcMem) {
-    final int minBytes = MatrixFamily.MATRIX.getMinPreLongs() * Long.BYTES;
-    final long memCapBytes = srcMem.getCapacity();
-    if (memCapBytes < minBytes) {
-      throw new IllegalArgumentException("Source Memory too small: " + memCapBytes
-              + " < " + minBytes);
-    }
-
-    final int preLongs = extractPreLongs(srcMem);
-    final int serVer = extractSerVer(srcMem);
-    final int familyID = extractFamilyID(srcMem);
-
-    if (serVer != 1) {
-      throw new IllegalArgumentException("Invalid SerVer reading srcMem. Expected 1, found: "
-              + serVer);
-    }
-    if (familyID != MatrixFamily.MATRIX.getID()) {
-      throw new IllegalArgumentException("srcMem does not point to a Matrix");
-    }
-
-    final int flags = extractFlags(srcMem);
-    final boolean isCompact = (flags & COMPACT_FLAG_MASK) > 0;
-
-    int nRows = extractNumRows(srcMem);
-    int nCols = extractNumColumns(srcMem);
-
-    final MatrixImplMTJ matrix;
-
-    if (isCompact) {
-      matrix = new MatrixImplMTJ(nRows, nCols);
-
-      nRows = extractNumRowsUsed(srcMem);
-      nCols = extractNumColumnsUsed(srcMem);
-
-      int memOffset = preLongs * Long.BYTES;
-      for (int c = 0; c < nCols; ++c) {
-        for (int r = 0; r < nRows; ++r) {
-          matrix.mtx_.set(r, c, srcMem.getDouble(memOffset));
-          memOffset += Double.BYTES;
-        }
-      }
-    } else {
-      final int nElements = nRows * nCols;
-      final double[] data = new double[nElements];
-      srcMem.getDoubleArray(preLongs * Long.BYTES, data, 0, nElements);
-
-      matrix = new MatrixImplMTJ(new DenseMatrix(nRows, nCols, data, false));
-    }
-
-    return matrix;
-  }
-
-  static Matrix wrap(final DenseMatrix mtx) {
-    return new MatrixImplMTJ(mtx);
-  }
-
-  @Override
-  public Object getRawObject() {
-    return mtx_;
-  }
-
-  @Override
-  public byte[] toByteArray() {
-    final int preLongs = 2;
-    final long numElements = numRows_ * numCols_;
-    assert numElements == (mtx_.numRows() * mtx_.numColumns());
-
-    final int outBytes = (int) ((preLongs * Long.BYTES) + (numElements * Double.BYTES));
-    final byte[] outByteArr = new byte[outBytes];
-    final WritableMemory memOut = WritableMemory.wrap(outByteArr);
-    final Object memObj = memOut.getArray();
-    final long memAddr = memOut.getCumulativeOffset(0L);
-
-    MatrixPreambleUtil.insertPreLongs(memObj, memAddr, preLongs);
-    MatrixPreambleUtil.insertSerVer(memObj, memAddr, MatrixPreambleUtil.SER_VER);
-    MatrixPreambleUtil.insertFamilyID(memObj, memAddr, MatrixFamily.MATRIX.getID());
-    MatrixPreambleUtil.insertFlags(memObj, memAddr, 0);
-    MatrixPreambleUtil.insertNumRows(memObj, memAddr, numRows_);
-    MatrixPreambleUtil.insertNumColumns(memObj, memAddr, numCols_);
-    memOut.putDoubleArray(preLongs << 3, mtx_.getData(), 0, (int) numElements);
-
-    return outByteArr;
-  }
-
-  @Override
-  public byte[] toCompactByteArray(final int numRows, final int numCols) {
-    // TODO: row/col limit checks
-
-    final int preLongs = 3;
-
-    // for non-compact we can do an array copy, so save as non-compact if using the entire matrix
-    final long numElements = (long) numRows * numCols;
-    final boolean isCompact = numElements < (mtx_.numRows() * mtx_.numColumns());
-    if (!isCompact) {
-      return toByteArray();
-    }
-
-    final int outBytes = (int) ((preLongs * Long.BYTES) + (numElements * Double.BYTES));
-    final byte[] outByteArr = new byte[outBytes];
-    final WritableMemory memOut = WritableMemory.wrap(outByteArr);
-    final Object memObj = memOut.getArray();
-    final long memAddr = memOut.getCumulativeOffset(0L);
-
-    MatrixPreambleUtil.insertPreLongs(memObj, memAddr, preLongs);
-    MatrixPreambleUtil.insertSerVer(memObj, memAddr, MatrixPreambleUtil.SER_VER);
-    MatrixPreambleUtil.insertFamilyID(memObj, memAddr, MatrixFamily.MATRIX.getID());
-    MatrixPreambleUtil.insertFlags(memObj, memAddr, COMPACT_FLAG_MASK);
-    MatrixPreambleUtil.insertNumRows(memObj, memAddr, mtx_.numRows());
-    MatrixPreambleUtil.insertNumColumns(memObj, memAddr, mtx_.numColumns());
-    MatrixPreambleUtil.insertNumRowsUsed(memObj, memAddr, numRows);
-    MatrixPreambleUtil.insertNumColumnsUsed(memObj, memAddr, numCols);
-
-    // write elements in column-major order
-    long offsetBytes = preLongs * Long.BYTES;
-    for (int c = 0; c < numCols; ++c) {
-      for (int r = 0; r < numRows; ++r) {
-        memOut.putDouble(offsetBytes, mtx_.get(r, c));
-        offsetBytes += Double.BYTES;
-      }
-    }
-
-    return outByteArr;
-  }
-
-  @Override
-  public double getElement(final int row, final int col) {
-    return mtx_.get(row, col);
-  }
-
-  @Override
-  public double[] getRow(final int row) {
-    final int cols = mtx_.numColumns();
-    final double[] result = new double[cols];
-    for (int c = 0; c < cols; ++c) {
-      result[c] = mtx_.get(row, c);
-    }
-    return result;
-  }
-
-  @Override
-  public double[] getColumn(final int col) {
-    final int rows = mtx_.numRows();
-    final double[] result = new double[rows];
-    for (int r = 0; r < rows; ++r) {
-      result[r] = mtx_.get(r, col);
-    }
-    return result;
-  }
-
-  @Override
-  public void setElement(final int row, final int col, final double value) {
-    mtx_.set(row, col, value);
-  }
-
-  @Override
-  public void setRow(final int row, final double[] values) {
-    if (values.length != mtx_.numColumns()) {
-      throw new IllegalArgumentException("Invalid number of elements for row. Expected "
-              + mtx_.numColumns() + ", found " + values.length);
-    }
-
-    for (int i = 0; i < mtx_.numColumns(); ++i) {
-      mtx_.set(row, i, values[i]);
-    }
-  }
-
-  @Override
-  public void setColumn(final int column, final double[] values) {
-    if (values.length != mtx_.numRows()) {
-      throw new IllegalArgumentException("Invalid number of elements for column. Expected "
-              + mtx_.numRows() + ", found " + values.length);
-    }
-
-    for (int i = 0; i < mtx_.numRows(); ++i) {
-      // TODO: System.arraycopy()?
-      mtx_.set(i, column, values[i]);
-    }
-  }
-
-  @Override
-  public MatrixType getMatrixType() {
-    return MatrixType.MTJ;
-  }
-}
diff --git a/src/main/java/com/yahoo/sketches/vector/matrix/MatrixType.java b/src/main/java/com/yahoo/sketches/vector/matrix/MatrixType.java
index 8a3dac2..7ca7f2b 100644
--- a/src/main/java/com/yahoo/sketches/vector/matrix/MatrixType.java
+++ b/src/main/java/com/yahoo/sketches/vector/matrix/MatrixType.java
@@ -1,8 +1,7 @@
 package com.yahoo.sketches.vector.matrix;
 
 public enum MatrixType {
-  OJALGO(1, "ojAlgo"),
-  MTJ(2, "MTJ");
+  OJALGO(1, "ojAlgo");
 
   private int id_;
   private String name_;
diff --git a/src/test/java/com/yahoo/sketches/vector/matrix/MatrixBuilderTest.java b/src/test/java/com/yahoo/sketches/vector/matrix/MatrixBuilderTest.java
index eb071cd..4beb32b 100644
--- a/src/test/java/com/yahoo/sketches/vector/matrix/MatrixBuilderTest.java
+++ b/src/test/java/com/yahoo/sketches/vector/matrix/MatrixBuilderTest.java
@@ -20,9 +20,6 @@
     Matrix m = builder.build(128, 512);
     assertNotNull(m);
 
-    builder.setType(MatrixType.MTJ);
-    assertEquals(builder.getBackingType(), MatrixType.MTJ);
-
     m = builder.build(128, 512);
     assertNotNull(m);
   }
@@ -34,10 +31,6 @@
     assertEquals(type, MatrixType.OJALGO); // default type
     assertEquals(type.getId(), MatrixType.OJALGO.getId());
     assertEquals(type.getName(), MatrixType.OJALGO.getName());
-
-    builder.setType(MatrixType.MTJ);
-    assertEquals(builder.getBackingType(), MatrixType.MTJ);
-    assertEquals(builder.getBackingType().toString(), "MTJ");
   }
 
 }
diff --git a/src/test/java/com/yahoo/sketches/vector/matrix/MatrixImplMTJTest.java b/src/test/java/com/yahoo/sketches/vector/matrix/MatrixImplMTJTest.java
deleted file mode 100644
index b23b961..0000000
--- a/src/test/java/com/yahoo/sketches/vector/matrix/MatrixImplMTJTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2017, Yahoo, Inc.
- * Licensed under the terms of the Apache License 2.0. See LICENSE file at the project root for terms.
- */
-
-package com.yahoo.sketches.vector.matrix;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import org.testng.annotations.Test;
-
-import com.yahoo.memory.Memory;
-import com.yahoo.memory.WritableMemory;
-import no.uib.cipr.matrix.DenseMatrix;
-
-public class MatrixImplMTJTest {
-  @Test
-  public void checkInstantiation() {
-    final int nRows = 10;
-    final int nCols = 15;
-    final Matrix m = MatrixImplMTJ.newInstance(nRows, nCols);
-    assertEquals(m.getNumRows(), nRows);
-    assertEquals(m.getNumColumns(), nCols);
-
-    final DenseMatrix pds = (DenseMatrix) m.getRawObject();
-    assertEquals(pds.numRows(), nRows);
-    assertEquals(pds.numColumns(), nCols);
-
-    final Matrix wrapped = Matrix.wrap(pds);
-    MatrixTest.checkMatrixEquality(wrapped, m);
-    assertEquals(wrapped.getRawObject(), pds);
-  }
-
-  @Test
-  public void updateAndQueryValues() {
-    final int nRows = 5;
-    final int nCols = 5;
-    final Matrix m = generateIncreasingEye(nRows, nCols); // tests setElement() in method
-
-    for (int i = 0; i < nRows; ++i) {
-      for (int j = 0; j < nCols; ++j) {
-        final double val = m.getElement(i, j);
-        if (i == j) {
-          assertEquals(val, i + 1.0);
-        } else {
-          assertEquals(val, 0.0);
-        }
-      }
-    }
-  }
-
-  @Test
-  public void checkStandardSerialization() {
-    final int nRows = 3;
-    final int nCols = 7;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-
-    final byte[] mtxBytes = m.toByteArray();
-    assertEquals(mtxBytes.length, m.getSizeBytes());
-
-    final Memory mem = Memory.wrap(mtxBytes);
-    final Matrix tgt = MatrixImplMTJ.heapifyInstance(mem);
-    MatrixTest.checkMatrixEquality(tgt, m);
-  }
-
-  @Test
-  public void checkCompactSerialization() {
-    final int nRows = 4;
-    final int nCols = 7;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-
-    byte[] mtxBytes = m.toCompactByteArray(nRows - 1, 7);
-    assertEquals(mtxBytes.length, m.getCompactSizeBytes(nRows - 1, 7));
-
-    Memory mem = Memory.wrap(mtxBytes);
-    Matrix tgt = MatrixImplMTJ.heapifyInstance(mem);
-    for (int c = 0; c < nCols; ++c) {
-      for (int r = 0; r < (nRows - 1); ++r) {
-        assertEquals(tgt.getElement(r, c), m.getElement(r, c)); // equal here
-      }
-      // assuming nRows - 1 so check only the last row as being 0
-      assertEquals(tgt.getElement(nRows - 1, c), 0.0);
-    }
-
-    // test without compacting
-    mtxBytes = m.toCompactByteArray(nRows, nCols);
-    assertEquals(mtxBytes.length, m.getSizeBytes());
-    mem = Memory.wrap(mtxBytes);
-    tgt = MatrixImplMTJ.heapifyInstance(mem);
-    MatrixTest.checkMatrixEquality(tgt, m);
-  }
-
-  @Test
-  public void matrixRowOperations() {
-    final int nRows = 7;
-    final int nCols = 5;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-
-    final int tgtCol = 2;
-    final double[] v = m.getRow(tgtCol); // diagonal matrix, so this works ok
-    for (int i = 0; i < v.length; ++i) {
-      assertEquals(v[i], (i == tgtCol ? i + 1.0 : 0.0));
-    }
-
-    assertEquals(m.getElement(6, tgtCol), 0.0);
-    m.setRow(6, v);
-    assertEquals(m.getElement(6, tgtCol), tgtCol + 1.0);
-  }
-
-  @Test
-  public void matrixColumnOperations() {
-    final int nRows = 9;
-    final int nCols = 4;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-
-    final int tgtRow = 3;
-    final double[] v = m.getColumn(tgtRow); // diagonal matrix, so this works ok
-    for (int i = 0; i < v.length; ++i) {
-      assertEquals(v[i], (i == tgtRow ? i + 1.0 : 0.0));
-    }
-
-    assertEquals(m.getElement(tgtRow, 0), 0.0);
-    m.setColumn(0, v);
-    assertEquals(m.getElement(tgtRow, 0), tgtRow + 1.0);
-  }
-
-  @Test
-  public void invalidRowColumnOperations() {
-    final int nRows = 9;
-    final int nCols = 4;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-
-    final double[] shortRow = new double[nCols - 2];
-    try {
-      m.setRow(1, shortRow);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-
-    final double[] longColumn = new double[nRows + 2];
-    try {
-      m.setColumn(1, longColumn);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-  }
-
-  @Test
-  public void invalidSerVer() {
-    final int nRows = 3;
-    final int nCols = 3;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-    final byte[] sketchBytes = m.toByteArray();
-    final WritableMemory mem = WritableMemory.wrap(sketchBytes);
-    MatrixPreambleUtil.insertSerVer(mem.getArray(), mem.getCumulativeOffset(0L), 0);
-
-    try {
-      MatrixImplMTJ.heapifyInstance(mem);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-  }
-
-  @Test
-  public void invalidFamily() {
-    final int nRows = 3;
-    final int nCols = 3;
-    final Matrix m = generateIncreasingEye(nRows, nCols);
-    final byte[] sketchBytes = m.toByteArray();
-    final WritableMemory mem = WritableMemory.wrap(sketchBytes);
-    MatrixPreambleUtil.insertFamilyID(mem.getArray(), mem.getCumulativeOffset(0L), 0);
-
-    try {
-      MatrixImplMTJ.heapifyInstance(mem);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-  }
-
-  @Test
-  public void insufficientMemoryCapacity() {
-    final byte[] bytes = new byte[6];
-    final Memory mem = Memory.wrap(bytes);
-    try {
-      MatrixImplMTJ.heapifyInstance(mem);
-      fail();
-    } catch (final IllegalArgumentException e) {
-      // expected
-    }
-  }
-
-  /**
-   * Creates a scaled I matrix, where the diagonal consists of increasing integers,
-   * starting with 1.0.
-   * @param nRows number of rows
-   * @param nCols number of columns
-   * @return PrimitiveDenseStore, suitable for direct use or wrapping
-   */
-  private static Matrix generateIncreasingEye(final int nRows, final int nCols) {
-    final Matrix m = MatrixImplMTJ.newInstance(nRows, nCols);
-    for (int i = 0; (i < nRows) && (i < nCols); ++i) {
-      m.setElement(i, i, 1.0 + i);
-    }
-    return m;
-  }
-}
diff --git a/src/test/java/com/yahoo/sketches/vector/matrix/MatrixTest.java b/src/test/java/com/yahoo/sketches/vector/matrix/MatrixTest.java
index a2262d7..8be75cc 100644
--- a/src/test/java/com/yahoo/sketches/vector/matrix/MatrixTest.java
+++ b/src/test/java/com/yahoo/sketches/vector/matrix/MatrixTest.java
@@ -26,13 +26,9 @@
     final Memory mem = Memory.wrap(bytes);
     println(MatrixPreambleUtil.preambleToString(mem));
 
-    Matrix tgt = Matrix.heapify(mem, MatrixType.OJALGO);
+    final Matrix tgt = Matrix.heapify(mem, MatrixType.OJALGO);
     assertTrue(tgt instanceof MatrixImplOjAlgo);
     checkMatrixEquality(m, tgt);
-
-    tgt = Matrix.heapify(mem, MatrixType.MTJ);
-    assertTrue(tgt instanceof MatrixImplMTJ);
-    checkMatrixEquality(m, tgt);
   }
 
   @Test