
ch.akuhn.matrix.Vector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cayley Show documentation
Show all versions of cayley Show documentation
Linear Algebra utilities for Java
The newest version!
package ch.akuhn.matrix;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* An ordered list of floating point numbers.
*
* @author Adrian Kuhn
*/
public abstract class Vector {
/**
* Add the given value to the value at the given index
*
* @param index
* @param value
* @return the new value
*/
public double add(int index, double value) {
return put(index, get(index) + value);
}
/**
* @return the density
*/
public double density() {
return ((double) used()) / size();
}
/**
* Iterates over all entries. Some vectors omit zero-valued entries.
*
* @return value and index of each entry.
*/
public Iterable entries() {
return new Iterable() {
@Override
public Iterator iterator() {
return new Iterator() {
private int index = 0;
@Override
public boolean hasNext() {
return index < size();
}
@Override
public Entry next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return new Entry(index, get(index++));
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
/**
* Get the value at the given index
*
* @param index
* @return the value
*/
public abstract double get(int index);
/**
* Compute the L2 norm
*
* @return the L2 norm
*/
public double norm() {
double sum = 0.0;
for (Entry each : entries()) {
sum += (each.value * each.value);
}
return Math.sqrt(sum);
}
/**
* Set the value at an index
*
* @param index
* @param value
* @return the new value
*/
public abstract double put(int index, double value);
/**
* @return the length of the vector
*/
public abstract int size();
/**
* @return the sum of values
*/
public double sum() {
double sum = 0.0;
for (Entry each : entries()) {
sum += each.value;
}
return sum;
}
/**
* Returns number of non-zero-valued entries.
*
* @return a positive integer.
*/
public int used() {
int count = 0;
for (Entry each : entries()) {
if (each.value != 0.0) {
count++;
}
}
return count;
}
/**
* An entry in a sparse vector
*/
public final class Entry {
/**
* The index
*/
public final int index;
/**
* The value
*/
public final double value;
/**
* Construct
*
* @param index
* @param value
*/
public Entry(int index, double value) {
this.index = index;
this.value = value;
}
}
/**
* Construct a Vector from an array of values
*
* @param values
* @return the vector
*/
public static Vector from(double... values) {
return new DenseVector(values.clone());
}
/**
* Copy a range from an array into a vector.
*
* @param values
* @param start
* @param length
* @return the vector
*/
public static Vector copy(double[] values, int start, int length) {
return new DenseVector(Arrays.copyOfRange(values, start, start + length));
}
/**
* Wrap an array in a vector
*
* @param values
* @return the vector
*/
public static Vector wrap(double... values) {
return new DenseVector(values);
}
/**
* Create an empty dense vector
*
* @param size
* @return the vector
*/
public static Vector dense(int size) {
return new DenseVector(size);
}
/**
* Create an empty sparse vector
*
* @param size
* @return the vector
*/
public static Vector sparse(int size) {
return new KuhnSparseVector(size);
}
/**
* Returns the dot/scalar product.
*
* @param x
* @return the dot product
*/
public double dot(Vector x) {
double product = 0.0;
for (Entry each : entries()) {
product += (each.value * x.get(each.index));
}
return product;
}
/**
* y = y + a*this
.
*
* @param a
* @param y
*/
public void scaleAndAddTo(double a, Vector y) {
for (Entry each : entries()) {
y.add(each.index, a * each.value);
}
}
/**
* I/O
*
* @param array
* @param start
*/
public void storeOn(double[] array, int start) {
if (start + size() > array.length) {
throw new IllegalArgumentException("start + size() > array.length");
}
Arrays.fill(array, start, start + size(), 0.0);
for (Entry each : entries()) {
array[start + each.index] = each.value;
}
}
@Override
public String toString() {
StringBuilder out = new StringBuilder();
out.append("(");
for (Entry each : entries()) {
out.append(each.value + ", ");
}
out.append(")");
return out.toString();
}
/**
* Multiply by a constant, creating a new vector
*
* @param scalar
* @return the vector
*/
public abstract Vector times(double scalar);
/**
* Multiply by a constant in-place
*
* @param scalar
* @return this
*/
public abstract Vector timesEquals(double scalar);
/**
* Test for equality
*
* @param v
* @param epsilon
* @return true if the same; false otherwise
*/
public abstract boolean equals(Vector v, double epsilon);
/**
* @return an array
*/
public double[] unwrap() {
throw new IllegalStateException("cannot unwrap instance of " + getClass());
}
/**
* mean-center the vector
*/
public void applyCentering() {
double[] values = unwrap();
double mean = Util.sum(values) / values.length;
for (int i = 0; i < values.length; i++) {
values[i] -= mean;
}
}
/**
* @return the mean of the values
*/
public double mean() {
double[] values = unwrap();
return Util.sum(values) / values.length;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy