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:48 UTC
[26/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/vector/MatrixVectorView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/MatrixVectorView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/MatrixVectorView.java
new file mode 100644
index 0000000..8f32a89
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/MatrixVectorView.java
@@ -0,0 +1,139 @@
+/*
+ * 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.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.IndexException;
+import org.apache.ignite.math.impls.storage.vector.MatrixVectorStorage;
+
+/**
+ * Row or column vector view off the matrix.
+ */
+public class MatrixVectorView extends AbstractVector {
+ /** */ private Matrix parent;
+
+ /** */ private int row;
+ /** */ private int col;
+
+ /** */ private int rowStride;
+ /** */ private int colStride;
+
+ /**
+ *
+ */
+ public MatrixVectorView() {
+ // No-op.
+ }
+
+ /**
+ * @param parent
+ * @param row
+ * @param col
+ * @param rowStride
+ * @param colStride
+ */
+ public MatrixVectorView(Matrix parent, int row, int col, int rowStride, int colStride) {
+ assert parent != null;
+
+ if (row < 0 || row >= parent.rowSize())
+ throw new IndexException(row);
+ if (col < 0 || col >= parent.columnSize())
+ throw new IndexException(col);
+
+ this.parent = parent;
+
+ this.row = row;
+ this.col = col;
+
+ this.rowStride = rowStride;
+ this.colStride = colStride;
+
+ setStorage(new MatrixVectorStorage(parent, row, col, rowStride, colStride));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ return new MatrixVectorView(parent, row, col, rowStride, colStride);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ return parent.likeVector(crd);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return parent.like(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+
+ out.writeObject(parent);
+ out.writeInt(row);
+ out.writeInt(col);
+ out.writeInt(rowStride);
+ out.writeInt(colStride);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+
+ parent = (Matrix)in.readObject();
+ row = in.readInt();
+ col = in.readInt();
+ rowStride = in.readInt();
+ colStride = in.readInt();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + (parent == null ? 0 : parent.hashCode());
+ res = res * 37 + row;
+ res = res * 37 + col;
+ res = res * 37 + rowStride;
+ res = res * 37 + colStride;
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ MatrixVectorView that = (MatrixVectorView)o;
+
+ return (parent != null ? parent.equals(that.parent) : that.parent == null) &&
+ row == that.row &&
+ col == that.col &&
+ rowStride == that.rowStride &&
+ colStride == that.colStride;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/PivotedVectorView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/PivotedVectorView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/PivotedVectorView.java
new file mode 100644
index 0000000..cc9e835
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/PivotedVectorView.java
@@ -0,0 +1,163 @@
+/*
+ * 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.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+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.Functions;
+import org.apache.ignite.math.impls.storage.vector.PivotedVectorStorage;
+
+/**
+ * Pivoted (index mapped) view over another vector.
+ */
+public class PivotedVectorView extends AbstractVector {
+ /** */ private Vector vec;
+
+ /**
+ * @param vec
+ * @param pivot Mapping from external index to internal.
+ * @param unpivot Mapping from internal index to external.
+ */
+ public PivotedVectorView(Vector vec, int[] pivot, int[] unpivot) {
+ setStorage(new PivotedVectorStorage(vec.getStorage(), pivot, unpivot));
+
+ checkCardinality(pivot);
+ checkCardinality(unpivot);
+
+ this.vec = vec;
+ }
+
+ /**
+ * @param vec
+ * @param pivot
+ */
+ public PivotedVectorView(Vector vec, int[] pivot) {
+ setStorage(new PivotedVectorStorage(vec.getStorage(), pivot));
+
+ checkCardinality(pivot);
+
+ this.vec = vec;
+ }
+
+ /**
+ *
+ *
+ */
+ private PivotedVectorStorage storage() {
+ return (PivotedVectorStorage)getStorage();
+ }
+
+ /**
+ *
+ */
+ public PivotedVectorView() {
+ // No-op.
+ }
+
+ /**
+ *
+ *
+ */
+ public Vector getBaseVector() {
+ return vec;
+ }
+
+ /**
+ * @param i
+ */
+ public int pivot(int i) {
+ return storage().pivot()[i];
+ }
+
+ /**
+ * @param i
+ */
+ public int unpivot(int i) {
+ return storage().unpivot()[i];
+ }
+
+ /**
+ * @param idx
+ */
+ protected Vector.Element makeElement(int idx) {
+ checkIndex(idx);
+
+ // External index.
+ int exIdx = storage().pivot()[idx];
+
+ return new Vector.Element() {
+ /** {@inheritDoc */
+ @Override public double get() {
+ return storageGet(idx);
+ }
+
+ /** {@inheritDoc */
+ @Override public int index() {
+ return exIdx;
+ }
+
+ /** {@inheritDoc */
+ @Override public void set(double val) {
+ storageSet(idx, val);
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ PivotedVectorStorage sto = storage();
+
+ return new PivotedVectorView(vec, sto.pivot(), sto.unpivot());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return vec.likeMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ if (x == 0.0)
+ return copy().map(Functions.mult(x));
+ else
+ return super.times(x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+
+ out.writeObject(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+
+ vec = (Vector)in.readObject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/RandomVector.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/RandomVector.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/RandomVector.java
new file mode 100644
index 0000000..c9121c9
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/RandomVector.java
@@ -0,0 +1,128 @@
+/*
+ * 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.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.matrix.RandomMatrix;
+import org.apache.ignite.math.impls.storage.vector.RandomVectorStorage;
+
+/**
+ * Random vector. Each value is taken from {-1,0,1} with roughly equal probability. Note
+ * that by default, the value is determined by a relatively simple hash of the index.
+ */
+public class RandomVector extends AbstractReadOnlyVector {
+ /** */ private boolean fastHash;
+
+ /**
+ * @param size Vector cardinality.
+ * @param fastHash
+ */
+ private VectorStorage mkStorage(int size, boolean fastHash) {
+ this.fastHash = fastHash;
+
+ return new RandomVectorStorage(size, fastHash);
+ }
+
+ /**
+ * @param size
+ * @param fastHash
+ */
+ public RandomVector(int size, boolean fastHash) {
+ setStorage(mkStorage(size, fastHash));
+ }
+
+ /**
+ * @param size
+ */
+ public RandomVector(int size) {
+ this(size, true);
+ }
+
+ /**
+ * @param args
+ */
+ public RandomVector(Map<String, Object> args) {
+ assert args != null;
+
+ if (args.containsKey("size") && args.containsKey("fastHash"))
+ setStorage(mkStorage((int)args.get("size"), (boolean)args.get("fastHash")));
+ else if (args.containsKey("size"))
+ setStorage(mkStorage((int)args.get("size"), true));
+ else
+ throw new UnsupportedOperationException("Invalid constructor argument(s).");
+ }
+
+ /** */
+ public RandomVector() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public org.apache.ignite.math.Vector like(int crd) {
+ return new RandomVector(crd, fastHash);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return new RandomMatrix(rows, cols);
+ }
+
+ /** {@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();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + Boolean.hashCode(fastHash);
+ 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;
+
+ RandomVector that = (RandomVector)o;
+ VectorStorage sto = getStorage();
+
+ return fastHash == that.fastHash && (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/vector/SingleElementVector.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVector.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVector.java
new file mode 100644
index 0000000..8d19ee0
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVector.java
@@ -0,0 +1,102 @@
+/*
+ * 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.vector;
+
+import java.util.Map;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.storage.vector.SingleElementVectorStorage;
+
+/**
+ * Read-write vector holding a single non-zero value at some index.
+ */
+public class SingleElementVector extends AbstractVector {
+ /**
+ *
+ */
+ public SingleElementVector() {
+ // No-op
+ }
+
+ /**
+ * @param size
+ * @param idx
+ * @param val
+ */
+ public SingleElementVector(int size, int idx, double val) {
+ super(new SingleElementVectorStorage(size, idx, val));
+ }
+
+ /**
+ * @param args
+ */
+ public SingleElementVector(Map<String, Object> args) {
+ assert args != null;
+
+ if (args.containsKey("size") && args.containsKey("index") && args.containsKey("value")) {
+ int size = (int)args.get("size");
+ int idx = (int)args.get("index");
+ double val = (double)args.get("value");
+
+ setStorage(new SingleElementVectorStorage(size, idx, val));
+ }
+ else
+ throw new UnsupportedOperationException("Invalid constructor argument(s).");
+ }
+
+ /**
+ *
+ *
+ */
+ private SingleElementVectorStorage storage() {
+ return (SingleElementVectorStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element minElement() {
+ return makeElement(storage().index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element maxElement() {
+ return makeElement(storage().index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ return getX(storage().index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public int nonZeroElements() {
+ return isZero(get(storage().index())) ? 0 : 1;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ int idx = storage().index();
+
+ return new SingleElementVector(crd, idx, getX(idx));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVectorView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVectorView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVectorView.java
new file mode 100644
index 0000000..76a1c0a
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SingleElementVectorView.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.vector;
+
+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.Functions;
+import org.apache.ignite.math.impls.storage.vector.SingleElementVectorDelegateStorage;
+
+/**
+ * Single value vector view over another vector.
+ */
+public class SingleElementVectorView extends AbstractVector {
+ /**
+ *
+ */
+ public SingleElementVectorView() {
+ // No-op.
+ }
+
+ /**
+ * @param vec
+ * @param idx
+ */
+ public SingleElementVectorView(Vector vec, int idx) {
+ super(new SingleElementVectorDelegateStorage(vec, idx));
+ }
+
+ /**
+ *
+ *
+ */
+ private SingleElementVectorDelegateStorage storage() {
+ return (SingleElementVectorDelegateStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector.Element minElement() {
+ return makeElement(storage().index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector.Element maxElement() {
+ return makeElement(storage().index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ return getX(storage().index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public int nonZeroElements() {
+ return isZero(getX(storage().index())) ? 0 : 1;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ SingleElementVectorDelegateStorage sto = storage();
+
+ return new SingleElementVectorView(sto.delegate(), sto.index());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ if (x == 0.0)
+ return copy().map(Functions.mult(x));
+ else
+ return super.times(x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalOffHeapVector.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalOffHeapVector.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalOffHeapVector.java
new file mode 100644
index 0000000..2fd1c57
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalOffHeapVector.java
@@ -0,0 +1,47 @@
+/*
+ * 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.vector;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.storage.vector.SparseLocalOffHeapVectorStorage;
+
+/**
+ * Implementation for {@link Vector} assuming sparse logic and local offheap JVM storage.
+ * It is suitable for data sets where local, non-distributed execution is satisfactory and on-heap JVM storage
+ * is not enough to keep the entire data set.
+ * <p>See also: <a href="https://en.wikipedia.org/wiki/Sparse_array">Wikipedia article</a>.</p>
+ */
+public class SparseLocalOffHeapVector extends AbstractVector {
+ /**
+ * @param crd Vector cardinality.
+ */
+ public SparseLocalOffHeapVector(int crd) {
+ setStorage(new SparseLocalOffHeapVectorStorage(crd));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ return new SparseLocalOffHeapVector(crd);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalVector.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalVector.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalVector.java
new file mode 100644
index 0000000..ebb6731
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/SparseLocalVector.java
@@ -0,0 +1,71 @@
+/*
+ * 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.vector;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.StorageConstants;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.matrix.SparseLocalOnHeapMatrix;
+import org.apache.ignite.math.impls.storage.vector.SparseLocalOnHeapVectorStorage;
+
+/**
+ * Local on-heap sparse vector based on hash map storage.
+ */
+public class SparseLocalVector extends AbstractVector implements StorageConstants {
+ /**
+ *
+ */
+ public SparseLocalVector() {
+ // No-op.
+ }
+
+ /**
+ * @param size
+ * @param acsMode
+ */
+ public SparseLocalVector(int size, int acsMode) {
+ assertAccessMode(acsMode);
+
+ setStorage(new SparseLocalOnHeapVectorStorage(size, acsMode));
+ }
+
+ /** */
+ private SparseLocalOnHeapVectorStorage storage() {
+ return (SparseLocalOnHeapVectorStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ SparseLocalOnHeapVectorStorage sto = storage();
+
+ return new SparseLocalVector(crd, sto.getAccessMode());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return new SparseLocalOnHeapMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ if (x == 0.0)
+ return assign(0);
+ else
+ return super.times(x);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/VectorView.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/VectorView.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/VectorView.java
new file mode 100644
index 0000000..ce51a45
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/VectorView.java
@@ -0,0 +1,85 @@
+/*
+ * 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.vector;
+
+import java.io.Externalizable;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.impls.storage.vector.DelegateVectorStorage;
+
+/**
+ * Implements the partial view into the parent {@link Vector}.
+ */
+public class VectorView extends AbstractVector {
+ /**
+ * Constructor for {@link Externalizable} interface.
+ */
+ public VectorView() {
+ // No-op.
+ }
+
+ /**
+ * @param parent Backing parent {@link Vector}.
+ * @param off Offset to parent vector.
+ * @param len Size of the view.
+ */
+ public VectorView(Vector parent, int off, int len) {
+ super(new DelegateVectorStorage(parent.getStorage(), off, len));
+ }
+
+ /**
+ * @param sto Backing parent {@link VectorStorage}.
+ * @param off Offset to parent vector.
+ * @param len Size of the view.
+ */
+ public VectorView(VectorStorage sto, int off, int len) {
+ super(new DelegateVectorStorage(sto, off, len));
+ }
+
+ /** */
+ private DelegateVectorStorage storage() {
+ return (DelegateVectorStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ DelegateVectorStorage sto = storage();
+
+ return new VectorView(sto.delegate(), sto.offset(), sto.length());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ return this == o ||
+ ((o != null)
+ && o.getClass() == getClass()
+ && (getStorage().equals(((VectorView)o).getStorage())));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/java/org/apache/ignite/math/impls/vector/package-info.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/impls/vector/package-info.java b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/package-info.java
new file mode 100644
index 0000000..d6ca1f3
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/impls/vector/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 vectors.
+ */
+package org.apache.ignite.math.impls.vector;
\ 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/package-info.java
----------------------------------------------------------------------
diff --git a/modules/math/src/main/java/org/apache/ignite/math/package-info.java b/modules/math/src/main/java/org/apache/ignite/math/package-info.java
new file mode 100644
index 0000000..05ce651
--- /dev/null
+++ b/modules/math/src/main/java/org/apache/ignite/math/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 main APIs for distributed code algebra.
+ */
+package org.apache.ignite.math;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/resources/org/apache/ignite/math/d3-matrix-template.html
----------------------------------------------------------------------
diff --git a/modules/math/src/main/resources/org/apache/ignite/math/d3-matrix-template.html b/modules/math/src/main/resources/org/apache/ignite/math/d3-matrix-template.html
new file mode 100644
index 0000000..19a907a
--- /dev/null
+++ b/modules/math/src/main/resources/org/apache/ignite/math/d3-matrix-template.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<meta charset="utf-8">
+<title>IgniteML</title>
+<style>
+ body {
+ margin: 0 15px;
+ }
+
+ p {
+ margin: 10px 0 !important;
+ }
+
+ .name {
+ font-size: 20px;
+ font-weight: 400;
+ font-family: monospace;
+ }
+
+ .swatch {
+ display: inline-block;
+ width: 25px;
+ height: 25px;
+ margin-left: 5px;
+ vertical-align: bottom;
+ }
+</style>
+<body>
+<img style="margin-top: 15px" width="100px" src="https://ignite.apache.org/images/logo3.png">
+<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
+<script>
+ /*@DATA@*/
+ var data = [[{d: 2.256, r: 198, g: 128, b: 128}, {d: 0.123, r: 218, g: 228, b: 18}], [{
+ d: 2.256,
+ r: 108,
+ g: 28,
+ b: 108
+ }, {d: 0.123, r: 228, g: 228, b: 228}]];
+ /*@MAX@*/
+ var max = {d: 2.256, r: 128, g: 128, b: 128};
+ /*@MIN@*/
+ var min = {d: 0.123, r: 228, g: 228, b: 228};
+ /*@NAME@*/
+ var name = "Matrix";
+
+ var rows = data.length;
+ var cols = data[0].length;
+
+ var range = max.d - min.d;
+
+ var rw, rh;
+ var W, H;
+
+ if (cols > W) {
+ rw = 1;
+ W = cols;
+ }
+ else {
+ W = 1000;
+ rw = Math.min(Math.round(W / cols), 10);
+ }
+
+ if (rows > H) {
+ rh = 1;
+ H = rows;
+ }
+ else {
+ H = 1000;
+ rh = Math.min(Math.round(H / rows), 10);
+ }
+
+ d3.selectAll("body")
+ .append("p")
+ .text(name + " (" + rows + "x" + cols + ")")
+ .attr("class", "name");
+
+ d3.selectAll("body")
+ .append("p")
+ .attr("class", "name")
+ .text("Max: " + max.d)
+ .append("span")
+ .attr("class", "swatch")
+ .attr("style", "background-color: rgb(" + max.r + ", " + max.g + ", " + max.b + ")");
+
+ d3.selectAll("body")
+ .append("p")
+ .attr("class", "name")
+ .text("Min: " + min.d)
+ .append("span")
+ .attr("class", "swatch")
+ .attr("style", "background-color: rgb(" + min.r + ", " + min.g + ", " + min.b + ")");
+
+ var svg = d3.select("body").append("svg")
+ .attr("width", W)
+ .attr("height", H);
+
+ var y = 0;
+
+ for (var row = 0; row < rows; row++)
+ svg.selectAll("div")
+ .data(data[row])
+ .enter()
+ .append("rect")
+ .attr("x", function (d, i) {
+ return i * rw
+ })
+ .attr("y", rh * row)
+ .attr("fill", function (d) {
+ return "rgb(" + d.r + ", " + d.g + ", " + d.b + ")";
+ })
+ .attr("width", rw)
+ .attr("height", rh);
+</script>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/main/resources/org/apache/ignite/math/d3-vector-template.html
----------------------------------------------------------------------
diff --git a/modules/math/src/main/resources/org/apache/ignite/math/d3-vector-template.html b/modules/math/src/main/resources/org/apache/ignite/math/d3-vector-template.html
new file mode 100644
index 0000000..7644481
--- /dev/null
+++ b/modules/math/src/main/resources/org/apache/ignite/math/d3-vector-template.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<!--
+ 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.
+-->
+<meta charset="utf-8">
+<title>IgniteML</title>
+<style>
+ body {
+ margin: 0 15px;
+ }
+
+ p {
+ margin: 10px 0 !important;
+ }
+
+ .name {
+ font-size: 20px;
+ font-weight: 400;
+ font-family: monospace;
+ }
+
+ .swatch {
+ display: inline-block;
+ width: 25px;
+ height: 25px;
+ margin-left: 5px;
+ vertical-align: bottom;
+ }
+</style>
+<body>
+<img style="margin-top: 15px" width="100px" src="https://ignite.apache.org/images/logo3.png">
+<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
+<script>
+ /*@DATA@*/
+ var data = [{d: 2.256, r: 128, g: 128, b: 128}, {d: 0.123, r: 228, g: 228, b: 228}];
+ /*@MAX@*/
+ var max = {d: 2.256, r: 128, g: 128, b: 128};
+ /*@MIN@*/
+ var min = {d: 0.123, r: 228, g: 228, b: 228};
+ /*@NAME@*/
+ var name = "Vector";
+
+ var W, H = 1000;
+
+ var range = max.d - min.d;
+
+ var rh = 20; // Constant.
+
+ var rw;
+
+ if (data.length > W) {
+ rw = 1;
+ W = data.length;
+ }
+ else {
+ W = 1000;
+ rw = Math.min(Math.round(W / data.length), 5);
+ }
+
+ d3.selectAll("body")
+ .append("p")
+ .text(name + " (size: " + data.length + ")")
+ .attr("class", "name");
+
+ d3.selectAll("body")
+ .append("p")
+ .attr("class", "name")
+ .text("Max: " + max.d)
+ .append("span")
+ .attr("class", "swatch")
+ .attr("style", "background-color: rgb(" + max.r + ", " + max.g + ", " + max.b + ")");
+
+ d3.selectAll("body")
+ .append("p")
+ .attr("class", "name")
+ .text("Min: " + min.d)
+ .append("span")
+ .attr("class", "swatch")
+ .attr("style", "background-color: rgb(" + min.r + ", " + min.g + ", " + min.b + ")");
+
+ var svg = d3.select("body").append("svg")
+ .attr("width", W)
+ .attr("height", H);
+
+ svg.selectAll("rect")
+ .data(data)
+ .enter()
+ .append("rect")
+ .attr("x", function (d, i) {
+ return i * rw
+ })
+ .attr("y", 10)
+ .attr("fill", function (d) {
+ return "rgb(" + d.r + ", " + d.g + ", " + d.b + ")";
+ })
+ .attr("width", rw)
+ .attr("height", rh);
+</script>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/ExternalizeTest.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/ExternalizeTest.java b/modules/math/src/test/java/org/apache/ignite/math/ExternalizeTest.java
new file mode 100644
index 0000000..218b7ff
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/ExternalizeTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import org.apache.ignite.math.impls.MathTestConstants;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Common test for externalization.
+ */
+public abstract class ExternalizeTest<T extends Externalizable & Destroyable> {
+ /** */
+ protected void externalizeTest(T initObj) {
+ T objRestored = null;
+
+ try {
+ ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream();
+ ObjectOutputStream objOutputStream = new ObjectOutputStream(byteArrOutputStream);
+
+ objOutputStream.writeObject(initObj);
+
+ ByteArrayInputStream byteArrInputStream = new ByteArrayInputStream(byteArrOutputStream.toByteArray());
+ ObjectInputStream objInputStream = new ObjectInputStream(byteArrInputStream);
+
+ objRestored = (T)objInputStream.readObject();
+
+ assertTrue(MathTestConstants.VAL_NOT_EQUALS, initObj.equals(objRestored));
+ assertTrue(MathTestConstants.VAL_NOT_EQUALS, Integer.compare(initObj.hashCode(), objRestored.hashCode()) == 0);
+ }
+ catch (ClassNotFoundException | IOException e) {
+ fail(e + " [" + e.getMessage() + "]");
+ }
+ finally {
+ if (objRestored != null)
+ objRestored.destroy();
+ }
+ }
+
+ /** */
+ @Test
+ public abstract void externalizeTest();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/MathImplDistributedTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/MathImplDistributedTestSuite.java b/modules/math/src/test/java/org/apache/ignite/math/MathImplDistributedTestSuite.java
new file mode 100644
index 0000000..318ea95
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/MathImplDistributedTestSuite.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+import org.apache.ignite.math.impls.matrix.CacheMatrixTest;
+import org.apache.ignite.math.impls.matrix.SparseDistributedMatrixTest;
+import org.apache.ignite.math.impls.storage.matrix.SparseDistributedMatrixStorageTest;
+import org.apache.ignite.math.impls.vector.CacheVectorTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for all distributed tests located in org.apache.ignite.math.impls.* package.
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ CacheVectorTest.class,
+ CacheMatrixTest.class,
+ SparseDistributedMatrixStorageTest.class,
+ SparseDistributedMatrixTest.class,
+})
+public class MathImplDistributedTestSuite {
+ // No-op.
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/MathImplLocalTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/MathImplLocalTestSuite.java b/modules/math/src/test/java/org/apache/ignite/math/MathImplLocalTestSuite.java
new file mode 100644
index 0000000..a652e7f
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/MathImplLocalTestSuite.java
@@ -0,0 +1,123 @@
+/*
+ * 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;
+
+import org.apache.ignite.math.decompositions.CholeskyDecompositionTest;
+import org.apache.ignite.math.decompositions.EigenDecompositionTest;
+import org.apache.ignite.math.decompositions.LUDecompositionTest;
+import org.apache.ignite.math.decompositions.QRDecompositionTest;
+import org.apache.ignite.math.decompositions.SingularValueDecompositionTest;
+import org.apache.ignite.math.impls.matrix.DenseLocalOffHeapMatrixConstructorTest;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrixConstructorTest;
+import org.apache.ignite.math.impls.matrix.DiagonalMatrixTest;
+import org.apache.ignite.math.impls.matrix.FunctionMatrixConstructorTest;
+import org.apache.ignite.math.impls.matrix.MatrixAttributeTest;
+import org.apache.ignite.math.impls.matrix.MatrixImplementationsTest;
+import org.apache.ignite.math.impls.matrix.MatrixViewConstructorTest;
+import org.apache.ignite.math.impls.matrix.PivotedMatrixViewConstructorTest;
+import org.apache.ignite.math.impls.matrix.RandomMatrixConstructorTest;
+import org.apache.ignite.math.impls.matrix.SparseLocalOnHeapMatrixConstructorTest;
+import org.apache.ignite.math.impls.matrix.TransposedMatrixViewTest;
+import org.apache.ignite.math.impls.storage.matrix.MatrixArrayStorageTest;
+import org.apache.ignite.math.impls.storage.matrix.MatrixOffHeapStorageTest;
+import org.apache.ignite.math.impls.storage.matrix.MatrixStorageImplementationTest;
+import org.apache.ignite.math.impls.storage.vector.RandomAccessSparseVectorStorageTest;
+import org.apache.ignite.math.impls.storage.vector.SparseLocalOffHeapVectorStorageTest;
+import org.apache.ignite.math.impls.storage.vector.VectorArrayStorageTest;
+import org.apache.ignite.math.impls.storage.vector.VectorOffheapStorageTest;
+import org.apache.ignite.math.impls.vector.AbstractVectorTest;
+import org.apache.ignite.math.impls.vector.ConstantVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.DelegatingVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.DenseLocalOffHeapVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.FunctionVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.MatrixVectorViewTest;
+import org.apache.ignite.math.impls.vector.PivotedVectorViewConstructorTest;
+import org.apache.ignite.math.impls.vector.RandomVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.SingleElementVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.SingleElementVectorViewConstructorTest;
+import org.apache.ignite.math.impls.vector.SparseLocalVectorConstructorTest;
+import org.apache.ignite.math.impls.vector.VectorAttributesTest;
+import org.apache.ignite.math.impls.vector.VectorFoldMapTest;
+import org.apache.ignite.math.impls.vector.VectorImplementationsTest;
+import org.apache.ignite.math.impls.vector.VectorIterableTest;
+import org.apache.ignite.math.impls.vector.VectorNormTest;
+import org.apache.ignite.math.impls.vector.VectorToMatrixTest;
+import org.apache.ignite.math.impls.vector.VectorViewTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for all local tests located in org.apache.ignite.math.impls.* package.
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ // Vector constructors tests.
+ DenseLocalOnHeapVectorConstructorTest.class,
+ DenseLocalOffHeapVectorConstructorTest.class,
+ SparseLocalVectorConstructorTest.class,
+ RandomVectorConstructorTest.class,
+ ConstantVectorConstructorTest.class,
+ FunctionVectorConstructorTest.class,
+ SingleElementVectorConstructorTest.class,
+ PivotedVectorViewConstructorTest.class,
+ SingleElementVectorViewConstructorTest.class,
+ DelegatingVectorConstructorTest.class,
+ // Various vectors tests.
+ AbstractVectorTest.class,
+ VectorImplementationsTest.class,
+ VectorViewTest.class,
+ MatrixVectorViewTest.class,
+ // Vector particular features tests.
+ VectorIterableTest.class,
+ VectorAttributesTest.class,
+ VectorToMatrixTest.class,
+ VectorNormTest.class,
+ VectorFoldMapTest.class,
+ // Vector storage tests
+ VectorArrayStorageTest.class,
+ VectorOffheapStorageTest.class,
+ RandomAccessSparseVectorStorageTest.class,
+ SparseLocalOffHeapVectorStorageTest.class,
+ // Matrix storage tests.
+ MatrixStorageImplementationTest.class,
+ MatrixOffHeapStorageTest.class,
+ MatrixArrayStorageTest.class,
+ // Matrix constructors tests.
+ DenseLocalOnHeapMatrixConstructorTest.class,
+ DenseLocalOffHeapMatrixConstructorTest.class,
+ RandomMatrixConstructorTest.class,
+ FunctionMatrixConstructorTest.class,
+ MatrixViewConstructorTest.class,
+ PivotedMatrixViewConstructorTest.class,
+ SparseLocalOnHeapMatrixConstructorTest.class,
+ // Matrix tests.
+ MatrixImplementationsTest.class,
+ DiagonalMatrixTest.class,
+ MatrixAttributeTest.class,
+ TransposedMatrixViewTest.class,
+ // Decomposes
+ LUDecompositionTest.class,
+ EigenDecompositionTest.class,
+ CholeskyDecompositionTest.class,
+ QRDecompositionTest.class,
+ SingularValueDecompositionTest.class
+})
+public class MathImplLocalTestSuite {
+ // No-op.
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/MathImplMainTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/MathImplMainTestSuite.java b/modules/math/src/test/java/org/apache/ignite/math/MathImplMainTestSuite.java
new file mode 100644
index 0000000..44fa8e6
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/MathImplMainTestSuite.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for local and distributed tests
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ MathImplLocalTestSuite.class,
+ MathImplDistributedTestSuite.class
+})
+public class MathImplMainTestSuite {
+ // No-op.
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/TracerTest.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/TracerTest.java b/modules/math/src/test/java/org/apache/ignite/math/TracerTest.java
new file mode 100644
index 0000000..35d2f60
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/TracerTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Optional;
+import org.apache.ignite.math.impls.MathTestConstants;
+import org.apache.ignite.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+import org.junit.Test;
+
+import static java.nio.file.Files.createTempFile;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link Tracer}.
+ */
+public class TracerTest {
+ /** */ private static final String DEFAULT_FORMAT = "%.10f";
+ /** */ private static final double DEFAULT_DELTA = 0.000000001d;
+
+ /**
+ * Color mapper that maps [0, 1] range into three distinct RGB segments.
+ */
+ private static final Tracer.ColorMapper COLOR_MAPPER = new Tracer.ColorMapper() {
+ /** {@inheritDoc} */
+ @Override public Color apply(Double d) {
+ if (d <= 0.33)
+ return Color.RED;
+ else if (d <= 0.66)
+ return Color.GREEN;
+ else
+ return Color.BLUE;
+ }
+ };
+
+ /**
+ * @param size Vector size.
+ */
+ private Vector makeRandomVector(int size) {
+ DenseLocalOnHeapVector vec = new DenseLocalOnHeapVector(size);
+
+ vec.assign((idx) -> Math.random());
+
+ return vec;
+ }
+
+ /**
+ * @param rows Amount of rows in matrix.
+ * @param cols Amount of columns in matrix.
+ */
+ private Matrix makeRandomMatrix(int rows, int cols) {
+ DenseLocalOnHeapMatrix mtx = new DenseLocalOnHeapMatrix(rows, cols);
+
+ // Missing assign(f)?
+ mtx.map((d) -> Math.random());
+
+ return mtx;
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testAsciiVectorTracer() {
+ Vector vec = makeRandomVector(20);
+
+ Tracer.showAscii(vec);
+ Tracer.showAscii(vec, "%2f");
+ Tracer.showAscii(vec, "%.3g");
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testAsciiMatrixTracer() {
+ Matrix mtx = makeRandomMatrix(10, 10);
+
+ Tracer.showAscii(mtx);
+ Tracer.showAscii(mtx, "%2f");
+ Tracer.showAscii(mtx, "%.3g");
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testHtmlVectorTracer() throws IOException {
+ Vector vec1 = makeRandomVector(1000);
+
+ // Default color mapping.
+ Tracer.showHtml(vec1);
+
+ // Custom color mapping.
+ Tracer.showHtml(vec1, COLOR_MAPPER);
+
+ // Default color mapping with sorted vector.
+ Tracer.showHtml(vec1.sort());
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testHtmlMatrixTracer() throws IOException {
+ Matrix mtx1 = makeRandomMatrix(100, 100);
+
+ // Custom color mapping.
+ Tracer.showHtml(mtx1, COLOR_MAPPER);
+
+ Matrix mtx2 = new DenseLocalOnHeapMatrix(100, 100);
+
+ double MAX = (double)(mtx2.rowSize() * mtx2.columnSize());
+
+ mtx2.assign((x, y) -> (double)(x * y) / MAX);
+
+ Tracer.showHtml(mtx2);
+ }
+
+ /** */
+ @Test
+ public void testWriteVectorToCSVFile() throws IOException {
+ DenseLocalOnHeapVector vector = new DenseLocalOnHeapVector(MathTestConstants.STORAGE_SIZE);
+
+ for (int i = 0; i < vector.size(); i++)
+ vector.set(i, Math.random());
+
+ Path file = createTempFile("vector", ".csv");
+
+ Tracer.saveAsCsv(vector, DEFAULT_FORMAT, file.toString());
+
+ System.out.println("Vector exported: " + file.getFileName());
+
+ List<String> strings = Files.readAllLines(file);
+ Optional<String> reduce = strings.stream().reduce((s1, s2) -> s1 + s2);
+ String[] csvVals = reduce.get().split(",");
+
+ for (int i = 0; i < vector.size(); i++) {
+ Double csvVal = Double.valueOf(csvVals[i]);
+
+ assertEquals("Unexpected value.", csvVal, vector.get(i), DEFAULT_DELTA);
+ }
+
+ Files.deleteIfExists(file);
+ }
+
+ /** */
+ @Test
+ public void testWriteMatrixToCSVFile() throws IOException {
+ DenseLocalOnHeapMatrix matrix = new DenseLocalOnHeapMatrix(MathTestConstants.STORAGE_SIZE, MathTestConstants.STORAGE_SIZE);
+
+ for (int i = 0; i < matrix.rowSize(); i++)
+ for (int j = 0; j < matrix.columnSize(); j++)
+ matrix.set(i, j, Math.random());
+
+ Path file = createTempFile("matrix", ".csv");
+
+ Tracer.saveAsCsv(matrix, DEFAULT_FORMAT, file.toString());
+
+ System.out.println("Matrix exported: " + file.getFileName());
+
+ List<String> strings = Files.readAllLines(file);
+ Optional<String> reduce = strings.stream().reduce((s1, s2) -> s1 + s2);
+ String[] csvVals = reduce.get().split(",");
+
+ for (int i = 0; i < matrix.rowSize(); i++)
+ for (int j = 0; j < matrix.columnSize(); j++) {
+ Double csvVal = Double.valueOf(csvVals[i * matrix.rowSize() + j]);
+
+ assertEquals("Unexpected value.", csvVal, matrix.get(i, j), DEFAULT_DELTA);
+ }
+
+ Files.deleteIfExists(file);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmark.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmark.java b/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmark.java
new file mode 100644
index 0000000..4c3718a
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmark.java
@@ -0,0 +1,205 @@
+/*
+ * 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.benchmark;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/** Refer {@link MathBenchmarkSelfTest} for usage examples. */
+class MathBenchmark {
+ /** */
+ private final boolean outputToConsole;
+
+ /** */
+ private final String benchmarkName;
+
+ /** */
+ private final int measurementTimes;
+
+ /** */
+ private final int warmUpTimes;
+
+ /** */
+ private final String tag;
+
+ /** */
+ private final String comments;
+
+ /** Constructor strictly for use within this class. */
+ private MathBenchmark(String benchmarkName, boolean outputToConsole, int measurementTimes, int warmUpTimes,
+ String tag, String comments) {
+ this.benchmarkName = benchmarkName;
+ this.outputToConsole = outputToConsole;
+ this.measurementTimes = measurementTimes;
+ this.warmUpTimes = warmUpTimes;
+ this.tag = tag;
+ this.comments = comments;
+ validate();
+ }
+
+ /**
+ * Benchmark with specified name and default parameters, in particular, default output file.
+ *
+ * @param benchmarkName name
+ */
+ MathBenchmark(String benchmarkName) {
+ this(benchmarkName, false, 100, 1, "", "");
+ }
+
+ /**
+ * Executes the code using config of this benchmark.
+ *
+ * @param code code to execute
+ * @throws Exception if something goes wrong
+ */
+ void execute(BenchmarkCode code) throws Exception {
+ System.out.println("Started benchmark [" + benchmarkName + "].");
+
+ for (int cnt = 0; cnt < warmUpTimes; cnt++)
+ code.call();
+
+ final long start = System.currentTimeMillis();
+
+ for (int cnt = 0; cnt < measurementTimes; cnt++)
+ code.call();
+
+ final long end = System.currentTimeMillis();
+
+ writeResults(formatResults(start, end));
+
+ System.out.println("Finished benchmark [" + benchmarkName + "].");
+ }
+
+ /**
+ * Set optional output mode for using stdout.
+ *
+ * @return configured benchmark
+ */
+ MathBenchmark outputToConsole() {
+ return new MathBenchmark(benchmarkName, true, measurementTimes, warmUpTimes, tag, comments);
+ }
+
+ /**
+ * Set optional measurement times.
+ *
+ * @param param times
+ * @return configured benchmark
+ */
+ MathBenchmark measurementTimes(int param) {
+ return new MathBenchmark(benchmarkName, outputToConsole, param, warmUpTimes, tag, comments);
+ }
+
+ /**
+ * Set optional warm-up times.
+ *
+ * @param param times
+ * @return configured benchmark
+ */
+ MathBenchmark warmUpTimes(int param) {
+ return new MathBenchmark(benchmarkName, outputToConsole, measurementTimes, param, tag, comments);
+ }
+
+ /**
+ * Set optional tag to help filtering specific kind of benchmark results.
+ *
+ * @param param name
+ * @return configured benchmark
+ */
+ MathBenchmark tag(String param) {
+ return new MathBenchmark(benchmarkName, outputToConsole, measurementTimes, warmUpTimes, param, comments);
+ }
+
+ /**
+ * Set optional comments.
+ *
+ * @param param name
+ * @return configured benchmark
+ */
+ MathBenchmark comments(String param) {
+ return new MathBenchmark(benchmarkName, outputToConsole, measurementTimes, warmUpTimes, tag, param);
+ }
+
+ /** */
+ private void writeResults(String results) throws Exception {
+ if (outputToConsole) {
+ System.out.println(results);
+
+ return;
+ }
+
+ new ResultsWriter().append(results);
+ }
+
+ /** */
+ private String formatResults(long start, long end) {
+ final String delim = ",";
+
+ assert !formatDouble(1000_000_001.1).contains(delim) : "Formatted results contain [" + delim + "].";
+
+ final String ts = formatTs(start);
+
+ assert !ts.contains(delim) : "Formatted timestamp contains [" + delim + "].";
+
+ return benchmarkName +
+ delim +
+ ts + // IMPL NOTE timestamp
+ delim +
+ formatDouble((double)(end - start) / measurementTimes) +
+ delim +
+ measurementTimes +
+ delim +
+ warmUpTimes +
+ delim +
+ tag +
+ delim +
+ comments;
+ }
+
+ /** */
+ private String formatDouble(double val) {
+ return String.format(Locale.US, "%f", val);
+ }
+
+ /** */
+ private String formatTs(long ts) {
+ final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+
+ sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ return sdf.format(new Date(ts));
+ }
+
+ /** */
+ private void validate() {
+ if (benchmarkName == null || benchmarkName.isEmpty())
+ throw new IllegalArgumentException("Invalid benchmark name: [" + benchmarkName + "].");
+
+ if (measurementTimes < 1)
+ throw new IllegalArgumentException("Invalid measurement times: [" + measurementTimes + "].");
+ }
+
+ /** */
+ interface BenchmarkCode {
+ // todo find out why Callable<Void> failed to work here
+
+ /** */
+ void call() throws Exception;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmarkSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmarkSelfTest.java b/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmarkSelfTest.java
new file mode 100644
index 0000000..7a86461
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/benchmark/MathBenchmarkSelfTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.benchmark;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/** */
+public class MathBenchmarkSelfTest {
+ /** */
+ @Test
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void demoTest() throws Exception {
+ for (int i = 0; i < 2; i++)
+ new MathBenchmark("demo test")
+ .outputToConsole() // IMPL NOTE this is to write output into console instead of a file
+ .tag(null) // IMPL NOTE try null for tag, expect it to be formatted reasonably
+ .comments(null) // IMPL NOTE try null for comments, expect it to be formatted reasonably
+ .execute(() -> {
+ double seed = 1.1;
+
+ for (int cnt = 0; cnt < 1000; cnt++) {
+ seed = Math.pow(seed, 2);
+
+ assertTrue(seed > 0);
+ }
+ });
+ }
+
+ /** */
+ @Test
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void configTest() throws Exception {
+ new MathBenchmark("demo config test")
+ .outputToConsole()
+ .measurementTimes(2)
+ .warmUpTimes(0)
+ .tag("demo tag")
+ .comments("demo comments")
+ .execute(() -> System.out.println("config test"));
+ }
+
+ /** */
+ @Test(expected = IllegalArgumentException.class)
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void emptyNameTest() throws Exception {
+ new MathBenchmark("")
+ .outputToConsole()
+ .measurementTimes(1)
+ .warmUpTimes(1)
+ .tag("empty name test tag")
+ .comments("empty name test comments")
+ .execute(() -> System.out.println("empty name test"));
+ }
+
+ /** */
+ @Test(expected = IllegalArgumentException.class)
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void nullDropboxPathTest() throws Exception {
+ new ResultsWriter(null, "whatever", "whatever");
+ }
+
+ /** */
+ @Test(expected = IllegalArgumentException.class)
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void nullDropboxUrlTest() throws Exception {
+ new ResultsWriter("whatever", null, "whatever");
+ }
+
+ /** */
+ @Test(expected = IllegalArgumentException.class)
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void nullDropboxTokenTest() throws Exception {
+ new ResultsWriter("whatever", "whatever", null);
+ }
+
+ /** */
+ @Test(expected = IllegalArgumentException.class)
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void nullResultsTest() throws Exception {
+ new ResultsWriter("whatever", "whatever", "whatever").append(null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/benchmark/ResultsWriter.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/benchmark/ResultsWriter.java b/modules/math/src/test/java/org/apache/ignite/math/benchmark/ResultsWriter.java
new file mode 100644
index 0000000..aeec156
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/benchmark/ResultsWriter.java
@@ -0,0 +1,127 @@
+/*
+ * 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.benchmark;
+
+import com.dropbox.core.DbxException;
+import com.dropbox.core.DbxRequestConfig;
+import com.dropbox.core.v2.DbxClientV2;
+import com.dropbox.core.v2.files.WriteMode;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.UUID;
+
+/** */
+class ResultsWriter {
+ /** */
+ private static final String DROPBOX_PATH
+ = "/benchmarks/math.benchmark.results.csv";
+
+ /** */
+ private static final String DROPBOX_URL
+ = "https://www.dropbox.com/s/r7tcle31r7gaty8/math.benchmark.results.csv";
+
+ /** */
+ private static final String ACCESS_TOKEN
+ = "1MMmQjEyzGAAAAAAAAAAfDFrQ6oBPPi4NX-iU_VrgmXB2JDXqRHGa125cTkkEQ0V";
+
+ /** */
+ private final String dropboxPath;
+ /** */
+ private final String dropboxUrl;
+ /** */
+ private final String accessTok;
+
+ /** */
+ ResultsWriter(String dropboxPath, String dropboxUrl, String accessTok) {
+ this.dropboxPath = dropboxPath;
+ this.dropboxUrl = dropboxUrl;
+ this.accessTok = accessTok;
+
+ if (dropboxPath == null || dropboxUrl == null || accessTok == null)
+ throw new IllegalArgumentException("Neither of dropbox path, URL, access token can be null.");
+ }
+
+ /** **/
+ ResultsWriter() {
+ this(DROPBOX_PATH, DROPBOX_URL, ACCESS_TOKEN);
+ }
+
+ /** */
+ void append(String res) throws DbxException, IOException {
+ if (res == null)
+ throw new IllegalArgumentException("benchmark result is null");
+
+ if (dropboxPath == null) {
+ System.out.println(res);
+
+ return;
+ }
+
+ append(res, client());
+ }
+
+ /** */
+ private void append(String res, DbxClientV2 client) throws DbxException, IOException {
+ File tmp = createTmpFile();
+
+ try (FileOutputStream out = new FileOutputStream(tmp)) {
+ client.files().download(dropboxPath).download(out);
+ }
+
+ writeResults(res, tmp);
+
+ try (FileInputStream in = new FileInputStream(tmp)) {
+ client.files().uploadBuilder(dropboxPath).withMode(WriteMode.OVERWRITE).uploadAndFinish(in);
+ }
+
+ if (!tmp.delete())
+ System.out.println("Failed to delete " + tmp.getAbsolutePath());
+
+ System.out.println("Uploaded benchmark results to: " + dropboxUrl);
+ }
+
+ /** */
+ private void writeResults(String res, File tmp) throws IOException {
+ final String unixLineSeparator = "\n";
+
+ try (final PrintWriter writer = new PrintWriter(Files.newBufferedWriter(Paths.get(tmp.toURI()),
+ StandardOpenOption.APPEND, StandardOpenOption.CREATE))) {
+ writer.write(res + unixLineSeparator);
+ }
+ }
+
+ /** */
+ private File createTmpFile() throws IOException {
+ File tmp = File.createTempFile(UUID.randomUUID().toString(), ".csv");
+
+ tmp.deleteOnExit();
+
+ return tmp;
+ }
+
+ /** */
+ private DbxClientV2 client() {
+ return new DbxClientV2(DbxRequestConfig.newBuilder("dropbox/MathBenchmark").build(), accessTok);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/benchmark/VectorBenchmarkTest.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/benchmark/VectorBenchmarkTest.java b/modules/math/src/test/java/org/apache/ignite/math/benchmark/VectorBenchmarkTest.java
new file mode 100644
index 0000000..1f7b204
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/benchmark/VectorBenchmarkTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.benchmark;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.vector.DenseLocalOffHeapVector;
+import org.apache.ignite.math.impls.vector.DenseLocalOnHeapVector;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/** */
+public class VectorBenchmarkTest {
+ // todo add benchmarks for other methods in Vector and for other types of Vector and Matrix
+
+ /** */
+ @Test
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void testDenseLocalOnHeapVector() throws Exception {
+ benchmark("DenseLocalOnHeapVector basic mix", DenseLocalOnHeapVector::new, this::basicMix);
+
+ benchmark("DenseLocalOnHeapVector fold map", DenseLocalOnHeapVector::new, this::foldMapMix);
+ }
+
+ /** */
+ @Test
+ @Ignore("Benchmark tests are intended only for manual execution")
+ public void testDenseLocalOffHeapVector() throws Exception {
+ benchmark("DenseLocalOffHeapVector basic mix", DenseLocalOffHeapVector::new, this::basicMix);
+
+ benchmark("DenseLocalOffHeapVector fold map", DenseLocalOffHeapVector::new, this::foldMapMix);
+ }
+
+ /** */
+ private void benchmark(String namePrefix, Function<Integer, Vector> constructor,
+ BiConsumer<Integer, Function<Integer, Vector>> consumer) throws Exception {
+ assertNotNull(namePrefix);
+
+ new MathBenchmark(namePrefix + " small sizes").execute(() -> {
+ for (int size : new int[] {2, 3, 4, 5, 6, 7})
+ consumer.accept(size, constructor);
+ });
+
+ new MathBenchmark(namePrefix + " sizes powers of 2").execute(() -> {
+ for (int power : new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14})
+ consumer.accept(1 << power, constructor);
+ });
+
+ new MathBenchmark(namePrefix + " large sizes").execute(() -> {
+ for (int power : new int[] {10, 12, 14, 16})
+ for (int delta : new int[] {-1, 0, 1})
+ consumer.accept((1 << power) + delta, constructor);
+ });
+
+ new MathBenchmark(namePrefix + " extra large sizes")
+ .measurementTimes(10)
+ .execute(() -> { // IMPL NOTE trying below with power 22 almost killed my IDEA and laptop
+ for (int power : new int[] {17, 18, 19, 20, 21})
+ for (int delta : new int[] {-1, 0}) // IMPL NOTE delta +1 is not intended for use here
+ consumer.accept((1 << power) + delta, constructor);
+ });
+ }
+
+ /** */
+ private void basicMix(int size, Function<Integer, Vector> constructor) {
+ final Vector v1 = constructor.apply(size), v2 = constructor.apply(size);
+
+ for (int idx = 0; idx < size; idx++) {
+ v1.set(idx, idx);
+
+ v2.set(idx, size - idx);
+ }
+
+ assertNotNull(v1.sum());
+
+ assertNotNull(v1.copy());
+
+ assertFalse(v1.getLengthSquared() < 0);
+
+ assertNotNull(v1.normalize());
+
+ assertNotNull(v1.logNormalize());
+
+ assertFalse(v1.getDistanceSquared(v2) < 0);
+
+ assertNotNull(v1.divide(2));
+
+ assertNotNull(v1.minus(v2));
+
+ assertNotNull(v1.plus(v2));
+
+ assertNotNull(v1.dot(v2));
+
+ assertNotNull(v1.assign(v2));
+
+ assertNotNull(v1.assign(1)); // IMPL NOTE this would better be last test for it sets all values the same
+ }
+
+ /** */
+ private void foldMapMix(int size, Function<Integer, Vector> constructor) {
+ final Vector v1 = constructor.apply(size), v2 = constructor.apply(size);
+
+ for (int idx = 0; idx < size; idx++) {
+ v1.set(idx, idx);
+
+ v2.set(idx, size - idx);
+ }
+
+ assertNotNull(v1.map((val) -> (val + 1)));
+
+ assertNotNull(v1.map(v2, (one, other) -> one + other / 2.0));
+
+ assertNotNull(v1.map((val, val1) -> (val + val1), 2.0));
+
+ assertNotNull(v1.foldMap((sum, val) -> (val + sum), (val) -> val, 0.0));
+
+ assertNotNull(v1.foldMap(v2, (sum, val) -> (val + sum), (val1, val2) -> val1 + val2, 0.0));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/acd21fb8/modules/math/src/test/java/org/apache/ignite/math/benchmark/package-info.java
----------------------------------------------------------------------
diff --git a/modules/math/src/test/java/org/apache/ignite/math/benchmark/package-info.java b/modules/math/src/test/java/org/apache/ignite/math/benchmark/package-info.java
new file mode 100644
index 0000000..cbf5d36
--- /dev/null
+++ b/modules/math/src/test/java/org/apache/ignite/math/benchmark/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.benchmark;