![JAR search and dependency download from the Maven repository](/logo.png)
com.enterprisemath.math.algebra.Vector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of em-math Show documentation
Show all versions of em-math Show documentation
Advanced mathematical algorithms.
The newest version!
package com.enterprisemath.math.algebra;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import com.enterprisemath.utils.DomainUtils;
import com.enterprisemath.utils.ValidationUtils;
/**
* This class represents vector in R^n space.
*
* @author radek.hecl
*
*/
public final class Vector {
/**
* Builder object.
*
* @author radek.hecl
*
*/
public static class Builder {
/**
* Components.
*/
private List components = new ArrayList();
/**
* Sets vector components.
*
* @param components vector components
* @return this instance
*/
public Builder setComponents(List components) {
this.components = DomainUtils.softCopyList(components);
return this;
}
/**
* Adds vector component.
*
* @param component component
* @return this instance
*/
public Builder addComponent(double component) {
this.components.add(component);
return this;
}
/**
* Builds the result object.
*
* @return created object
*/
public Vector build() {
return new Vector(this);
}
}
/**
* Components of this vector.
*/
private double[] components;
/**
* Constructor which can be called only from inside.
*
*/
private Vector() {
}
/**
* Creates new instance.
*
* @param builder builder object
*/
public Vector(Builder builder) {
List defRef = builder.components;
components = new double[defRef.size()];
for (int i = 0; i < components.length; ++i) {
components[i] = defRef.get(i);
}
guardInvariants();
}
/**
* Guards this object to be consistent. Throws exception if this is not the case.
*/
private void guardInvariants() {
ValidationUtils.guardNotNull(components, "components cannot be null");
}
/**
* Returns the dimension of this vector.
*
* @return dimension of this vector
*/
public int getDimension() {
return components.length;
}
/**
* Returns the value of the specified component.
*
* @param index index of the component
* @return value of the specified component
*/
public double getComponent(int index) {
return components[index];
}
/**
* Returns the magnitude of this vector.
* Magnitude is returned in L_2 (Euclidean) norm.
*
* @return magnitude of this vector
*/
public double getMagnitude() {
double d = 0;
for (int i = 0; i < components.length; ++i) {
d = d + components[i] * components[i];
}
return Math.sqrt(d);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("[");
for (int i = 0; i < components.length - 1; ++i) {
res.append(components[i]);
res.append(", ");
}
res.append(components[components.length - 1]);
res.append("]");
return res.toString();
}
public static Vector create(double... x) {
Vector res = new Vector();
res.components = Arrays.copyOf(x, x.length);
res.guardInvariants();
return res;
}
/**
* Creates 1D vector.
*
* @param x component
* @return created vector
*/
public static Vector create1D(double x) {
Vector res = new Vector();
res.components = new double[]{x};
res.guardInvariants();
return res;
}
/**
* Creates 2D vector.
*
* @param x x component
* @param y y component
* @return created vector
*/
public static Vector create2D(double x, double y) {
Vector res = new Vector();
res.components = new double[]{x, y};
res.guardInvariants();
return res;
}
/**
* Creates 3D vector.
*
* @param x x component
* @param y y component
* @param z z component
* @return created vector
*/
public static Vector create3D(double x, double y, double z) {
Vector res = new Vector();
res.components = new double[]{x, y, z};
res.guardInvariants();
return res;
}
/**
* Creates 4D vector.
*
* @param x x component
* @param y y component
* @param z z component
* @param u u component
* @return created vector
*/
public static Vector create4D(double x, double y, double z, double u) {
Vector res = new Vector();
res.components = new double[]{x, y, z, u};
res.guardInvariants();
return res;
}
/**
* Creates the vector which is minimum boundary of the two specified.
* This means the vector which contains the minimum of all components.
* For example for vector [1, 2] and [2, 1] the result will be [1, 1].
*
* @param v1 vector 1
* @param v2 vector 2
* @return boundary minimum vector
* @throws IllegalArgumentException if input vectors have different dimension
*/
public static Vector createBoundaryMin(Vector v1, Vector v2) {
ValidationUtils.guardEquals(v1.getDimension(), v2.getDimension(), "v1 and v2 must have same dimension");
double[] comps = new double[v1.getDimension()];
for (int i = 0; i < comps.length; ++i) {
comps[i] = Math.min(v1.getComponent(i), v2.getComponent(i));
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates the vector which is maximum boundary of the two specified.
* This means the vector which contains the maximum of all components.
* For example for vector [1, 2] and [2, 1] the result will be [2, 2].
*
* @param v1 vector 1
* @param v2 vector 2
* @return boundary minimum vector
* @throws IllegalArgumentException if input vectors have different dimension
*/
public static Vector createBoundaryMax(Vector v1, Vector v2) {
ValidationUtils.guardEquals(v1.getDimension(), v2.getDimension(), "v1 and v2 must have same dimension");
double[] comps = new double[v1.getDimension()];
for (int i = 0; i < comps.length; ++i) {
comps[i] = Math.max(v1.getComponent(i), v2.getComponent(i));
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates vector by addition x + y.
*
* @param x vector x
* @param y vector y
* @return added vector
*/
public static Vector add(Vector x, Vector y) {
ValidationUtils.guardEquals(x.getDimension(), y.getDimension(), "x and y must have same dimension");
double[] comps = new double[x.getDimension()];
for (int i = 0; i < x.getDimension(); ++i) {
comps[i] = x.getComponent(i) + y.getComponent(i);
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates vector by subtracting x - y.
*
* @param x vector x
* @param y vector y
* @return subtracted vector
*/
public static Vector sub(Vector x, Vector y) {
ValidationUtils.guardEquals(x.getDimension(), y.getDimension(), "x and y must have same dimension");
double[] comps = new double[x.getDimension()];
for (int i = 0; i < x.getDimension(); ++i) {
comps[i] = x.getComponent(i) - y.getComponent(i);
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates vector averaging the two other.
*
* @param x vector x
* @param y vector y
* @return average vector
*/
public static Vector avg(Vector x, Vector y) {
ValidationUtils.guardEquals(x.getDimension(), y.getDimension(), "x and y must have same dimension");
double[] comps = new double[x.getDimension()];
for (int i = 0; i < x.getDimension(); ++i) {
comps[i] = (x.getComponent(i) + y.getComponent(i)) / 2;
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates the diagonal vector. Diagonal vector have all the components same.
*
* @param dimension dimension
* @param scalar value for all the components
* @return created diagonal vector
* @throws IllegalArgumentException if dimension is <= 0
*/
public static Vector diagonal(int dimension, double scalar) {
ValidationUtils.guardPositiveInt(dimension, "dimension must be at least 1");
double[] comps = new double[dimension];
for (int i = 0; i < comps.length; ++i) {
comps[i] = scalar;
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates vector which is the scale * x.
*
* @param x original vector
* @param scale scale factor
* @return scaled vector
*/
public static Vector scale(Vector x, double scale) {
double[] comps = new double[x.getDimension()];
for (int i = 0; i < x.getDimension(); ++i) {
comps[i] = x.getComponent(i) * scale;
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
/**
* Creates vector which has same direction, but L_2 (euclidean) magnitude is 1.
*
* @param x source vector
* @return normalized vector
*/
public static Vector normalize(Vector x) {
return Vector.scale(x, 1 / x.getMagnitude());
}
/**
* Creates vector which is cross product of 2 vectors.
* Both input vector must be 3D.
*
* @param a first vector for product
* @param b second vector for product
* @return cross product
*/
public static Vector cross(Vector a, Vector b) {
ValidationUtils.guardEquals(3, a.getDimension(), "dimension of vector a must be 3");
ValidationUtils.guardEquals(3, b.getDimension(), "dimension of vector b must be 3");
return Vector.create3D(a.getComponent(1) * b.getComponent(2) - a.getComponent(2) * b.getComponent(1),
a.getComponent(2) * b.getComponent(0) - a.getComponent(0) * b.getComponent(2),
a.getComponent(0) * b.getComponent(1) - a.getComponent(1) * b.getComponent(0));
}
/**
* Creates vector from a list of components. Size determines the dimension.
*
* @param components components
* @return created vector
*/
public static Vector create(List components) {
double comps[] = new double[components.size()];
for (int i = 0; i < components.size(); ++i) {
comps[i] = components.get(i);
}
Vector res = new Vector();
res.components = comps;
res.guardInvariants();
return res;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy