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/18 13:45:52 UTC

[07/62] [abbrv] ignite git commit: IGNITE-5000 Rename Ignite Math module to Ignite ML module

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/RandomVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/RandomVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/RandomVectorStorage.java
new file mode 100644
index 0000000..58f0fb4
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/RandomVectorStorage.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
+import java.util.Random;
+import org.apache.ignite.math.MurmurHash;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+
+/**
+ * {@link VectorStorage} implementation with random values in the vector elements.
+ */
+public class RandomVectorStorage implements VectorStorage {
+    /** */
+    private static final long SCALE = 1L << 32;
+    /** */
+    private static final int PRIME = 104047;
+
+    /** Random generation seed. */
+    private int seed;
+
+    /** Vector size. */
+    private int size;
+
+    /** Whether fast hash is used, in {@link #get(int)}. */
+    private boolean fastHash;
+
+    /** */
+    public RandomVectorStorage() {
+        // No-op.
+    }
+
+    /**
+     * @param size Size of the storage.
+     * @param fastHash Whether or not to use fast hashing or Murmur hashing.
+     */
+    public RandomVectorStorage(int size, boolean fastHash) {
+        assert size > 0;
+
+        this.size = size;
+        this.fastHash = fastHash;
+
+        seed = new Random().nextInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public double get(int i) {
+        if (!fastHash) {
+            ByteBuffer buf = ByteBuffer.allocate(4);
+
+            buf.putInt(i);
+            buf.flip();
+
+            return (MurmurHash.hash64A(buf, seed) & (SCALE - 1)) / (double)SCALE;
+        }
+        else
+            // This isn't a fantastic random number generator, but it is just fine for random projections.
+            return (((i * PRIME) & 8) * 0.25) - 1;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void set(int i, double v) {
+        throw new UnsupportedOperationException("Random vector storage is a read-only storage.");
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeInt(size);
+        out.writeInt(seed);
+        out.writeBoolean(fastHash);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        size = in.readInt();
+        seed = in.readInt();
+        fastHash = in.readBoolean();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSequentialAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDense() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isRandomAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDistributed() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isArrayBased() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = 1;
+
+        res = res * 37 + Boolean.hashCode(fastHash);
+        res = res * 37 + seed;
+        res = res * 37 + size;
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        RandomVectorStorage that = (RandomVectorStorage)o;
+
+        return size == that.size && seed == that.seed && fastHash == that.fastHash;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorDelegateStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorDelegateStorage.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorDelegateStorage.java
new file mode 100644
index 0000000..c5a4350
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorDelegateStorage.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+
+/**
+ * Single value view storage over another vector.
+ */
+public class SingleElementVectorDelegateStorage implements VectorStorage {
+    /** */ private int idx;
+    /** */ private Vector vec;
+
+    /**
+     *
+     */
+    public SingleElementVectorDelegateStorage() {
+        // No-op.
+    }
+
+    /**
+     * @param vec Parent vector.
+     * @param idx Element index.
+     */
+    public SingleElementVectorDelegateStorage(Vector vec, int idx) {
+        assert vec != null;
+        assert idx >= 0;
+
+        this.vec = vec;
+        this.idx = idx;
+    }
+
+    /**
+     *
+     *
+     */
+    public int index() {
+        return idx;
+    }
+
+    /**
+     *
+     *
+     */
+    public Vector delegate() {
+        return vec;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return vec.size();
+    }
+
+    /** {@inheritDoc} */
+    @Override public double get(int i) {
+        return i == idx ? vec.get(i) : 0.0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void set(int i, double v) {
+        if (i == idx)
+            vec.set(i, v);
+        else
+            throw new UnsupportedOperationException("Can't set element outside of index: " + idx);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(vec);
+        out.writeInt(idx);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        vec = (Vector)in.readObject();
+        idx = in.readInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSequentialAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDense() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isRandomAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDistributed() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isArrayBased() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        SingleElementVectorDelegateStorage that = (SingleElementVectorDelegateStorage)o;
+
+        return idx == that.idx && (vec != null ? vec.equals(that.vec) : that.vec == null);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = idx;
+
+        res = 31 * res + (vec != null ? vec.hashCode() : 0);
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorStorage.java
new file mode 100644
index 0000000..3378817
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SingleElementVectorStorage.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+
+/**
+ * Vector storage holding a single non-zero value at some index.
+ */
+public class SingleElementVectorStorage implements VectorStorage {
+    /** */ private int idx;
+    /** */ private double val;
+    /** */ private int size;
+
+    /**
+     *
+     */
+    public SingleElementVectorStorage() {
+        // No-op.
+    }
+
+    /**
+     * @param size Parent vector size.
+     * @param idx Element index in the parent vector.
+     * @param val Value of the element.
+     */
+    public SingleElementVectorStorage(int size, int idx, double val) {
+        assert size > 0;
+        assert idx >= 0;
+
+        this.size = size;
+        this.idx = idx;
+        this.val = val;
+    }
+
+    /**
+     *
+     * @return Index of the element in the parent vector.
+     */
+    public int index() {
+        return idx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public double get(int i) {
+        return i == idx ? val : 0.0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void set(int i, double v) {
+        if (i == idx)
+            val = v;
+        else
+            throw new UnsupportedOperationException("Can't set element outside of index: " + idx);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeInt(size);
+        out.writeInt(idx);
+        out.writeDouble(val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        size = in.readInt();
+        idx = in.readInt();
+        val = in.readDouble();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSequentialAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDense() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isRandomAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDistributed() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isArrayBased() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        SingleElementVectorStorage that = (SingleElementVectorStorage)o;
+
+        return idx == that.idx && Double.compare(that.val, val) == 0 && size == that.size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = idx;
+        long temp = Double.doubleToLongBits(val);
+
+        res = 31 * res + (int)(temp ^ (temp >>> 32));
+        res = 31 * res + size;
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOffHeapVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOffHeapVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOffHeapVectorStorage.java
new file mode 100644
index 0000000..9b912cb
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOffHeapVectorStorage.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.vector;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.nio.ByteBuffer;
+import org.apache.ignite.internal.util.offheap.GridOffHeapMap;
+import org.apache.ignite.internal.util.offheap.GridOffHeapMapFactory;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+
+/**
+ * {@link VectorStorage} implementation for {@link org.apache.ignite.math.impls.vector.SparseLocalOffHeapVector}.
+ */
+public class SparseLocalOffHeapVectorStorage implements VectorStorage {
+    /** Assume 10% density. */
+    private static final int INIT_DENSITY = 10;
+    /** Storage capacity. */
+    private int size;
+    /** Local off heap map. */
+    private GridOffHeapMap gridOffHeapMap;
+
+    /** */
+    public SparseLocalOffHeapVectorStorage() {
+        //No-op.
+    }
+
+    /** */
+    public SparseLocalOffHeapVectorStorage(int cap) {
+        assert cap > 0;
+
+        gridOffHeapMap = GridOffHeapMapFactory.unsafeMap(cap / INIT_DENSITY);
+        size = cap;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public double get(int i) {
+        byte[] bytes = gridOffHeapMap.get(hash(i), intToByteArray(i));
+        return bytes == null ? 0 : ByteBuffer.wrap(bytes).getDouble();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void set(int i, double v) {
+        if (v != 0.0)
+            gridOffHeapMap.put(hash(i), intToByteArray(i), doubleToByteArray(v));
+        else if (gridOffHeapMap.contains(hash(i), intToByteArray(i)))
+            gridOffHeapMap.remove(hash(i), intToByteArray(i));
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        throw new UnsupportedOperationException(); // TODO: add externalization support.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSequentialAccess() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isRandomAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDense() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isArrayBased() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDistributed() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void destroy() {
+        gridOffHeapMap.destruct();
+    }
+
+    /** */
+    private int hash(int h) {
+        // Apply base step of MurmurHash; see http://code.google.com/p/smhasher/
+        // Despite two multiplies, this is often faster than others
+        // with comparable bit-spread properties.
+        h ^= h >>> 16;
+        h *= 0x85ebca6b;
+        h ^= h >>> 13;
+        h *= 0xc2b2ae35;
+
+        return (h >>> 16) ^ h;
+    }
+
+    /** */
+    private byte[] intToByteArray(int val) {
+        return new byte[] {
+            (byte)(val >>> 24),
+            (byte)(val >>> 16),
+            (byte)(val >>> 8),
+            (byte)val};
+    }
+
+    /** */
+    private byte[] doubleToByteArray(double val) {
+        long l = Double.doubleToRawLongBits(val);
+        return new byte[] {
+            (byte)((l >> 56) & 0xff),
+            (byte)((l >> 48) & 0xff),
+            (byte)((l >> 40) & 0xff),
+            (byte)((l >> 32) & 0xff),
+            (byte)((l >> 24) & 0xff),
+            (byte)((l >> 16) & 0xff),
+            (byte)((l >> 8) & 0xff),
+            (byte)((l) & 0xff),
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
new file mode 100644
index 0000000..b3a8a3c
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.math.impls.storage.vector;
+
+import it.unimi.dsi.fastutil.ints.Int2DoubleOpenHashMap;
+import it.unimi.dsi.fastutil.ints.Int2DoubleRBTreeMap;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+import org.apache.ignite.math.StorageConstants;
+import org.apache.ignite.math.VectorStorage;
+
+/**
+ * Sparse, local, on-heap vector storage.
+ */
+public class SparseLocalOnHeapVectorStorage implements VectorStorage, StorageConstants {
+    /** */ private int size;
+    /** */ private int acsMode;
+
+    /** Actual map storage. */
+    private Map<Integer, Double> sto;
+
+    /**
+     *
+     */
+    public SparseLocalOnHeapVectorStorage() {
+        // No-op.
+    }
+
+    /**
+     * @param size Vector size.
+     * @param acsMode Access mode.
+     */
+    public SparseLocalOnHeapVectorStorage(int size, int acsMode) {
+        assert size > 0;
+        assertAccessMode(acsMode);
+
+        this.size = size;
+        this.acsMode = acsMode;
+
+        if (acsMode == SEQUENTIAL_ACCESS_MODE)
+            sto = new Int2DoubleRBTreeMap();
+        else
+            sto = new Int2DoubleOpenHashMap();
+    }
+
+    /**
+     *
+     *
+     */
+    public int getAccessMode() {
+        return acsMode;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return size;
+    }
+
+    /** {@inheritDoc} */
+    @Override public double get(int i) {
+        return sto.getOrDefault(i, 0.0);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void set(int i, double v) {
+        if (v != 0.0)
+            sto.put(i, v);
+        else if (sto.containsKey(i))
+            sto.remove(i);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeInt(size);
+        out.writeInt(acsMode);
+        out.writeObject(sto);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings({"unchecked"})
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        size = in.readInt();
+        acsMode = in.readInt();
+        sto = (Map<Integer, Double>)in.readObject();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isSequentialAccess() {
+        return acsMode == SEQUENTIAL_ACCESS_MODE;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDense() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isRandomAccess() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isDistributed() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isArrayBased() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        SparseLocalOnHeapVectorStorage that = (SparseLocalOnHeapVectorStorage)o;
+
+        return size == that.size && acsMode == that.acsMode && (sto != null ? sto.equals(that.sto) : that.sto == null);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = size;
+
+        res = 31 * res + acsMode;
+        res = 31 * res + (sto != null ? sto.hashCode() : 0);
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/package-info.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/package-info.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/vector/package-info.java
new file mode 100644
index 0000000..a716e6a
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/storage/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 vector storage models.
+ */
+package org.apache.ignite.math.impls.storage.vector;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractReadOnlyVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractReadOnlyVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractReadOnlyVector.java
new file mode 100644
index 0000000..58c583a
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractReadOnlyVector.java
@@ -0,0 +1,108 @@
+package org.apache.ignite.math.impls.vector;
+
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.functions.IgniteBiFunction;
+import org.apache.ignite.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.math.impls.matrix.FunctionMatrix;
+
+/**
+ * This class provides a helper implementation of the read-only implementation of {@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 AbstractReadOnlyVector extends AbstractVector {
+    /** */
+    public AbstractReadOnlyVector() {
+        // No-op.
+    }
+
+    /**
+     * @param sto Storage.
+     */
+    public AbstractReadOnlyVector(VectorStorage sto) {
+        super(true, sto);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Matrix cross(Vector vec) {
+        return new FunctionMatrix(size(), vec.size(),
+            (row, col) -> vec.get(col) * get(row));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Matrix toMatrix(boolean rowLike) {
+        return new FunctionMatrix(rowLike ? 1 : size(), rowLike ? size() : 1,
+            (row, col) -> rowLike ? get(col) : get(row));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Matrix toMatrixPlusOne(boolean rowLike, double zeroVal) {
+        return new FunctionMatrix(rowLike ? 1 : size() + 1, rowLike ? size() + 1 : 1, (row, col) -> {
+            if (row == 0 && col == 0)
+                return zeroVal;
+
+            return rowLike ? get(col - 1) : get(row - 1);
+        });
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector copy() {
+        return this; // This exploits read-only feature of this type vector.
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector logNormalize() {
+        return logNormalize(2.0, Math.sqrt(getLengthSquared()));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector logNormalize(double power) {
+        return logNormalize(power, kNorm(power));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector map(IgniteDoubleFunction<Double> fun) {
+        return new FunctionVector(size(), (i) -> fun.apply(get(i)));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector map(Vector vec, IgniteBiFunction<Double, Double, Double> fun) {
+        checkCardinality(vec);
+
+        return new FunctionVector(size(), (i) -> fun.apply(get(i), vec.get(i)));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector map(IgniteBiFunction<Double, Double, Double> fun, double y) {
+        return new FunctionVector(size(), (i) -> fun.apply(get(i), y));
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector divide(double x) {
+        if (x == 1.0)
+            return this;
+
+        return new FunctionVector(size(), (i) -> get(i) / x);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Vector times(double x) {
+        return x == 0 ? new ConstantVector(size(), 0) : new FunctionVector(size(), (i) -> get(i) * x);
+    }
+
+    /**
+     * @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);
+
+        return new FunctionVector(size(), (idx) -> Math.log1p(get(idx)) / denominator);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/AbstractVector.java
new file mode 100644
index 0000000..d84c0f3
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.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.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.exceptions.CardinalityException;
+import org.apache.ignite.math.exceptions.IndexException;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.functions.Functions;
+import org.apache.ignite.math.functions.IgniteBiFunction;
+import org.apache.ignite.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.math.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/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/CacheVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/CacheVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/CacheVector.java
new file mode 100644
index 0000000..0e9b26f
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.math.impls.vector;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.ValueMapper;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.VectorKeyMapper;
+import org.apache.ignite.math.exceptions.UnsupportedOperationException;
+import org.apache.ignite.math.functions.IgniteBiFunction;
+import org.apache.ignite.math.functions.IgniteDoubleFunction;
+import org.apache.ignite.math.functions.IgniteFunction;
+import org.apache.ignite.math.impls.CacheUtils;
+import org.apache.ignite.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/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/ConstantVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/ConstantVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/ConstantVector.java
new file mode 100644
index 0000000..0fddfd6
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.math.impls.vector;
+
+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.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/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DelegatingVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DelegatingVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DelegatingVector.java
new file mode 100644
index 0000000..a10fa45
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.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.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.VectorStorage;
+import org.apache.ignite.math.functions.IgniteBiFunction;
+import org.apache.ignite.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/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DenseLocalOffHeapVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DenseLocalOffHeapVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DenseLocalOffHeapVector.java
new file mode 100644
index 0000000..4e7eb21
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.math.impls.vector;
+
+import java.util.stream.IntStream;
+import org.apache.ignite.math.Matrix;
+import org.apache.ignite.math.Vector;
+import org.apache.ignite.math.impls.matrix.DenseLocalOffHeapMatrix;
+import org.apache.ignite.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/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DenseLocalOnHeapVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DenseLocalOnHeapVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/DenseLocalOnHeapVector.java
new file mode 100644
index 0000000..5827998
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.math.impls.vector;
+
+import java.util.Map;
+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.matrix.DenseLocalOnHeapMatrix;
+import org.apache.ignite.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/732dfea9/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/FunctionVector.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/FunctionVector.java b/modules/ml/src/main/java/org/apache/ignite/math/impls/vector/FunctionVector.java
new file mode 100644
index 0000000..0e7cfad
--- /dev/null
+++ b/modules/ml/src/main/java/org/apache/ignite/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.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.functions.IgniteFunction;
+import org.apache.ignite.math.functions.IntDoubleToVoidFunction;
+import org.apache.ignite.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 org.apache.ignite.math.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);
+    }
+}