You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/04/17 08:21:51 UTC
[29/50] [abbrv] ignite git commit: IGNITE-4572 Machine Learning:
Develop distributed algebra support for dense and sparse data sets.
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/AbstractMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/AbstractMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/AbstractMatrix.java
new file mode 100644
index 0000000..ca11e81
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/AbstractMatrix.java
@@ -0,0 +1,880 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.decompositions.LUDecomposition;
+import org.apache.ignite.math.exceptions.CardinalityException;
+import org.apache.ignite.math.exceptions.ColumnIndexException;
+import org.apache.ignite.math.exceptions.RowIndexException;
+import org.apache.ignite.math.functions.Functions;
+import org.apache.ignite.math.functions.IgniteBiFunction;
+import org.apache.ignite.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.math.functions.IgniteFunction;
+import org.apache.ignite.math.functions.IntIntToDoubleFunction;
+import org.apache.ignite.math.impls.vector.MatrixVectorView;
+
+/**
+ * This class provides a helper implementation of the {@link Matrix}
+ * interface to minimize the effort required to implement it.
+ * Subclasses may override some of the implemented methods if a more
+ * specific or optimized implementation is desirable.
+ *
+ * TODO: add row/column optimization.
+ */
+public abstract class AbstractMatrix implements Matrix {
+ // Stochastic sparsity analysis.
+ /** */
+ private static final double Z95 = 1.959964;
+ /** */
+ private static final double Z80 = 1.281552;
+ /** */
+ private static final int MAX_SAMPLES = 500;
+ /** */
+ private static final int MIN_SAMPLES = 15;
+
+ /** Cached minimum element. */
+ private Element minElm;
+ /** Cached maximum element. */
+ private Element maxElm = null;
+
+ /** Matrix storage implementation. */
+ private MatrixStorage sto;
+
+ /** Meta attributes storage. */
+ private Map<String, Object> meta = new HashMap<>();
+
+ /** Matrix's GUID. */
+ private IgniteUuid guid = IgniteUuid.randomUuid();
+
+ /**
+ * @param sto Backing {@link MatrixStorage}.
+ */
+ public AbstractMatrix(MatrixStorage sto) {
+ this.sto = sto;
+ }
+
+ /**
+ *
+ */
+ public AbstractMatrix() {
+ // No-op.
+ }
+
+ /**
+ * @param sto Backing {@link MatrixStorage}.
+ */
+ protected void setStorage(MatrixStorage sto) {
+ assert sto != null;
+
+ this.sto = sto;
+ }
+
+ /**
+ * @param row Row index in the matrix.
+ * @param col Column index in the matrix.
+ * @param v Value to set.
+ */
+ protected void storageSet(int row, int col, double v) {
+ sto.set(row, col, v);
+
+ // Reset cached values.
+ minElm = maxElm = null;
+ }
+
+ /**
+ * @param row Row index in the matrix.
+ * @param col Column index in the matrix.
+ */
+ protected double storageGet(int row, int col) {
+ return sto.get(row, col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element maxElement() {
+ if (maxElm == null) {
+ double max = Double.NEGATIVE_INFINITY;
+ int row = 0, col = 0;
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++) {
+ double d = storageGet(x, y);
+
+ if (d > max) {
+ max = d;
+ row = x;
+ col = y;
+ }
+ }
+
+ maxElm = mkElement(row, col);
+ }
+
+ return maxElm;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element minElement() {
+ if (minElm == null) {
+ double min = Double.MAX_VALUE;
+ int row = 0, col = 0;
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++) {
+ double d = storageGet(x, y);
+
+ if (d < min) {
+ min = d;
+ row = x;
+ col = y;
+ }
+ }
+
+ minElm = mkElement(row, col);
+ }
+
+ return minElm;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxValue() {
+ return maxElement().get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double minValue() {
+ return minElement().get();
+ }
+
+ /**
+ * @param row Row index in the matrix.
+ * @param col Column index in the matrix.
+ */
+ private Element mkElement(int row, int col) {
+ return new Element() {
+ /** {@inheritDoc} */
+ @Override public double get() {
+ return storageGet(row, col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int row() {
+ return row;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int column() {
+ return col;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(double d) {
+ storageSet(row, col, d);
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element getElement(int row, int col) {
+ return mkElement(row, col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix swapRows(int row1, int row2) {
+ checkRowIndex(row1);
+ checkRowIndex(row2);
+
+ int cols = columnSize();
+
+ for (int y = 0; y < cols; y++) {
+ double v = getX(row1, y);
+
+ setX(row1, y, getX(row2, y));
+ setX(row2, y, v);
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix swapColumns(int col1, int col2) {
+ checkColumnIndex(col1);
+ checkColumnIndex(col2);
+
+ int rows = rowSize();
+
+ for (int x = 0; x < rows; x++) {
+ double v = getX(x, col1);
+
+ setX(x, col1, getX(x, col2));
+ setX(x, col2, v);
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public MatrixStorage getStorage() {
+ return sto;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSequentialAccess() {
+ return sto.isSequentialAccess();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDense() {
+ return sto.isDense();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRandomAccess() {
+ return sto.isRandomAccess();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDistributed() {
+ return sto.isDistributed();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isArrayBased() {
+ return sto.isArrayBased();
+ }
+
+ /**
+ * Check row index bounds.
+ *
+ * @param row Row index.
+ */
+ private void checkRowIndex(int row) {
+ if (row < 0 || row >= rowSize())
+ throw new RowIndexException(row);
+ }
+
+ /**
+ * Check column index bounds.
+ *
+ * @param col Column index.
+ */
+ private void checkColumnIndex(int col) {
+ if (col < 0 || col >= columnSize())
+ throw new ColumnIndexException(col);
+ }
+
+ /**
+ * Check column and row index bounds.
+ *
+ * @param row Row index.
+ * @param col Column index.
+ */
+ protected void checkIndex(int row, int col) {
+ checkRowIndex(row);
+ checkColumnIndex(col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(sto);
+ out.writeObject(meta);
+ out.writeObject(guid);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<String, Object> getMetaStorage() {
+ return meta;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ sto = (MatrixStorage)in.readObject();
+ meta = (Map<String, Object>)in.readObject();
+ guid = (IgniteUuid)in.readObject();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assign(double val) {
+ if (sto.isArrayBased())
+ for (double[] column : sto.data())
+ Arrays.fill(column, val);
+ else {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ storageSet(x, y, val);
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assign(IntIntToDoubleFunction fun) {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ storageSet(x, y, fun.apply(x, y));
+
+ return this;
+ }
+
+ /** */
+ private void checkCardinality(Matrix mtx) {
+ checkCardinality(mtx.rowSize(), mtx.columnSize());
+ }
+
+ /** */
+ private void checkCardinality(int rows, int cols) {
+ if (rows != rowSize())
+ throw new CardinalityException(rowSize(), rows);
+
+ if (cols != columnSize())
+ throw new CardinalityException(columnSize(), cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assign(double[][] vals) {
+ checkCardinality(vals.length, vals[0].length);
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ storageSet(x, y, vals[x][y]);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assign(Matrix mtx) {
+ checkCardinality(mtx);
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ storageSet(x, y, mtx.getX(x, y));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix map(IgniteDoubleFunction<Double> fun) {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ storageSet(x, y, fun.apply(storageGet(x, y)));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix map(Matrix mtx, IgniteBiFunction<Double, Double, Double> fun) {
+ checkCardinality(mtx);
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ storageSet(x, y, fun.apply(storageGet(x, y), mtx.getX(x, y)));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assignColumn(int col, org.apache.ignite.math.Vector vec) {
+ checkColumnIndex(col);
+
+ int rows = rowSize();
+
+ for (int x = 0; x < rows; x++)
+ storageSet(x, col, vec.getX(x));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assignRow(int row, Vector vec) {
+ checkRowIndex(row);
+
+ int cols = columnSize();
+
+ if (cols != vec.size())
+ throw new CardinalityException(cols, vec.size());
+
+ if (sto.isArrayBased() && vec.getStorage().isArrayBased())
+ System.arraycopy(vec.getStorage().data(), 0, sto.data()[row], 0, cols);
+ else
+ for (int y = 0; y < cols; y++)
+ storageSet(row, y, vec.getX(y));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector foldRows(IgniteFunction<Vector, Double> fun) {
+ int rows = rowSize();
+
+ Vector vec = likeVector(rows);
+
+ for (int i = 0; i < rows; i++)
+ vec.setX(i, fun.apply(viewRow(i)));
+
+ return vec;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector foldColumns(IgniteFunction<Vector, Double> fun) {
+ int cols = columnSize();
+
+ Vector vec = likeVector(cols);
+
+ for (int i = 0; i < cols; i++)
+ vec.setX(i, fun.apply(viewColumn(i)));
+
+ return vec;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> T foldMap(IgniteBiFunction<T, Double, T> foldFun, IgniteDoubleFunction<Double> mapFun,
+ T zeroVal) {
+ T res = zeroVal;
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ res = foldFun.apply(res, mapFun.apply(storageGet(x, y)));
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int columnSize() {
+ return sto.columnSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int rowSize() {
+ return sto.rowSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double determinant() {
+ //TODO: This decomposition should be cached
+ LUDecomposition dec = new LUDecomposition(this);
+ double res = dec.determinant();
+ dec.destroy();
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix inverse() {
+ if (rowSize() != columnSize())
+ throw new CardinalityException(rowSize(), columnSize());
+
+ //TODO: This decomposition should be cached
+ LUDecomposition dec = new LUDecomposition(this);
+
+ Matrix res = dec.solve(likeIdentity());
+ dec.destroy();
+
+ return res;
+ }
+
+ /** */
+ protected Matrix likeIdentity() {
+ int n = rowSize();
+ Matrix res = like(n, n);
+
+ for (int i = 0; i < n; i++)
+ res.setX(i, i, 1.0);
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix divide(double d) {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ setX(x, y, getX(x, y) / d);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double get(int row, int col) {
+ checkIndex(row, col);
+
+ return storageGet(row, col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getX(int row, int col) {
+ return storageGet(row, col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix minus(Matrix mtx) {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ checkCardinality(rows, cols);
+
+ Matrix res = like(rows, cols);
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ res.setX(x, y, getX(x, y) - mtx.getX(x, y));
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix plus(double x) {
+ Matrix cp = copy();
+
+ cp.map(Functions.plus(x));
+
+ return cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix plus(Matrix mtx) {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ checkCardinality(rows, cols);
+
+ Matrix res = like(rows, cols);
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ res.setX(x, y, getX(x, y) + mtx.getX(x, y));
+
+ return res;
+
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteUuid guid() {
+ return guid;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix set(int row, int col, double val) {
+ checkIndex(row, col);
+
+ storageSet(row, col, val);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix setRow(int row, double[] data) {
+ checkRowIndex(row);
+
+ int cols = columnSize();
+
+ if (cols != data.length)
+ throw new CardinalityException(cols, data.length);
+
+ if (sto.isArrayBased())
+ System.arraycopy(data, 0, sto.data()[row], 0, cols);
+ else
+ for (int y = 0; y < cols; y++)
+ setX(row, y, data[y]);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix setColumn(int col, double[] data) {
+ checkColumnIndex(col);
+
+ int rows = rowSize();
+
+ if (rows != data.length)
+ throw new CardinalityException(rows, data.length);
+
+ for (int x = 0; x < rows; x++)
+ setX(x, col, data[x]);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix setX(int row, int col, double val) {
+ storageSet(row, col, val);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix times(double x) {
+ Matrix cp = copy();
+
+ cp.map(Functions.mult(x));
+
+ return cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxAbsRowSumNorm() {
+ double max = 0.0;
+
+ int rows = rowSize();
+ int cols = columnSize();
+
+ for (int x = 0; x < rows; x++) {
+ double sum = 0;
+
+ for (int y = 0; y < cols; y++)
+ sum += Math.abs(getX(x, y));
+
+ if (sum > max)
+ max = sum;
+ }
+
+ return max;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(Vector vec) {
+ int cols = columnSize();
+
+ if (cols != vec.size())
+ throw new CardinalityException(cols, vec.size());
+
+ int rows = rowSize();
+
+ Vector res = likeVector(rows);
+
+ for (int x = 0; x < rows; x++)
+ res.setX(x, vec.dot(viewRow(x)));
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix times(Matrix mtx) {
+ int cols = columnSize();
+
+ if (cols != mtx.rowSize())
+ throw new CardinalityException(cols, mtx.rowSize());
+
+ int rows = rowSize();
+
+ int mtxCols = mtx.columnSize();
+
+ Matrix res = like(rows, mtxCols);
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < mtxCols; y++) {
+ double sum = 0.0;
+
+ for (int k = 0; k < cols; k++)
+ sum += getX(x, k) * mtx.getX(k, y);
+
+ res.setX(x, y, sum);
+ }
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ double sum = 0.0;
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ sum += getX(x, y);
+
+ return sum;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix transpose() {
+ int rows = rowSize();
+ int cols = columnSize();
+
+ Matrix mtx = like(cols, rows);
+
+ for (int x = 0; x < rows; x++)
+ for (int y = 0; y < cols; y++)
+ mtx.setX(y, x, getX(x, y));
+
+ return mtx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean density(double threshold) {
+ assert threshold >= 0.0 && threshold <= 1.0;
+
+ int n = MIN_SAMPLES;
+ int rows = rowSize();
+ int cols = columnSize();
+
+ double mean = 0.0;
+ double pq = threshold * (1 - threshold);
+
+ Random rnd = new Random();
+
+ for (int i = 0; i < MIN_SAMPLES; i++)
+ if (getX(rnd.nextInt(rows), rnd.nextInt(cols)) != 0.0)
+ mean++;
+
+ mean /= MIN_SAMPLES;
+
+ double iv = Z80 * Math.sqrt(pq / n);
+
+ if (mean < threshold - iv)
+ return false; // Sparse.
+ else if (mean > threshold + iv)
+ return true; // Dense.
+
+ while (n < MAX_SAMPLES) {
+ // Determine upper bound we may need for 'n' to likely relinquish the uncertainty.
+ // Here, we use confidence interval formula but solved for 'n'.
+ double ivX = Math.max(Math.abs(threshold - mean), 1e-11);
+
+ double stdErr = ivX / Z80;
+ double nX = Math.min(Math.max((int)Math.ceil(pq / (stdErr * stdErr)), n), MAX_SAMPLES) - n;
+
+ if (nX < 1.0) // IMPL NOTE this can happen with threshold 1.0
+ nX = 1.0;
+
+ double meanNext = 0.0;
+
+ for (int i = 0; i < nX; i++)
+ if (getX(rnd.nextInt(rows), rnd.nextInt(cols)) != 0.0)
+ meanNext++;
+
+ mean = (n * mean + meanNext) / (n + nX);
+
+ n += nX;
+
+ // Are we good now?
+ iv = Z80 * Math.sqrt(pq / n);
+
+ if (mean < threshold - iv)
+ return false; // Sparse.
+ else if (mean > threshold + iv)
+ return true; // Dense.
+ }
+
+ return mean > threshold; // Dense if mean > threshold.
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix viewPart(int[] off, int[] size) {
+ return new MatrixView(this, off[0], off[1], size[0], size[1]);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix viewPart(int rowOff, int rows, int colOff, int cols) {
+ return viewPart(new int[] {rowOff, colOff}, new int[] {rows, cols});
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewRow(int row) {
+ return new MatrixVectorView(this, row, 0, 0, 1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewColumn(int col) {
+ return new MatrixVectorView(this, 0, col, 1, 0);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewDiagonal() {
+ return new MatrixVectorView(this, 0, 0, 1, 1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ Matrix cp = like(rowSize(), columnSize());
+
+ cp.assign(this);
+
+ return cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + guid.hashCode();
+ res = res * 37 + sto.hashCode();
+ res = res * 37 + meta.hashCode();
+
+ return res;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * We ignore guid's for comparisons.
+ */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ AbstractMatrix that = (AbstractMatrix)o;
+
+ MatrixStorage sto = getStorage();
+
+ return (sto != null ? sto.equals(that.getStorage()) : that.getStorage() == null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/CacheMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/CacheMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/CacheMatrix.java
new file mode 100644
index 0000000..8ce1192
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/CacheMatrix.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixKeyMapper;
+import org.apache.ignite.math.ValueMapper;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.math.functions.IgniteFunction;
+import org.apache.ignite.math.impls.CacheUtils;
+import org.apache.ignite.math.impls.storage.matrix.CacheMatrixStorage;
+
+/**
+ * Matrix based on existing cache and key and value mapping functions.
+ */
+public class CacheMatrix<K, V> extends AbstractMatrix {
+ /**
+ *
+ */
+ public CacheMatrix() {
+ // No-op.
+ }
+
+ /**
+ * Creates new matrix over existing cache.
+ *
+ * @param rows
+ * @param cols
+ * @param cache
+ * @param keyMapper
+ * @param valMapper
+ */
+ public CacheMatrix(
+ int rows,
+ int cols,
+ IgniteCache<K, V> cache,
+ MatrixKeyMapper<K> keyMapper,
+ ValueMapper<V> valMapper) {
+ assert rows > 0;
+ assert cols > 0;
+ assert cache != null;
+ assert keyMapper != null;
+ assert valMapper != null;
+
+ setStorage(new CacheMatrixStorage<>(rows, cols, cache, keyMapper, valMapper));
+ }
+
+ /**
+ *
+ *
+ */
+ @SuppressWarnings({"unchecked"})
+ private CacheMatrixStorage<K, V> storage() {
+ return (CacheMatrixStorage<K, V>)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the same matrix with updates values (broken contract).
+ *
+ * @param d
+ */
+ @Override public Matrix divide(double d) {
+ return mapOverValues((Double v) -> v / d);
+ }
+
+ /**
+ * Return the same matrix with updates values (broken contract).
+ *
+ * @param x
+ */
+ @Override public Matrix plus(double x) {
+ return mapOverValues((Double v) -> v + x);
+ }
+
+ /**
+ * Return the same matrix with updates values (broken contract).
+ *
+ * @param x
+ */
+ @Override public Matrix times(double x) {
+ return mapOverValues((Double v) -> v * x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assign(double val) {
+ return mapOverValues((Double v) -> val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix map(IgniteDoubleFunction<Double> fun) {
+ return mapOverValues(fun::apply);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ CacheMatrixStorage<K, V> sto = storage();
+
+ return CacheUtils.sum(sto.cache().getName(), sto.keyMapper(), sto.valueMapper());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxValue() {
+ CacheMatrixStorage<K, V> sto = storage();
+
+ return CacheUtils.max(sto.cache().getName(), sto.keyMapper(), sto.valueMapper());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double minValue() {
+ CacheMatrixStorage<K, V> sto = storage();
+
+ return CacheUtils.min(sto.cache().getName(), sto.keyMapper(), sto.valueMapper());
+ }
+
+ /**
+ * @param mapper
+ */
+ private Matrix mapOverValues(IgniteFunction<Double, Double> mapper) {
+ CacheMatrixStorage<K, V> sto = storage();
+
+ CacheUtils.map(sto.cache().getName(), sto.keyMapper(), sto.valueMapper(), mapper);
+
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrix.java
new file mode 100644
index 0000000..d5f8eca
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOffHeapMatrix.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.storage.matrix.DenseOffHeapMatrixStorage;
+import org.apache.ignite.math.impls.vector.DenseLocalOffHeapVector;
+
+/**
+ * Dense local off-heap implementation of the {@link Matrix} interface.
+ */
+public class DenseLocalOffHeapMatrix extends AbstractMatrix {
+ /** */
+ public DenseLocalOffHeapMatrix() {
+ // No-op.
+ }
+
+ /**
+ * @param data Backing data array.
+ */
+ public DenseLocalOffHeapMatrix(double[][] data) {
+ assert data != null;
+
+ setStorage(new DenseOffHeapMatrixStorage(data));
+ }
+
+ /**
+ * @param rows Amount of rows in matrix.
+ * @param cols Amount of columns in matrix.
+ */
+ public DenseLocalOffHeapMatrix(int rows, int cols) {
+ assert rows > 0;
+ assert cols > 0;
+
+ setStorage(new DenseOffHeapMatrixStorage(rows, cols));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ DenseLocalOffHeapMatrix cp = new DenseLocalOffHeapMatrix(getStorage().rowSize(), getStorage().columnSize());
+
+ cp.assign(this);
+
+ return cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ return new DenseLocalOffHeapMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ return new DenseLocalOffHeapVector(crd);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void destroy() {
+ getStorage().destroy();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Matrix likeIdentity() {
+ int n = rowSize();
+ Matrix res = like(n, n);
+
+ // IMPL NOTE as opposed to on-heap matrices this one isn't initialized with zeroes
+ for (int i = 0; i < n; i++)
+ for (int j = 0; j < n; j++)
+ res.setX(i, j, i == j ? 1.0 : 0.0);
+
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrix.java
new file mode 100644
index 0000000..3cc3e4f
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DenseLocalOnHeapMatrix.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.storage.matrix.ArrayMatrixStorage;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+
+/**
+ * Basic implementation for matrix.
+ *
+ * This is a trivial implementation for matrix assuming dense logic, local on-heap JVM storage
+ * based on <code>double[][]</code> array. It is only suitable for data sets where
+ * local, non-distributed execution is satisfactory and on-heap JVM storage is enough
+ * to keep the entire data set.
+ */
+public class DenseLocalOnHeapMatrix extends AbstractMatrix {
+ /**
+ *
+ */
+ public DenseLocalOnHeapMatrix() {
+ // No-op.
+ }
+
+ /**
+ * @param rows Amount of rows in matrix.
+ * @param cols Amount of columns in matrix.
+ */
+ public DenseLocalOnHeapMatrix(int rows, int cols) {
+ assert rows > 0;
+ assert cols > 0;
+
+ setStorage(new ArrayMatrixStorage(rows, cols));
+ }
+
+ /**
+ * @param mtx Backing data array.
+ */
+ public DenseLocalOnHeapMatrix(double[][] mtx) {
+ assert mtx != null;
+
+ setStorage(new ArrayMatrixStorage(mtx));
+ }
+
+ /**
+ * @param orig Original matrix.
+ */
+ private DenseLocalOnHeapMatrix(DenseLocalOnHeapMatrix orig) {
+ assert orig != null;
+
+ setStorage(new ArrayMatrixStorage(orig.rowSize(), orig.columnSize()));
+
+ assign(orig);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ return new DenseLocalOnHeapMatrix(this);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ return new DenseLocalOnHeapMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ return new DenseLocalOnHeapVector(crd);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DiagonalMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DiagonalMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DiagonalMatrix.java
new file mode 100644
index 0000000..0b1f97e
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/DiagonalMatrix.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.storage.matrix.DiagonalMatrixStorage;
+import org.apache.ignite.math.impls.vector.ConstantVector;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+import org.apache.ignite.math.impls.vector.SingleElementVectorView;
+
+/**
+ * Implementation of diagonal view of the {@link Matrix}.
+ *
+ * <p>See also: <a href="https://en.wikipedia.org/wiki/Diagonal_matrix">Wikipedia article</a>.</p>
+ */
+public class DiagonalMatrix extends AbstractMatrix {
+ /**
+ *
+ */
+ public DiagonalMatrix() {
+ // No-op.
+ }
+
+ /**
+ * @param diagonal Backing {@link Vector}.
+ */
+ public DiagonalMatrix(Vector diagonal) {
+ super(new DiagonalMatrixStorage(diagonal));
+ }
+
+ /**
+ * @param mtx Backing {@link Matrix}.
+ */
+ public DiagonalMatrix(Matrix mtx) {
+ super(new DiagonalMatrixStorage(mtx == null ? null : mtx.viewDiagonal()));
+ }
+
+ /**
+ * @param vals Backing array of values at diagonal.
+ */
+ public DiagonalMatrix(double[] vals) {
+ super(new DiagonalMatrixStorage(new DenseLocalOnHeapVector(vals)));
+ }
+
+ /**
+ *
+ *
+ */
+ private DiagonalMatrixStorage storage() {
+ return (DiagonalMatrixStorage)getStorage();
+ }
+
+ /**
+ * @param size Size of diagonal.
+ * @param val Constant value at diagonal.
+ */
+ public DiagonalMatrix(int size, double val) {
+ super(new DiagonalMatrixStorage(new ConstantVector(size, val)));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewRow(int row) {
+ return new SingleElementVectorView(storage().diagonal(), row);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewColumn(int col) {
+ return new SingleElementVectorView(storage().diagonal(), col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ return new DiagonalMatrix(storage().diagonal());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ return storage().diagonal().likeMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ return storage().diagonal().like(crd);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/FunctionMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/FunctionMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/FunctionMatrix.java
new file mode 100644
index 0000000..b180b5b
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/FunctionMatrix.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.functions.IntIntDoubleToVoidFunction;
+import org.apache.ignite.math.functions.IntIntToDoubleFunction;
+import org.apache.ignite.math.impls.storage.matrix.FunctionMatrixStorage;
+
+/**
+ * Implementation of {@link Matrix} that maps row and column index to {@link java.util.function} interfaces.
+ */
+public class FunctionMatrix extends AbstractMatrix {
+ /**
+ *
+ */
+ public FunctionMatrix() {
+ // No-op.
+ }
+
+ /**
+ * Creates read-write or read-only function matrix.
+ *
+ * @param rows Amount of rows in the matrix.
+ * @param cols Amount of columns in the matrix.
+ * @param getFunc Function that returns value corresponding to given row and column index.
+ * @param setFunc Set function. If {@code null} - this will be a read-only matrix.
+ */
+ public FunctionMatrix(int rows, int cols, IntIntToDoubleFunction getFunc, IntIntDoubleToVoidFunction setFunc) {
+ assert rows > 0;
+ assert cols > 0;
+ assert getFunc != null;
+
+ setStorage(new FunctionMatrixStorage(rows, cols, getFunc, setFunc));
+ }
+
+ /**
+ * Creates read-only function matrix.
+ *
+ * @param rows Amount of rows in the matrix.
+ * @param cols Amount of columns in the matrix.
+ * @param getFunc Function that returns value corresponding to given row and column index.
+ */
+ public FunctionMatrix(int rows, int cols, IntIntToDoubleFunction getFunc) {
+ assert rows > 0;
+ assert cols > 0;
+ assert getFunc != null;
+
+ setStorage(new FunctionMatrixStorage(rows, cols, getFunc));
+ }
+
+ /**
+ *
+ *
+ */
+ private FunctionMatrixStorage storage() {
+ return (FunctionMatrixStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ FunctionMatrixStorage sto = storage();
+
+ return new FunctionMatrix(sto.rowSize(), sto.columnSize(), sto.getFunction(), sto.setFunction());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ FunctionMatrixStorage sto = storage();
+
+ return new FunctionMatrix(rows, cols, sto.getFunction(), sto.setFunction());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/MatrixView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/MatrixView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/MatrixView.java
new file mode 100644
index 0000000..7b04dde
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/MatrixView.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import java.io.Externalizable;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.storage.matrix.MatrixDelegateStorage;
+
+/**
+ * Implements the rectangular view into the parent {@link Matrix}.
+ */
+public class MatrixView extends AbstractMatrix {
+ /**
+ * Constructor for {@link Externalizable} interface.
+ */
+ public MatrixView() {
+ // No-op.
+ }
+
+ /**
+ * @param parent Backing parent {@link Matrix}.
+ * @param rowOff Row offset to parent matrix.
+ * @param colOff Column offset to parent matrix.
+ * @param rows Amount of rows in the view.
+ * @param cols Amount of columns in the view.
+ */
+ public MatrixView(Matrix parent, int rowOff, int colOff, int rows, int cols) {
+ this(parent == null ? null : parent.getStorage(), rowOff, colOff, rows, cols);
+ }
+
+ /**
+ * @param sto Backing parent {@link MatrixStorage}.
+ * @param rowOff Row offset to parent storage.
+ * @param colOff Column offset to parent storage.
+ * @param rows Amount of rows in the view.
+ * @param cols Amount of columns in the view.
+ */
+ public MatrixView(MatrixStorage sto, int rowOff, int colOff, int rows, int cols) {
+ super(new MatrixDelegateStorage(sto, rowOff, colOff, rows, cols));
+ }
+
+ /**
+ *
+ *
+ */
+ private MatrixDelegateStorage storage() {
+ return (MatrixDelegateStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ MatrixDelegateStorage sto = storage();
+
+ return new MatrixView(sto.delegate(), sto.rowOffset(), sto.columnOffset(), sto.rowSize(), sto.columnSize());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/PivotedMatrixView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/PivotedMatrixView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/PivotedMatrixView.java
new file mode 100644
index 0000000..1f7b008
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/PivotedMatrixView.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.IndexException;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.storage.matrix.PivotedMatrixStorage;
+import org.apache.ignite.math.impls.vector.PivotedVectorView;
+
+/**
+ * Pivoted (index mapped) view over another matrix implementation.
+ */
+public class PivotedMatrixView extends AbstractMatrix {
+ /** Pivoted matrix. */
+ private Matrix mtx;
+
+ /**
+ *
+ */
+ public PivotedMatrixView() {
+ // No-op.
+ }
+
+ /**
+ * @param mtx
+ * @param rowPivot
+ * @param colPivot
+ */
+ public PivotedMatrixView(Matrix mtx, int[] rowPivot, int[] colPivot) {
+ super(new PivotedMatrixStorage(mtx == null ? null : mtx.getStorage(), rowPivot, colPivot));
+
+ this.mtx = mtx;
+ }
+
+ /**
+ * @param mtx
+ */
+ public PivotedMatrixView(Matrix mtx) {
+ super(new PivotedMatrixStorage(mtx == null ? null : mtx.getStorage()));
+
+ this.mtx = mtx;
+ }
+
+ /**
+ * @param mtx
+ * @param pivot
+ */
+ public PivotedMatrixView(Matrix mtx, int[] pivot) {
+ super(new PivotedMatrixStorage(mtx == null ? null : mtx.getStorage(), pivot));
+
+ this.mtx = mtx;
+ }
+
+ /**
+ * Swaps indexes {@code i} and {@code j} for both both row and column.
+ *
+ * @param i First index to swap.
+ * @param j Second index to swap.
+ */
+ public Matrix swap(int i, int j) {
+ swapRows(i, j);
+ swapColumns(i, j);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix swapRows(int i, int j) {
+ if (i < 0 || i >= storage().rowPivot().length)
+ throw new IndexException(i);
+ if (j < 0 || j >= storage().rowPivot().length)
+ throw new IndexException(j);
+
+ storage().swapRows(i, j);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix swapColumns(int i, int j) {
+ if (i < 0 || i >= storage().columnPivot().length)
+ throw new IndexException(i);
+ if (j < 0 || j >= storage().columnPivot().length)
+ throw new IndexException(j);
+
+ storage().swapColumns(i, j);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewRow(int row) {
+ return new PivotedVectorView(
+ mtx.viewRow(storage().rowPivot()[row]),
+ storage().columnPivot(),
+ storage().columnUnpivot()
+ );
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewColumn(int col) {
+ return new PivotedVectorView(
+ mtx.viewColumn(storage().columnPivot()[col]),
+ storage().rowPivot(),
+ storage().rowUnpivot()
+ );
+ }
+
+ /**
+ *
+ *
+ */
+ public Matrix getBaseMatrix() {
+ return mtx;
+ }
+
+ /**
+ *
+ *
+ */
+ public int[] rowPivot() {
+ return storage().rowPivot();
+ }
+
+ /**
+ *
+ *
+ */
+ public int[] columnPivot() {
+ return storage().columnPivot();
+ }
+
+ /**
+ * @param i
+ */
+ public int rowPivot(int i) {
+ return storage().rowPivot()[i];
+ }
+
+ /**
+ * @param i
+ */
+ public int columnPivot(int i) {
+ return storage().columnPivot()[i];
+ }
+
+ /**
+ * @param i
+ */
+ public int rowUnpivot(int i) {
+ return storage().rowUnpivot()[i];
+ }
+
+ /**
+ * @param i
+ */
+ public int columnUnpivot(int i) {
+ return storage().columnUnpivot()[i];
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+
+ out.writeObject(mtx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+
+ mtx = (Matrix)in.readObject();
+ }
+
+ /**
+ *
+ *
+ */
+ private PivotedMatrixStorage storage() {
+ return (PivotedMatrixStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ return new PivotedMatrixView(mtx, storage().rowPivot(), storage().columnPivot());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + mtx.hashCode();
+ res = res * 37 + getStorage().hashCode();
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ PivotedMatrixView that = (PivotedMatrixView)o;
+
+ MatrixStorage sto = storage();
+
+ return mtx.equals(that.mtx) && sto.equals(that.storage());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/RandomMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/RandomMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/RandomMatrix.java
new file mode 100644
index 0000000..2c3dcb2
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/RandomMatrix.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.storage.matrix.RandomMatrixStorage;
+import org.apache.ignite.math.impls.vector.RandomVector;
+
+/**
+ * Implementation of {@link Matrix} with random values in the elements.
+ */
+public class RandomMatrix extends AbstractMatrix {
+ /** Whether fast hash is used, see {@link RandomMatrixStorage}. */
+ private boolean fastHash;
+
+ /**
+ * @param rows Amount of rows in the matrix.
+ * @param cols Amount of columns in the matrix.
+ * @param fastHash Whether fast hash is used.
+ */
+ private MatrixStorage mkStorage(int rows, int cols, boolean fastHash) {
+ this.fastHash = fastHash;
+
+ return new RandomMatrixStorage(rows, cols, fastHash);
+ }
+
+ /**
+ * @param rows Amount of rows in the matrix.
+ * @param cols Amount of columns in the matrix.
+ * @param fastHash Whether fast hash is used.
+ */
+ public RandomMatrix(int rows, int cols, boolean fastHash) {
+ setStorage(mkStorage(rows, cols, fastHash));
+ }
+
+ /**
+ * @param rows Amount of rows in the matrix.
+ * @param cols Amount of columns in the matrix.
+ */
+ public RandomMatrix(int rows, int cols) {
+ this(rows, cols, true);
+ }
+
+ /** */
+ public RandomMatrix() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ return new RandomMatrix(rowSize(), columnSize(), fastHash);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ return new RandomMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ return new RandomVector(crd);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+
+ out.writeBoolean(fastHash);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+
+ fastHash = in.readBoolean();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseDistributedMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseDistributedMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseDistributedMatrix.java
new file mode 100644
index 0000000..5c40d70
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseDistributedMatrix.java
@@ -0,0 +1,155 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.StorageConstants;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.math.functions.IgniteFunction;
+import org.apache.ignite.math.impls.CacheUtils;
+import org.apache.ignite.math.impls.storage.matrix.SparseDistributedMatrixStorage;
+
+/**
+ * Sparse distributed matrix implementation based on data grid.
+ *
+ * Unlike {@link CacheMatrix} that is based on existing cache, this implementation creates distributed
+ * cache internally and doesn't rely on pre-existing cache.
+ *
+ * You also need to call {@link #destroy()} to remove the underlying cache when you no longer need this
+ * matrix.
+ *
+ * <b>Currently fold supports only commutative operations.<b/>
+ */
+public class SparseDistributedMatrix extends AbstractMatrix implements StorageConstants {
+ /**
+ *
+ */
+ public SparseDistributedMatrix() {
+ // No-op.
+ }
+
+ /**
+ * @param rows
+ * @param cols
+ * @param stoMode
+ * @param acsMode
+ */
+ public SparseDistributedMatrix(int rows, int cols, int stoMode, int acsMode) {
+ assert rows > 0;
+ assert cols > 0;
+ assertAccessMode(acsMode);
+ assertStorageMode(stoMode);
+
+ setStorage(new SparseDistributedMatrixStorage(rows, cols, stoMode, acsMode));
+ }
+
+ /**
+ *
+ *
+ */
+ private SparseDistributedMatrixStorage storage() {
+ return (SparseDistributedMatrixStorage)getStorage();
+ }
+
+ /**
+ * Return the same matrix with updates values (broken contract).
+ *
+ * @param d
+ */
+ @Override public Matrix divide(double d) {
+ return mapOverValues((Double v) -> v / d);
+ }
+
+ /**
+ * Return the same matrix with updates values (broken contract).
+ *
+ * @param x
+ */
+ @Override public Matrix plus(double x) {
+ return mapOverValues((Double v) -> v + x);
+ }
+
+ /**
+ * Return the same matrix with updates values (broken contract).
+ *
+ * @param x
+ */
+ @Override public Matrix times(double x) {
+ return mapOverValues((Double v) -> v * x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix assign(double val) {
+ return mapOverValues((Double v) -> val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix map(IgniteDoubleFunction<Double> fun) {
+ return mapOverValues(fun::apply);
+ }
+
+ /**
+ * @param mapper
+ */
+ private Matrix mapOverValues(IgniteFunction<Double, Double> mapper) {
+ CacheUtils.sparseMap(storage().cache().getName(), mapper);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ return CacheUtils.sparseSum(storage().cache().getName());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxValue() {
+ return CacheUtils.sparseMax(storage().cache().getName());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double minValue() {
+ return CacheUtils.sparseMin(storage().cache().getName());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseLocalOnHeapMatrix.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseLocalOnHeapMatrix.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseLocalOnHeapMatrix.java
new file mode 100644
index 0000000..cb08939
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/SparseLocalOnHeapMatrix.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.StorageConstants;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.storage.matrix.SparseLocalOnHeapMatrixStorage;
+import org.apache.ignite.math.impls.vector.SparseLocalVector;
+
+/**
+ * Sparse local onheap matrix with {@link SparseLocalVector} as rows.
+ */
+public class SparseLocalOnHeapMatrix extends AbstractMatrix implements StorageConstants {
+ /**
+ *
+ */
+ public SparseLocalOnHeapMatrix() {
+ // No-op.
+ }
+
+ /**
+ * Construct new {@link SparseLocalOnHeapMatrix}.
+ *
+ * By default storage sets in row optimized mode and in random access mode.
+ */
+ public SparseLocalOnHeapMatrix(int rows, int cols) {
+ setStorage(mkStorage(rows, cols));
+ }
+
+ /**
+ * Create new {@link SparseLocalOnHeapMatrixStorage}.
+ */
+ private MatrixStorage mkStorage(int rows, int cols) {
+ return new SparseLocalOnHeapMatrixStorage(rows, cols, StorageConstants.RANDOM_ACCESS_MODE, StorageConstants.ROW_STORAGE_MODE);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ return new SparseLocalOnHeapMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ return new SparseLocalVector(crd, StorageConstants.RANDOM_ACCESS_MODE);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ Matrix cp = like(rowSize(), columnSize());
+
+ cp.assign(this);
+
+ return cp;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/TransposedMatrixView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/TransposedMatrixView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/TransposedMatrixView.java
new file mode 100644
index 0000000..9da909b
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/TransposedMatrixView.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.matrix;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.storage.matrix.MatrixDelegateStorage;
+
+/**
+ * Implements transposed view of the parent {@link Matrix}.
+ */
+public class TransposedMatrixView extends AbstractMatrix {
+ /** */
+ public TransposedMatrixView() {
+ //No-op.
+ }
+
+ /**
+ * @param mtx Parent matrix.
+ */
+ public TransposedMatrixView(Matrix mtx) {
+ this(mtx == null ? null : mtx.getStorage());
+ }
+
+ /** */
+ private TransposedMatrixView(MatrixStorage sto) {
+ super(new MatrixDelegateStorage(sto, 0, 0,
+ sto == null ? 0 : sto.rowSize(), sto == null ? 0 : sto.columnSize()));
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void storageSet(int row, int col, double v) {
+ super.storageSet(col, row, v);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected double storageGet(int row, int col) {
+ return super.storageGet(col, row);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int rowSize() {
+ return getStorage().columnSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int columnSize() {
+ return getStorage().rowSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix copy() {
+ MatrixDelegateStorage sto = (MatrixDelegateStorage)getStorage();
+
+ return new TransposedMatrixView(sto.delegate());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix like(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector likeVector(int crd) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/package-info.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/package-info.java b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/package-info.java
new file mode 100644
index 0000000..75d7532
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/matrix/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <!-- Package description. -->
+ * Contains several matrix implementations.
+ */
+package org.apache.ignite.math.impls.matrix;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/package-info.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/package-info.java b/modules/math/src/main/java/org/apache/ignite/math/impls/package-info.java
new file mode 100644
index 0000000..f1b2e36
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * <!-- Package description. -->
+ * Contains specific implementations for core algebra.
+ */
+package org.apache.ignite.math.impls;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/ArrayMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/ArrayMatrixStorage.java b/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/ArrayMatrixStorage.java
new file mode 100644
index 0000000..eb65b1d
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/ArrayMatrixStorage.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.matrix;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+import org.apache.ignite.math.MatrixStorage;
+
+/**
+ * Array based {@link MatrixStorage} implementation.
+ */
+public class ArrayMatrixStorage implements MatrixStorage {
+ /** Backing data array. */
+ private double[][] data;
+ /** Amount of rows in the matrix. */
+ private int rows;
+ /** Amount of columns in the matrix. */
+ private int cols;
+
+ /**
+ *
+ */
+ public ArrayMatrixStorage() {
+ // No-op.
+ }
+
+ /**
+ * @param rows Amount of rows in the matrix.
+ * @param cols Amount of columns in the matrix.
+ */
+ public ArrayMatrixStorage(int rows, int cols) {
+ assert rows > 0;
+ assert cols > 0;
+
+ this.data = new double[rows][cols];
+ this.rows = rows;
+ this.cols = cols;
+ }
+
+ /**
+ * @param data Backing data array.
+ */
+ public ArrayMatrixStorage(double[][] data) {
+ assert data != null;
+ assert data[0] != null;
+
+ this.data = data;
+ this.rows = data.length;
+ this.cols = data[0].length;
+
+ assert rows > 0;
+ assert cols > 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double get(int x, int y) {
+ return data[x][y];
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSequentialAccess() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDense() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRandomAccess() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDistributed() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(int x, int y, double v) {
+ data[x][y] = v;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int columnSize() {
+ return cols;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int rowSize() {
+ return rows;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isArrayBased() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double[][] data() {
+ return data;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeInt(rows);
+ out.writeInt(cols);
+
+ out.writeObject(data);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ rows = in.readInt();
+ cols = in.readInt();
+
+ data = (double[][])in.readObject();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res += res * 37 + rows;
+ res += res * 37 + cols;
+ res += res * 37 + Arrays.deepHashCode(data);
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ ArrayMatrixStorage that = (ArrayMatrixStorage)o;
+
+ return Arrays.deepEquals(data, that.data);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/CacheMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/CacheMatrixStorage.java b/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/CacheMatrixStorage.java
new file mode 100644
index 0000000..7aefa2c
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/CacheMatrixStorage.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.matrix;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.math.MatrixKeyMapper;
+import org.apache.ignite.math.MatrixStorage;
+import org.apache.ignite.math.ValueMapper;
+
+/**
+ * Matrix storage based on arbitrary cache and key and value mapping functions.
+ */
+public class CacheMatrixStorage<K, V> implements MatrixStorage {
+ /** */ private int rows;
+ /** */ private int cols;
+ /** */ private IgniteCache<K, V> cache;
+ /** */ private MatrixKeyMapper<K> keyMapper;
+ /** */ private ValueMapper<V> valMapper;
+
+ /**
+ *
+ */
+ public CacheMatrixStorage() {
+ // No-op.
+ }
+
+ /**
+ * @param rows
+ * @param cols
+ * @param cache
+ * @param keyMapper
+ * @param valMapper
+ */
+ public CacheMatrixStorage(int rows, int cols, IgniteCache<K, V> cache, MatrixKeyMapper<K> keyMapper,
+ ValueMapper<V> valMapper) {
+ assert rows > 0;
+ assert cols > 0;
+ assert cache != null;
+ assert keyMapper != null;
+ assert valMapper != null;
+
+ this.rows = rows;
+ this.cols = cols;
+ this.cache = cache;
+ this.keyMapper = keyMapper;
+ this.valMapper = valMapper;
+ }
+
+ /**
+ * @return Ignite cache.
+ */
+ public IgniteCache<K, V> cache() {
+ return cache;
+ }
+
+ /**
+ * @return Key mapper.
+ */
+ public MatrixKeyMapper<K> keyMapper() {
+ return keyMapper;
+ }
+
+ /**
+ * @return Value mapper.
+ */
+ public ValueMapper<V> valueMapper() {
+ return valMapper;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double get(int x, int y) {
+ return valMapper.toDouble(cache.get(keyMapper.apply(x, y)));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(int x, int y, double v) {
+ cache.put(keyMapper.apply(x, y), valMapper.fromDouble(v));
+ }
+
+ /** {@inheritDoc} */
+ @Override public int columnSize() {
+ return cols;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int rowSize() {
+ return rows;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeInt(rows);
+ out.writeInt(cols);
+ out.writeUTF(cache.getName());
+ out.writeObject(keyMapper);
+ out.writeObject(valMapper);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings({"unchecked"})
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ rows = in.readInt();
+ cols = in.readInt();
+ cache = Ignition.localIgnite().getOrCreateCache(in.readUTF());
+ keyMapper = (MatrixKeyMapper<K>)in.readObject();
+ valMapper = (ValueMapper<V>)in.readObject();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSequentialAccess() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDense() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRandomAccess() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDistributed() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isArrayBased() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + rows;
+ res = res * 37 + cols;
+ res = res * 37 + cache.hashCode();
+ res = res * 37 + keyMapper.hashCode();
+ res = res * 37 + valMapper.hashCode();
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ CacheMatrixStorage that = (CacheMatrixStorage)o;
+
+ return (cache != null ? cache.equals(that.cache) : that.cache == null) &&
+ (keyMapper != null ? keyMapper.equals(that.keyMapper) : that.keyMapper == null) &&
+ (valMapper != null ? valMapper.equals(that.valMapper) : that.valMapper == null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java b/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
new file mode 100644
index 0000000..6695bc2
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/storage/matrix/DenseOffHeapMatrixStorage.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.matrix;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.math.MatrixStorage;
+
+/**
+ * Local, dense off-heap matrix storage.
+ */
+public class DenseOffHeapMatrixStorage implements MatrixStorage {
+ /** */ private int rows;
+ /** */ private int cols;
+ /** */ private transient long ptr;
+ //TODO: temp solution.
+ /** */ private int ptrInitHash;
+
+ /** */
+ public DenseOffHeapMatrixStorage() {
+ // No-op.
+ }
+
+ /** */
+ public DenseOffHeapMatrixStorage(int rows, int cols) {
+ assert rows > 0;
+ assert cols > 0;
+
+ this.rows = rows;
+ this.cols = cols;
+
+ allocateMemory(rows, cols);
+ }
+
+ /** */
+ public DenseOffHeapMatrixStorage(double[][] data) {
+ assert data != null;
+ assert data[0] != null;
+
+ this.rows = data.length;
+ this.cols = data[0].length;
+
+ assert rows > 0;
+ assert cols > 0;
+
+ allocateMemory(rows, cols);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ set(i, j, data[i][j]);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double get(int x, int y) {
+ return GridUnsafe.getDouble(pointerOffset(x, y));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(int x, int y, double v) {
+ GridUnsafe.putDouble(pointerOffset(x, y), v);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int columnSize() {
+ return cols;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSequentialAccess() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDense() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRandomAccess() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDistributed() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int rowSize() {
+ return rows;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isArrayBased() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double[][] data() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeInt(rows);
+ out.writeInt(cols);
+ out.writeInt(ptrInitHash);
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ out.writeDouble(get(i, j));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ rows = in.readInt();
+ cols = in.readInt();
+
+ allocateMemory(rows, cols);
+
+ ptrInitHash = in.readInt();
+
+ for (int i = 0; i < rows; i++)
+ for (int j = 0; j < cols; j++)
+ set(i, j, in.readDouble());
+ }
+
+ /** {@inheritDoc} */
+ @Override public void destroy() {
+ GridUnsafe.freeMemory(ptr);
+ }
+
+ /** {@inheritDoc} */
+ private long pointerOffset(int x, int y) {
+ return ptr + x * cols * Double.BYTES + y * Double.BYTES;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object obj) {
+ return obj != null &&
+ getClass().equals(obj.getClass()) &&
+ (rows == ((DenseOffHeapMatrixStorage)obj).rows) &&
+ (cols == ((DenseOffHeapMatrixStorage)obj).cols) &&
+ (rows == 0 || cols == 0 || ptr == ((DenseOffHeapMatrixStorage)obj).ptr || isMemoryEquals((DenseOffHeapMatrixStorage)obj));
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + rows;
+ res = res * 37 + cols;
+ res = res * 37 + ptrInitHash;
+
+ return res;
+ }
+
+ /** */
+ private boolean isMemoryEquals(DenseOffHeapMatrixStorage otherStorage) {
+ boolean res = true;
+
+ for (int i = 0; i < otherStorage.rows; i++) {
+ for (int j = 0; j < otherStorage.cols; j++) {
+ if (Double.compare(get(i, j), otherStorage.get(i, j)) != 0) {
+ res = false;
+ break;
+ }
+ }
+ }
+
+ return res;
+ }
+
+ /** */
+ private void allocateMemory(int rows, int cols) {
+ ptr = GridUnsafe.allocateMemory(rows * cols * Double.BYTES);
+
+ ptrInitHash = Long.hashCode(ptr);
+ }
+}