package aalg.algebra;


/**
 * Interface for mathematical vector build over field.
 * @author Ing. Petr Ležák
 *
 * @param <F> type of field elements
 */
public interface IVector<F extends IElement> {
	/**
	 * Returns underlying field.
	 * @return field
	 */
	public IField<F> getField();

	/**
	 * Returns number of elements.
	 * @return number of elements
	 */
	public int getSize();
	
	/**
	 * Returns element on given index.
	 * @param index index of element
	 * @return element on given index
	 */
	public F get (final int index);
	
	/**
	 * Sets element on given index.
	 * @param index index on given element
	 * @param element new element value
	 */
	public void set (final int index, final F element);
	
	/**
	 * Returns iterator that iterates through nonzero elements.
	 * @return iterator
	 */
	public IElementIterator<F> getNonzeroIterator();
	
	/**
	 * Returns iterator that iterates through all elements.
	 * @return iterator
	 */
	public IElementIterator<F> getFullIterator();
	
	/**
	 * Sets all elements to given value.
	 * @param element new element value
	 */
	public void fill (final F element);
	
	/**
	 * Swaps elements with given indices. 
	 * @param index1 first row index
	 * @param index2 second row index
	 */
	public void swapElements (final int index1, final int index2);
	
	/**
	 * Assigns given original vector with same size to this.
	 * @param orig original vector
	 */
	public void assign (final IVector<F> orig);
	
	/**
	 * Creates copy of the vector.
	 * @return copy of the vector
	 */
	public IVector<F> copy();

	/**
	 * Calculates sum of vectors.
	 * @param x added vector
	 * @return this + x
	 */
	public IVector<F> add (final IVector<F> x);
	
	/**
	 * Calculates difference of vectors.
	 * @param x subtracted vector
	 * @return this - x
	 */
	public IVector<F> subtract (final IVector<F> x);

	/**
	 * Calculates multiplication of vector by scalar.
	 * @param c multiplicator
	 * @return this * x
	 */
	public IVector<F> multiply (final F c);

	/**
	 * Transforms elements of the vector.
	 * @param transformation element transformation
	 * @return transformed vector
	 * @throws TransformationException thrown if transformation is not possible
	 */
	public <T extends IElement> IVector<T> transform (final IFieldTransformation<F, T> transformation) throws TransformationException;
}
