You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/04/20 08:39:19 UTC
[12/71] [abbrv] ignite git commit: IGNITE-5000 Rename Ignite Math
module to Ignite ML module added missed licenses renamed packages fixed wrong
ml profile activation
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/AbstractVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/AbstractVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/AbstractVector.java
new file mode 100644
index 0000000..3c075f4
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/AbstractVector.java
@@ -0,0 +1,903 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.IntToDoubleFunction;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.exceptions.CardinalityException;
+import org.apache.ignite.ml.math.exceptions.IndexException;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.functions.Functions;
+import org.apache.ignite.ml.math.functions.IgniteBiFunction;
+import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.ml.math.impls.matrix.MatrixView;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * This class provides a helper implementation of the {@link Vector}
+ * 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.
+ */
+public abstract class AbstractVector implements Vector {
+ /** Vector storage implementation. */
+ private VectorStorage sto;
+
+ /** Meta attribute storage. */
+ private Map<String, Object> meta = new HashMap<>();
+
+ /** Vector's GUID. */
+ private IgniteUuid guid = IgniteUuid.randomUuid();
+
+ /** Cached value for length squared. */
+ private double lenSq = 0.0;
+
+ /** Maximum cached element. */
+ private Element maxElm = null;
+ /** Minimum cached element. */
+ private Element minElm = null;
+
+ /** Readonly flag (false by default). */
+ private boolean readOnly = false;
+
+ /** Read-only error message. */
+ private static final String RO_MSG = "Vector is read-only.";
+
+ /**
+ *
+ */
+ private void ensureReadOnly() {
+ if (readOnly)
+ throw new UnsupportedOperationException(RO_MSG);
+ }
+
+ /**
+ * @param sto Storage.
+ */
+ public AbstractVector(VectorStorage sto) {
+ this(false, sto);
+ }
+
+ /**
+ * @param readOnly Is read only.
+ * @param sto Storage.
+ */
+ public AbstractVector(boolean readOnly, VectorStorage sto) {
+ assert sto != null;
+
+ this.readOnly = readOnly;
+ this.sto = sto;
+ }
+
+ /**
+ *
+ */
+ public AbstractVector() {
+ // No-op.
+ }
+
+ /**
+ * Set storage.
+ *
+ * @param sto Storage.
+ */
+ protected void setStorage(VectorStorage sto) {
+ this.sto = sto;
+ }
+
+ /**
+ * @param i Index.
+ * @param v Value.
+ */
+ protected void storageSet(int i, double v) {
+ ensureReadOnly();
+
+ sto.set(i, v);
+
+ // Reset cached values.
+ lenSq = 0.0;
+ maxElm = minElm = null;
+ }
+
+ /**
+ * @param i Index.
+ * @return Value.
+ */
+ protected double storageGet(int i) {
+ return sto.get(i);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int size() {
+ return sto.size();
+ }
+
+ /**
+ * Check index bounds.
+ *
+ * @param idx Index to check.
+ */
+ protected void checkIndex(int idx) {
+ if (idx < 0 || idx >= sto.size())
+ throw new IndexException(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double get(int idx) {
+ checkIndex(idx);
+
+ return storageGet(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getX(int idx) {
+ return storageGet(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isArrayBased() {
+ return sto.isArrayBased();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector sort() {
+ if (isArrayBased())
+ Arrays.parallelSort(sto.data());
+ else
+ throw new UnsupportedOperationException();
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(IgniteDoubleFunction<Double> fun) {
+ if (sto.isArrayBased()) {
+ double[] data = sto.data();
+
+ Arrays.setAll(data, (idx) -> fun.apply(data[idx]));
+ }
+ else {
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ storageSet(i, fun.apply(storageGet(i)));
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(Vector vec, IgniteBiFunction<Double, Double, Double> fun) {
+ checkCardinality(vec);
+
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ storageSet(i, fun.apply(storageGet(i), vec.get(i)));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(IgniteBiFunction<Double, Double, Double> fun, double y) {
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ storageSet(i, fun.apply(storageGet(i), y));
+
+ return this;
+ }
+
+ /**
+ * @param idx Index.
+ * @return Value.
+ */
+ protected Element makeElement(int idx) {
+ checkIndex(idx);
+
+ return new Element() {
+ /** {@inheritDoc} */
+ @Override public double get() {
+ return storageGet(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int index() {
+ return idx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void set(double val) {
+ storageSet(idx, val);
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element minElement() {
+ if (minElm == null) {
+ int minIdx = 0;
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ if (storageGet(i) < storageGet(minIdx))
+ minIdx = i;
+
+ minElm = makeElement(minIdx);
+ }
+
+ return minElm;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element maxElement() {
+ if (maxElm == null) {
+ int maxIdx = 0;
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ if (storageGet(i) > storageGet(maxIdx))
+ maxIdx = i;
+
+ maxElm = makeElement(maxIdx);
+ }
+
+ return maxElm;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double minValue() {
+ return minElement().get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxValue() {
+ return maxElement().get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector set(int idx, double val) {
+ checkIndex(idx);
+
+ storageSet(idx, val);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector setX(int idx, double val) {
+ storageSet(idx, val);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector increment(int idx, double val) {
+ checkIndex(idx);
+
+ storageSet(idx, storageGet(idx) + val);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector incrementX(int idx, double val) {
+ storageSet(idx, storageGet(idx) + val);
+
+ return this;
+ }
+
+ /**
+ * Tests if given value is considered a zero value.
+ *
+ * @param val Value to check.
+ */
+ protected boolean isZero(double val) {
+ return val == 0.0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ double sum = 0;
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ sum += storageGet(i);
+
+ return sum;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteUuid guid() {
+ return guid;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterable<Element> all() {
+ return new Iterable<Element>() {
+ private int idx = 0;
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override public Iterator<Element> iterator() {
+ return new Iterator<Element>() {
+ /** {@inheritDoc} */
+ @Override public boolean hasNext() {
+ return size() > 0 && idx < size();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element next() {
+ if (hasNext())
+ return getElement(idx++);
+
+ throw new NoSuchElementException();
+ }
+ };
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public int nonZeroElements() {
+ int cnt = 0;
+
+ for (Element ignored : nonZeroes())
+ cnt++;
+
+ return cnt;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> T foldMap(IgniteBiFunction<T, Double, T> foldFun, IgniteDoubleFunction<Double> mapFun,
+ T zeroVal) {
+ T res = zeroVal;
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ res = foldFun.apply(res, mapFun.apply(storageGet(i)));
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> T foldMap(Vector vec, IgniteBiFunction<T, Double, T> foldFun,
+ IgniteBiFunction<Double, Double, Double> combFun, T zeroVal) {
+ checkCardinality(vec);
+
+ T res = zeroVal;
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ res = foldFun.apply(res, combFun.apply(storageGet(i), vec.getX(i)));
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterable<Element> nonZeroes() {
+ return new Iterable<Element>() {
+ private int idx = 0;
+ private int idxNext = -1;
+
+ /** {@inheritDoc} */
+ @NotNull
+ @Override public Iterator<Element> iterator() {
+ return new Iterator<Element>() {
+ @Override public boolean hasNext() {
+ findNext();
+
+ return !over();
+ }
+
+ @Override public Element next() {
+ if (hasNext()) {
+ idx = idxNext;
+
+ return getElement(idxNext);
+ }
+
+ throw new NoSuchElementException();
+ }
+
+ private void findNext() {
+ if (over())
+ return;
+
+ if (idxNextInitialized() && idx != idxNext)
+ return;
+
+ if (idxNextInitialized())
+ idx = idxNext + 1;
+
+ while (idx < size() && isZero(get(idx)))
+ idx++;
+
+ idxNext = idx++;
+ }
+
+ private boolean over() {
+ return idxNext >= size();
+ }
+
+ private boolean idxNextInitialized() {
+ return idxNext != -1;
+ }
+ };
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<String, Object> getMetaStorage() {
+ return meta;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(double val) {
+ if (sto.isArrayBased()) {
+ ensureReadOnly();
+
+ Arrays.fill(sto.data(), val);
+ }
+ else {
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ storageSet(i, val);
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(double[] vals) {
+ checkCardinality(vals);
+
+ if (sto.isArrayBased()) {
+ ensureReadOnly();
+
+ System.arraycopy(vals, 0, sto.data(), 0, vals.length);
+
+ lenSq = 0.0;
+ }
+ else {
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ storageSet(i, vals[i]);
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(Vector vec) {
+ checkCardinality(vec);
+
+ for (Vector.Element x : vec.all())
+ storageSet(x.index(), x.get());
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(IntToDoubleFunction fun) {
+ assert fun != null;
+
+ if (sto.isArrayBased()) {
+ ensureReadOnly();
+
+ Arrays.setAll(sto.data(), fun);
+ }
+ else {
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ storageSet(i, fun.applyAsDouble(i));
+ }
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Spliterator<Double> allSpliterator() {
+ return new Spliterator<Double>() {
+ /** {@inheritDoc} */
+ @Override public boolean tryAdvance(Consumer<? super Double> act) {
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ act.accept(storageGet(i));
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Spliterator<Double> trySplit() {
+ return null; // No Splitting.
+ }
+
+ /** {@inheritDoc} */
+ @Override public long estimateSize() {
+ return size();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int characteristics() {
+ return ORDERED | SIZED;
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public Spliterator<Double> nonZeroSpliterator() {
+ return new Spliterator<Double>() {
+ /** {@inheritDoc} */
+ @Override public boolean tryAdvance(Consumer<? super Double> act) {
+ int len = size();
+
+ for (int i = 0; i < len; i++) {
+ double val = storageGet(i);
+
+ if (!isZero(val))
+ act.accept(val);
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Spliterator<Double> trySplit() {
+ return null; // No Splitting.
+ }
+
+ /** {@inheritDoc} */
+ @Override public long estimateSize() {
+ return nonZeroElements();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int characteristics() {
+ return ORDERED | SIZED;
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Override public double dot(Vector vec) {
+ checkCardinality(vec);
+
+ double sum = 0.0;
+ int len = size();
+
+ for (int i = 0; i < len; i++)
+ sum += storageGet(i) * vec.getX(i);
+
+ return sum;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getLengthSquared() {
+ if (lenSq == 0.0)
+ lenSq = dotSelf();
+
+ return lenSq;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDense() {
+ return sto.isDense();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSequentialAccess() {
+ return sto.isSequentialAccess();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRandomAccess() {
+ return sto.isRandomAccess();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDistributed() {
+ return sto.isDistributed();
+ }
+
+ /** {@inheritDoc} */
+ @Override public VectorStorage getStorage() {
+ return sto;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewPart(int off, int len) {
+ return new VectorView(this, off, len);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix cross(Vector vec) {
+ Matrix res = likeMatrix(size(), vec.size());
+
+ if (res == null)
+ return null;
+
+ for (Element e : nonZeroes()) {
+ int row = e.index();
+
+ res.assignRow(row, vec.times(getX(row)));
+ }
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix toMatrix(boolean rowLike) {
+ Matrix res = likeMatrix(rowLike ? 1 : size(), rowLike ? size() : 1);
+
+ if (res == null)
+ return null;
+
+ if (rowLike)
+ res.assignRow(0, this);
+ else
+ res.assignColumn(0, this);
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix toMatrixPlusOne(boolean rowLike, double zeroVal) {
+ Matrix res = likeMatrix(rowLike ? 1 : size() + 1, rowLike ? size() + 1 : 1);
+
+ if (res == null)
+ return null;
+
+ res.set(0, 0, zeroVal);
+
+ if (rowLike)
+ new MatrixView(res, 0, 1, 1, size()).assignRow(0, this);
+ else
+ new MatrixView(res, 1, 0, size(), 1).assignColumn(0, this);
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getDistanceSquared(Vector vec) {
+ checkCardinality(vec);
+
+ double thisLenSq = getLengthSquared();
+ double thatLenSq = vec.getLengthSquared();
+ double dot = dot(vec);
+ double distEst = thisLenSq + thatLenSq - 2 * dot;
+
+ if (distEst > 1.0e-3 * (thisLenSq + thatLenSq))
+ // The vectors are far enough from each other that the formula is accurate.
+ return Math.max(distEst, 0);
+ else
+ return foldMap(vec, Functions.PLUS, Functions.MINUS_SQUARED, 0d);
+ }
+
+ /** */
+ protected void checkCardinality(Vector vec) {
+ if (vec.size() != size())
+ throw new CardinalityException(size(), vec.size());
+ }
+
+ /** */
+ protected void checkCardinality(double[] vec) {
+ if (vec.length != size())
+ throw new CardinalityException(size(), vec.length);
+ }
+
+ /** */
+ protected void checkCardinality(int[] arr) {
+ if (arr.length != size())
+ throw new CardinalityException(size(), arr.length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector minus(Vector vec) {
+ checkCardinality(vec);
+
+ Vector cp = copy();
+
+ return cp.map(vec, Functions.MINUS);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector plus(double x) {
+ Vector cp = copy();
+
+ return x != 0.0 ? cp.map(Functions.plus(x)) : cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector divide(double x) {
+ Vector cp = copy();
+
+ if (x != 1.0)
+ for (Element element : cp.all())
+ element.set(element.get() / x);
+
+ return cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ if (x == 0.0)
+ return like(size());
+ else
+ return copy().map(Functions.mult(x));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(Vector vec) {
+ checkCardinality(vec);
+
+ return copy().map(vec, Functions.MULT);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector plus(Vector vec) {
+ checkCardinality(vec);
+
+ Vector cp = copy();
+
+ return cp.map(vec, Functions.PLUS);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector logNormalize() {
+ return logNormalize(2.0, Math.sqrt(getLengthSquared()));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector logNormalize(double power) {
+ return logNormalize(power, kNorm(power));
+ }
+
+ /**
+ * @param power Power.
+ * @param normLen Normalized length.
+ * @return logNormalized value.
+ */
+ private Vector logNormalize(double power, double normLen) {
+ assert !(Double.isInfinite(power) || power <= 1.0);
+
+ double denominator = normLen * Math.log(power);
+
+ Vector cp = copy();
+
+ for (Element element : cp.all())
+ element.set(Math.log1p(element.get()) / denominator);
+
+ return cp;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double kNorm(double power) {
+ assert power >= 0.0;
+
+ // Special cases.
+ if (Double.isInfinite(power))
+ return foldMap(Math::max, Math::abs, 0d);
+ else if (power == 2.0)
+ return Math.sqrt(getLengthSquared());
+ else if (power == 1.0)
+ return foldMap(Functions.PLUS, Math::abs, 0d);
+ else if (power == 0.0)
+ return nonZeroElements();
+ else
+ // Default case.
+ return Math.pow(foldMap(Functions.PLUS, Functions.pow(power), 0d), 1.0 / power);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector normalize() {
+ return divide(Math.sqrt(getLengthSquared()));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector normalize(double power) {
+ return divide(kNorm(power));
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ return like(size()).assign(this);
+ }
+
+ /**
+ * @return Result of dot with self.
+ */
+ protected double dotSelf() {
+ double sum = 0.0;
+ int len = size();
+
+ for (int i = 0; i < len; i++) {
+ double v = storageGet(i);
+
+ sum += v * v;
+ }
+
+ return sum;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element getElement(int idx) {
+ return makeElement(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(sto);
+ out.writeObject(meta);
+ out.writeObject(guid);
+ out.writeBoolean(readOnly);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ sto = (VectorStorage)in.readObject();
+ meta = (Map<String, Object>)in.readObject();
+ guid = (IgniteUuid)in.readObject();
+ readOnly = in.readBoolean();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void destroy() {
+ sto.destroy();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+ res += res * 37 + guid.hashCode();
+ res += sto == null ? 0 : res * 37 + sto.hashCode();
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+
+ if (obj == null || getClass() != obj.getClass())
+ return false;
+
+ AbstractVector that = (AbstractVector)obj;
+
+ return (sto != null ? sto.equals(that.sto) : that.sto == null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
new file mode 100644
index 0000000..7e23791
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/CacheVector.java
@@ -0,0 +1,140 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.ValueMapper;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.VectorKeyMapper;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.functions.IgniteBiFunction;
+import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.ml.math.functions.IgniteFunction;
+import org.apache.ignite.ml.math.impls.CacheUtils;
+import org.apache.ignite.ml.math.impls.storage.vector.CacheVectorStorage;
+
+/**
+ * Vector based on existing cache and index and value mapping functions.
+ */
+public class CacheVector<K, V> extends AbstractVector {
+ /**
+ *
+ */
+ public CacheVector() {
+ // No-op.
+ }
+
+ /**
+ * Creates new vector over existing cache.
+ *
+ * @param size
+ * @param cache
+ * @param keyFunc
+ * @param valMapper
+ */
+ public CacheVector(
+ int size,
+ IgniteCache<K, V> cache,
+ VectorKeyMapper<K> keyFunc,
+ ValueMapper<V> valMapper) {
+ setStorage(new CacheVectorStorage<>(size, cache, keyFunc, valMapper));
+ }
+
+ /**
+ * @param mapper
+ */
+ private Vector mapOverCache(IgniteFunction<Double, Double> mapper) {
+ CacheVectorStorage<K, V> sto = storage();
+
+ CacheUtils.map(sto.cache().getName(), sto.keyMapper(), sto.valueMapper(), mapper);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double minValue() {
+ CacheVectorStorage<K, V> sto = storage();
+
+ return CacheUtils.min(sto.cache().getName(), sto.keyMapper(), sto.valueMapper());
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxValue() {
+ CacheVectorStorage<K, V> sto = storage();
+
+ return CacheUtils.max(sto.cache().getName(), sto.keyMapper(), sto.valueMapper());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(IgniteDoubleFunction<Double> fun) {
+ return mapOverCache(fun::apply);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(IgniteBiFunction<Double, Double, Double> fun, double y) {
+ // TODO: provide cache-optimized implementation.
+ return super.map(fun, y); // TODO
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ CacheVectorStorage<K, V> sto = storage();
+
+ return CacheUtils.sum(sto.cache().getName(), sto.keyMapper(), sto.valueMapper());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(double val) {
+ return mapOverCache((Double d) -> val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector plus(double x) {
+ return mapOverCache((Double d) -> d + x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector divide(double x) {
+ return mapOverCache((Double d) -> d / x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ return mapOverCache((Double d) -> d * x);
+ }
+
+ /**
+ *
+ *
+ */
+ @SuppressWarnings({"unchecked"})
+ private CacheVectorStorage<K, V> storage() {
+ return (CacheVectorStorage<K, V>)getStorage();
+ }
+
+ /** {@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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/ConstantVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/ConstantVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/ConstantVector.java
new file mode 100644
index 0000000..71c9c3e
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/ConstantVector.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.ml.math.impls.vector;
+
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.impls.storage.vector.ConstantVectorStorage;
+
+/**
+ * Constant value, read-only vector.
+ */
+public class ConstantVector extends AbstractReadOnlyVector {
+ /**
+ *
+ */
+ public ConstantVector() {
+ // No-op.
+ }
+
+ /**
+ * @param size
+ * @param val
+ */
+ public ConstantVector(int size, double val) {
+ super(new ConstantVectorStorage(size, val));
+ }
+
+ /**
+ *
+ *
+ */
+ private ConstantVectorStorage storage() {
+ return (ConstantVectorStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ ConstantVectorStorage sto = storage();
+
+ return new ConstantVector(sto.size(), sto.constant());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ return new ConstantVector(crd, storage().constant());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ ConstantVector that = (ConstantVector)o;
+
+ VectorStorage sto = getStorage();
+
+ return (sto != null ? sto.equals(that.getStorage()) : that.getStorage() == null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DelegatingVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DelegatingVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DelegatingVector.java
new file mode 100644
index 0000000..891eb8e
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DelegatingVector.java
@@ -0,0 +1,391 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.function.IntToDoubleFunction;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.functions.IgniteBiFunction;
+import org.apache.ignite.ml.math.functions.IgniteDoubleFunction;
+
+/**
+ * Convenient class that can be used to add decorations to an existing vector. Subclasses
+ * can add weights, indices, etc. while maintaining full vector functionality.
+ */
+public class DelegatingVector implements Vector {
+ /** Delegating vector. */
+ private Vector dlg;
+
+ /** Meta attribute storage. */
+ private Map<String, Object> meta = new HashMap<>();
+
+ /** GUID. */
+ private IgniteUuid guid = IgniteUuid.randomUuid();
+
+ /** */
+ public DelegatingVector() {
+ // No-op.
+ }
+
+ /**
+ * @param dlg
+ */
+ public DelegatingVector(Vector dlg) {
+ assert dlg != null;
+
+ this.dlg = dlg;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(dlg);
+ out.writeObject(meta);
+ out.writeObject(guid);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ dlg = (Vector)in.readObject();
+ meta = (Map<String, Object>)in.readObject();
+ guid = (IgniteUuid)in.readObject();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<String, Object> getMetaStorage() {
+ return meta;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return dlg.likeMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix toMatrix(boolean rowLike) {
+ return dlg.toMatrix(rowLike);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix toMatrixPlusOne(boolean rowLike, double zeroVal) {
+ return dlg.toMatrixPlusOne(rowLike, zeroVal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int size() {
+ return dlg.size();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDense() {
+ return dlg.isDense();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double minValue() {
+ return dlg.minValue();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double maxValue() {
+ return dlg.maxValue();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isSequentialAccess() {
+ return dlg.isSequentialAccess();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isArrayBased() {
+ return dlg.isArrayBased();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector copy() {
+ return new DelegatingVector(dlg);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterable<Element> all() {
+ return dlg.all();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Iterable<Element> nonZeroes() {
+ return dlg.nonZeroes();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector sort() {
+ return dlg.sort();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Spliterator<Double> allSpliterator() {
+ return dlg.allSpliterator();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Spliterator<Double> nonZeroSpliterator() {
+ return dlg.nonZeroSpliterator();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element getElement(int idx) {
+ return dlg.getElement(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(double val) {
+ return dlg.assign(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(double[] vals) {
+ return dlg.assign(vals);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(Vector vec) {
+ return dlg.assign(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(IntToDoubleFunction fun) {
+ return dlg.assign(fun);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(IgniteDoubleFunction<Double> fun) {
+ return dlg.map(fun);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(Vector vec, IgniteBiFunction<Double, Double, Double> fun) {
+ return dlg.map(vec, fun);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector map(IgniteBiFunction<Double, Double, Double> fun, double y) {
+ return dlg.map(fun, y);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector divide(double x) {
+ return dlg.divide(x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double dot(Vector vec) {
+ return dlg.dot(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double get(int idx) {
+ return dlg.get(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getX(int idx) {
+ return dlg.getX(idx);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ return dlg.like(crd);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector minus(Vector vec) {
+ return dlg.minus(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector normalize() {
+ return dlg.normalize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector normalize(double power) {
+ return dlg.normalize(power);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector logNormalize() {
+ return dlg.logNormalize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector logNormalize(double power) {
+ return dlg.logNormalize(power);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double kNorm(double power) {
+ return dlg.kNorm(power);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element minElement() {
+ return dlg.minElement();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Element maxElement() {
+ return dlg.maxElement();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector plus(double x) {
+ return dlg.plus(x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector plus(Vector vec) {
+ return dlg.plus(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector set(int idx, double val) {
+ return dlg.set(idx, val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector setX(int idx, double val) {
+ return dlg.setX(idx, val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector incrementX(int idx, double val) {
+ return dlg.incrementX(idx, val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector increment(int idx, double val) {
+ return dlg.increment(idx, val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int nonZeroElements() {
+ return dlg.nonZeroElements();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ return dlg.times(x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(Vector vec) {
+ return dlg.times(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector viewPart(int off, int len) {
+ return dlg.viewPart(off, len);
+ }
+
+ /** {@inheritDoc} */
+ @Override public VectorStorage getStorage() {
+ return dlg.getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double sum() {
+ return dlg.sum();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix cross(Vector vec) {
+ return dlg.cross(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> T foldMap(IgniteBiFunction<T, Double, T> foldFun, IgniteDoubleFunction<Double> mapFun,
+ T zeroVal) {
+ return dlg.foldMap(foldFun, mapFun, zeroVal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> T foldMap(Vector vec, IgniteBiFunction<T, Double, T> foldFun,
+ IgniteBiFunction<Double, Double, Double> combFun, T zeroVal) {
+ return dlg.foldMap(vec, foldFun, combFun, zeroVal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getLengthSquared() {
+ return dlg.getLengthSquared();
+ }
+
+ /** {@inheritDoc} */
+ @Override public double getDistanceSquared(Vector vec) {
+ return dlg.getDistanceSquared(vec);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isRandomAccess() {
+ return dlg.isRandomAccess();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isDistributed() {
+ return dlg.isDistributed();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteUuid guid() {
+ return guid;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void destroy() {
+ dlg.destroy();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = 1;
+
+ res = res * 37 + meta.hashCode();
+ res = res * 37 + dlg.hashCode();
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ DelegatingVector that = (DelegatingVector)o;
+
+ return meta.equals(that.meta) && dlg.equals(that.dlg);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOffHeapVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOffHeapVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOffHeapVector.java
new file mode 100644
index 0000000..c635572
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOffHeapVector.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import java.util.stream.IntStream;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.impls.matrix.DenseLocalOffHeapMatrix;
+import org.apache.ignite.ml.math.impls.storage.vector.DenseLocalOffHeapVectorStorage;
+
+/**
+ * Implementation for {@link Vector} assuming dense 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.
+ */
+public class DenseLocalOffHeapVector extends AbstractVector {
+ /** */
+ public DenseLocalOffHeapVector() {
+ // No-op.
+ }
+
+ /** */
+ private void makeOffheapStorage(int size) {
+ setStorage(new DenseLocalOffHeapVectorStorage(size));
+ }
+
+ /**
+ * @param arr Array to copy to offheap storage.
+ */
+ public DenseLocalOffHeapVector(double[] arr) {
+ makeOffheapStorage(arr.length);
+
+ assign(arr);
+ }
+
+ /**
+ * @param size Vector cardinality.
+ */
+ public DenseLocalOffHeapVector(int size) {
+ makeOffheapStorage(size);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector assign(Vector vec) {
+ checkCardinality(vec);
+
+ IntStream.range(0, size()).parallel().forEach(idx -> set(idx, vec.get(idx)));
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ if (x == 0.0)
+ return like(size()).assign(0);
+ else
+ return super.times(x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ return new DenseLocalOffHeapVector(crd);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return new DenseLocalOffHeapMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ return o != null && getClass().equals(o.getClass()) && (getStorage().equals(((Vector)o).getStorage()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOnHeapVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOnHeapVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOnHeapVector.java
new file mode 100644
index 0000000..c37bda0
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/DenseLocalOnHeapVector.java
@@ -0,0 +1,104 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import java.util.Map;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.impls.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.ml.math.impls.storage.vector.ArrayVectorStorage;
+
+/**
+ * Basic implementation for vector.
+ * <p>
+ * This is a trivial implementation for vector assuming dense logic, local on-heap JVM storage
+ * based on {@code double[]} 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 DenseLocalOnHeapVector extends AbstractVector {
+ /**
+ * @param size Vector cardinality.
+ */
+ private VectorStorage mkStorage(int size) {
+ return new ArrayVectorStorage(size);
+ }
+
+ /**
+ * @param arr Source array.
+ * @param cp {@code true} to clone array, reuse it otherwise.
+ */
+ private VectorStorage mkStorage(double[] arr, boolean cp) {
+ assert arr != null;
+
+ return new ArrayVectorStorage(cp ? arr.clone() : arr);
+ }
+
+ /**
+ * @param args Parameters for new Vector.
+ */
+ public DenseLocalOnHeapVector(Map<String, Object> args) {
+ assert args != null;
+
+ if (args.containsKey("size"))
+ setStorage(mkStorage((int)args.get("size")));
+ else if (args.containsKey("arr") && args.containsKey("copy"))
+ setStorage(mkStorage((double[])args.get("arr"), (boolean)args.get("copy")));
+ else
+ throw new UnsupportedOperationException("Invalid constructor argument(s).");
+ }
+
+ /** */
+ public DenseLocalOnHeapVector() {
+ // No-op.
+ }
+
+ /**
+ * @param size Vector cardinality.
+ */
+ public DenseLocalOnHeapVector(int size) {
+ setStorage(mkStorage(size));
+ }
+
+ /**
+ * @param arr Source array.
+ * @param shallowCp {@code true} to use shallow copy.
+ */
+ public DenseLocalOnHeapVector(double[] arr, boolean shallowCp) {
+ setStorage(mkStorage(arr, shallowCp));
+ }
+
+ /**
+ * @param arr Source array.
+ */
+ public DenseLocalOnHeapVector(double[] arr) {
+ this(arr, false);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ return new DenseLocalOnHeapMatrix(rows, cols);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ return new DenseLocalOnHeapVector(crd);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/FunctionVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/FunctionVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/FunctionVector.java
new file mode 100644
index 0000000..a2ffd90
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/FunctionVector.java
@@ -0,0 +1,112 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import java.util.Map;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.functions.IgniteFunction;
+import org.apache.ignite.ml.math.functions.IntDoubleToVoidFunction;
+import org.apache.ignite.ml.math.impls.storage.vector.FunctionVectorStorage;
+
+/**
+ * Implementation of {@link Vector} that maps vector element index to {@link java.util.function} interfaces.
+ */
+public class FunctionVector extends AbstractVector {
+ /**
+ *
+ */
+ public FunctionVector() {
+ // No-op.
+ }
+
+ /**
+ * Creates read-write or read-only function vector.
+ *
+ * @param size Vector size.
+ * @param getFunc Function that returns value corresponding to given element index.
+ * @param setFunc Set function. If {@code null} - this will be a read-only vector.
+ */
+ public FunctionVector(int size, IgniteFunction<Integer, Double> getFunc, IntDoubleToVoidFunction setFunc) {
+ setStorage(new FunctionVectorStorage(size, getFunc, setFunc));
+ }
+
+ /**
+ * Creates read-only function vector.
+ *
+ * @param size Vector size.
+ * @param getFunc Function that returns value corresponding to given element index.
+ */
+ public FunctionVector(int size, IgniteFunction<Integer, Double> getFunc) {
+ setStorage(new FunctionVectorStorage(size, getFunc));
+ }
+
+ /**
+ * @param args Arguments for vector constructor.
+ */
+ public FunctionVector(Map<String, Object> args) {
+ assert args != null;
+
+ if (args.containsKey("size") && args.containsKey("getFunc") && args.containsKey("setFunc")) {
+ @SuppressWarnings("unchecked")
+ IgniteFunction<Integer, Double> getFunc = (IgniteFunction<Integer, Double>)args.get("getFunc");
+ IntDoubleToVoidFunction setFunc = (IntDoubleToVoidFunction)args.get("setFunc");
+ int size = (int)args.get("size");
+
+ setStorage(new FunctionVectorStorage(size, getFunc, setFunc));
+ }
+ else if (args.containsKey("size") && args.containsKey("getFunc")) {
+ @SuppressWarnings("unchecked")
+ IgniteFunction<Integer, Double> getFunc = (IgniteFunction<Integer, Double>)args.get("getFunc");
+ int size = (int)args.get("size");
+
+ setStorage(new FunctionVectorStorage(size, getFunc));
+ }
+ else
+ throw new UnsupportedOperationException("Invalid constructor argument(s).");
+ }
+
+ /**
+ *
+ *
+ */
+ private FunctionVectorStorage storage() {
+ return (FunctionVectorStorage)getStorage();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector like(int crd) {
+ FunctionVectorStorage sto = storage();
+
+ return new FunctionVector(crd, sto.getFunction(), sto.setFunction());
+ }
+
+ /** {@inheritDoc} */
+ @Override public Matrix likeMatrix(int rows, int cols) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Vector times(double x) {
+ if (x == 0.0)
+ return like(size()).assign(0);
+ else
+ return super.times(x);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/MatrixVectorView.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/MatrixVectorView.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/MatrixVectorView.java
new file mode 100644
index 0000000..723c585
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.exceptions.IndexException;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/PivotedVectorView.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/PivotedVectorView.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/PivotedVectorView.java
new file mode 100644
index 0000000..607bb72
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.functions.Functions;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/RandomVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/RandomVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/RandomVector.java
new file mode 100644
index 0000000..08292eb
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/RandomVector.java
@@ -0,0 +1,129 @@
+/*
+ * 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.ml.math.impls.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.impls.matrix.RandomMatrix;
+import org.apache.ignite.ml.math.impls.storage.vector.RandomVectorStorage;
+import org.apache.ignite.ml.math.Vector;
+
+/**
+ * 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 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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SingleElementVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SingleElementVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SingleElementVector.java
new file mode 100644
index 0000000..cae5ca3
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import java.util.Map;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SingleElementVectorView.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SingleElementVectorView.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SingleElementVectorView.java
new file mode 100644
index 0000000..0fb4105
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.math.functions.Functions;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SparseLocalOffHeapVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SparseLocalOffHeapVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SparseLocalOffHeapVector.java
new file mode 100644
index 0000000..fa216ff
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SparseLocalVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SparseLocalVector.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/SparseLocalVector.java
new file mode 100644
index 0000000..d60eea8
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.StorageConstants;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.impls.matrix.SparseLocalOnHeapMatrix;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/VectorView.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/VectorView.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/VectorView.java
new file mode 100644
index 0000000..f3bd4dd
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
+
+import java.io.Externalizable;
+import org.apache.ignite.ml.math.Matrix;
+import org.apache.ignite.ml.math.Vector;
+import org.apache.ignite.ml.math.VectorStorage;
+import org.apache.ignite.ml.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.ml.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/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/vector/package-info.java
new file mode 100644
index 0000000..b7f485c
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math.impls.vector;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/d78e071a/modules/ml/src/main/java/org/apache/ignite/ml/math/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/package-info.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/package-info.java
new file mode 100644
index 0000000..5887d4b
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/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.ml.math;
\ No newline at end of file