package base;

import java.util.HashMap;
import java.util.Iterator;

public class SparseVector extends HashMap<String, Double> implements Structure
{
	public SparseVector()
	{
		super();
	}

	public SparseVector(SparseVector sparseVector)
	{
		super(sparseVector);
	}

	public SparseVector(DenseVector w, HashMap<String, Integer> wMap)
	{
		for (Entry<String, Integer> e : wMap.entrySet())
		{
			this.put(e.getKey(), w.x[e.getValue()]);
		}
	}

	public void scale(double a)
	{
		for (String s : keySet())
			this.put(s, this.get(s) * a);
	}

	public double multiply(DenseVector w, HashMap<String, Integer> wMap)
	{
		double s = 0;
		for (Iterator<String> i = this.keySet().iterator(); i.hasNext();)
		{
			String k = i.next();
			if (wMap.containsKey(k))
				s += get(k) * w.x[wMap.get(k)];
			else
				i.remove(); // NOTE: THIS MIGHT BE RISKY!
		}
		return s;
	}

	public void add(SparseVector s)
	{
		for (Entry<String, Double> e : s.entrySet())
		{
			if (this.containsKey(e.getKey()))
				this.put(e.getKey(), e.getValue() + this.get(e.getKey()));
			else
				this.put(e.getKey(), e.getValue());
		}
	}

	public void subtract(SparseVector s)
	{
		for (Entry<String, Double> e : s.entrySet())
		{
			if (this.containsKey(e.getKey()))
				this.put(e.getKey(), -e.getValue() + this.get(e.getKey()));
			else
				this.put(e.getKey(), e.getValue());
		}
	}

	public void plusOne(String s)
	{
		if (this.containsKey(s))
			this.put(s, this.get(s) + 1);
		else
			this.put(s, 1d);
	}

	public double multiply(SparseVector phi2)
	{
		double s = 0;
		if (phi2.size() < size())
		{
			for (String i : phi2.keySet())
				if (this.containsKey(i))
					s += this.get(i) * phi2.get(i);
		}
		else
		{
			for (String i : keySet())
				if (phi2.containsKey(i))
					s += this.get(i) * phi2.get(i);
		}
		return s;
	}
}
