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