package util.linalg;
import java.io.Serializable;
import java.text.DecimalFormat;
import shared.Copyable;
/**
* A class representing a vector with linear algebra
* operations.
* @author Andrew Guillory gtg008g@mail.gatech.edu
* @version 1.0
*/
public abstract class Vector implements Serializable, Copyable {
/**
* Get the size of the vector (the number of rows)
* @return the number of rows
*/
public abstract int size();
/**
* Get an element from the vecotr
* @param i the element to get
* @return the element
*/
public abstract double get(int i);
/**
* Get some sub portion of the vector
* @param ia the starting index (inclusive)
* @param ib the ending index (exclusive)
* @return the result
*/
public Vector get(int ia, int ib) {
double[] result = new double[ib - ia];
for (int i = 0; i < result.length; i++) {
result[i] = get(ia + i);
}
return new DenseVector(result);
}
/**
* Set a portion of the vector
* @param i the starting porition
* @param values the values
*/
public void set(int i, Vector values) {
for (int row = i; row-i < values.size(); row++) {
set(row, values.get(row-i));
}
}
/**
* Set an element in the vector
* @param i the element to set
* @param d the new value
*/
public abstract void set(int i, double d);
/**
* Get the maximum of this vector with the given vector
* @param v the other vector
* @return the max
*/
public Vector max(Vector v) {
double[] result = new double[size()];
for (int i = 0; i < result.length; i++) {
result[i] = Math.max(get(i), v.get(i));
}
return new DenseVector(result);
}
/**
* Set this vector equal to the max of itself with
* the given vector
* @param v the given vector
*/
public void maxEquals(Vector v) {
for (int i = 0; i < size(); i++) {
set(i, Math.max(get(i), v.get(i)));
}
}
/**
* Set this vector equal to the min of itself with
* the given vector
* @param v the given vector
*/
public void minEquals(Vector v) {
for (int i = 0; i < size(); i++) {
set(i, Math.min(get(i), v.get(i)));
}
}
/**
* Get the minimum of this vector with the given vector
* @param v the other vector
* @return the min
*/
public Vector min(Vector v) {
double[] result = new double[size()];
for (int i = 0; i < result.length; i++) {
result[i] = Math.min(get(i), v.get(i));
}
return new DenseVector(result);
}
/**
* Get the indice arg max of this vector
* @return the arg max inidice
*/
public int argMax() {
int max = 0;
for (int i = 1; i < size(); i++) {
if (get(i) > get(max)) {
max = i;
}
}
return max;
}
/**
* Dot product this vector with another vector
* @param vector the other vector
* @return the dot product
*/
public double dotProduct(Vector vector) {
double result = 0;
for (int i = 0; i < size(); i++) {
result += get(i) * vector.get(i);
}
return result;
}
/**
* Outer product this vector with another vector
* @param vector the other vector
* @return the outer product
*/
public Matrix outerProduct(Vector vector) {
double[][] result = new double[size()][size()];
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[0].length; j++) {
result[i][j] = get(i) * vector.get(j);
}
}
return new RectangularMatrix(result);
}
/**
* Multiply this vector by a scale
* @param scale the scale
* @return the multiplied vector
*/
public Vector times(double scale) {
Vector result = (Vector) copy();
result.timesEquals(scale);
return result;
}
/**
* Multiply this vector by a scale in place
* @param scale the scale
*/
public void timesEquals(double scale) {
for (int i = 0; i < size(); i++) {
set(i, get(i) * scale);
}
}
/**
* Add this vector to another vector
* @param vector the other vector
* @return the result
*/
public Vector plus(Vector vector) {
Vector result = (Vector) copy();
result.plusEquals(vector);
return result;
}
/**
* Get the sum of all of the entries
* @return the sum
*/
public double sum() {
double sum = 0;
for (int i = 0; i < size(); i++) {
sum += get(i);
}
return sum;
}
/**
* Add a vector onto this vector in place
* @param vector the vector to add
*/
public void plusEquals(Vector vector) {
for (int i = 0; i < size(); i++) {
set(i, get(i) + vector.get(i));
}
}
/**
* Subtract a vector from this vector
* @param vector the other vector
* @return the result
*/
public Vector minus(Vector vector) {
Vector result = (Vector) copy();
result.minusEquals(vector);
return result;
}
/**
* Subtract a vector from this vector in place
* @param vector the vector to subtract
*/
public void minusEquals(Vector vector) {
for (int i = 0; i < size(); i++) {
set(i, get(i) - vector.get(i));
}
}
/**
* Get the two norm squared of this vector
* @return the two norm squared
*/
public double normSquared() {
return this.dotProduct(this);
}
/**
* Get the two norm of this vector
* @return the two norm
*/
public double norm() {
return Math.sqrt(normSquared());
}
/**
* Make a copy of this vector
* @return the copy
*/
public Copyable copy() {
double[] copy = new double[size()];
for (int i = 0; i < copy.length; i++) {
copy[i] = get(i);
}
return new DenseVector(copy);
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object o) {
Vector v = (Vector) o;
if (v.size() != size()) {
return false;
}
for (int i = 0; i < v.size(); i++) {
if (get(i) != v.get(i)) {
return false;
}
}
return true;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
DecimalFormat df = new DecimalFormat("0.000000");
String result = "";
for (int i = 0; i < size(); i++) {
result += df.format(get(i));
if (i + 1 < size()) {
result += ", ";
}
}
return result;
}
}