All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.uib.cipr.matrix.sparse.MapVector Maven / Gradle / Ivy

Go to download

A comprehensive collection of matrix data structures, linear solvers, least squares methods, eigenvalue, and singular value decompositions. Forked from: https://github.com/fommil/matrix-toolkits-java and added support for eigenvalue computation of general matrices

There is a newer version: 1.0.8
Show newest version
package no.uib.cipr.matrix.sparse;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.Arrays;

import no.uib.cipr.matrix.AbstractVector;
import no.uib.cipr.matrix.Vector;
import no.uib.cipr.matrix.VectorEntry;


/**
 * Sparse Vector implemented using standard library HashMap
 */
public class MapVector extends AbstractVector implements ISparseVector{

	Map map;
	Supplier> supplier;

	public MapVector(int size) {
		this(size, HashMap::new);
	}

	public MapVector(int size, Supplier> supplier) {
		super(size);
		this.supplier = supplier;
		map = supplier.get();
	}

	public MapVector(Vector x){
		this(x, HashMap::new);
	}

	public MapVector(Vector x, Supplier> supplier) {
		super(x.size());
		this.supplier = supplier;
		map = supplier.get();
		x.forEach(e ->{
			map.put(e.index(), e.get());
		}); 
	}

	public int size() {
		return map.size();
	}

	@Override
	public void set(int index, double value) {
		check(index);
		map.put(index, value);
	}

	@Override
	public void add(int index, double value) {
		check(index);
		double current = map.getOrDefault(index, 0.0);
		map.put(index, value + current);
	}

	@Override
	public double get(int index) {
		check(index);
		return map.getOrDefault(index, 0.0);
	}

	@Override
	public Vector copy() {
		return new MapVector(this, supplier);
	}

	@Override
	public Vector zero() {
		//		for(Entry e: map.entrySet()){
		//			e.setValue(0.0);
		//		}
		map.clear();
		return this;
	}

	@Override
	public Vector scale(double alpha) {
		map.keySet().forEach(k ->{
			map.put(k, map.get(k)*alpha);
		});
		return this;
	}

	@Override
	public Vector set(Vector y) {
		return set(1, y);
	}

	@Override
	public Vector set(double alpha, Vector y) {
		map.clear();
		y.forEach(e ->{
			map.put(e.index(), e.get()*alpha);
		});
		return null;
	}

	@Override
	public Vector add(Vector y) {
		return add(1, y);
	}

	@Override
	public Vector add(double alpha, Vector y) {
		y.forEach(e ->{
			map.put(e.index(), map.getOrDefault(e.index(), 0.0) + e.get()*alpha);
		});
		return this;
	}

	@Override
	public double dot(Vector y) {
		double sum = 0;
		map.entrySet().stream().map(e -> e.getValue()*y.get(e.getKey()));
		return sum;
	}

	@Override
	public Iterator iterator() {
		return new MapVectorIterator();
	}

	/**
	 * Iterator over a sparse vector
	 */
	private class MapVectorIterator implements Iterator {

		private int cursor;
		private int[] indices = MapVector.this.getIndex();
		private final MapVectorEntry entry = new MapVectorEntry();

		public boolean hasNext() {
			return cursor < indices.length;
		}

		public VectorEntry next() {
			entry.update(indices[cursor]);

			cursor++;

			return entry;
		}

		public void remove() {
			entry.set(0);
		}

	}

	/**
	 * Entry of a sparse vector
	 */
	private class MapVectorEntry implements VectorEntry {

		private int index;

		public void update(int index) {
			this.index = index;
		}

		public int index() {
			return index;
		}

		public double get() {
			return map.getOrDefault(index, 0.0);
		}

		public void set(double value) {
			map.put(index, value);
		}

	}

	@Override
	public int[] getIndex() {
		Stream> stream = map.entrySet().stream();

		if(!(map instanceof SortedMap)){
			stream = stream.sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()));
		}

		return stream.mapToInt(e -> e.getKey()).toArray();
	}

	@Override
	public int getUsed() {
		return map.size();
	}

	@Override
	public void compact() {

		Map newMap = supplier.get();

		map.entrySet().stream()
		.filter(e -> e.getValue() != 0)
		.forEach(e -> newMap.put(e.getKey(), e.getValue()));

		map = newMap;
	}

	@Override
	public double[] getData() {
		Stream> stream = map.entrySet().stream();

		if(!(map instanceof SortedMap)){
			stream = stream.sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()));
		}

		return stream.mapToDouble(e -> e.getValue()).toArray();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy