package jsci.maths.vectors;
import jsci.GlobalSettings;
import jsci.maths.Mapping;
import jsci.maths.MathDouble;
import jsci.maths.MathInteger;
import jsci.maths.algebras.Module;
import jsci.maths.algebras.VectorSpace;
import jsci.maths.fields.Field;
import jsci.maths.fields.Ring;
import jsci.maths.groups.AbelianGroup;
/**
* An optimised implementation of a 3D double vector.
* @version 2.0
* @author Mark Hale
*/
public final class Double3Vector extends AbstractDoubleVector {
protected double x;
protected double y;
protected double z;
/**
* Constructs an empty 3-vector.
*/
public Double3Vector() {
super(3);
}
/**
* Constructs a 3-vector.
* @param x x coordinate.
* @param y y coordinate.
* @param z z coordinate.
*/
public Double3Vector(final double x, final double y, final double z) {
this();
this.x = x;
this.y = y;
this.z = z;
}
/**
* Constructs a 3-vector.
*/
public Double3Vector(double[] array) {
this();
x = array[0];
y = array[1];
z = array[2];
}
/**
* Compares two double vectors for equality.
* @param obj a double 3-vector
*/
public boolean equals(Object obj, double tol) {
if(obj != null && (obj instanceof Double3Vector)) {
final Double3Vector vec = (Double3Vector) obj;
double dx = x - vec.x;
double dy = y - vec.y;
double dz = z - vec.z;
return (dx*dx
+ dy*dy
+ dz*dz <= tol*tol);
} else
return false;
}
/**
* Returns a comma delimited string representing the value of this vector.
*/
public String toString() {
final StringBuffer buf = new StringBuffer(15);
buf.append(x).append(',').append(y).append(',').append(z);
return buf.toString();
}
/**
* Converts this 3-vector to an integer 3-vector.
* @return an integer 3-vector
*/
public AbstractIntegerVector toIntegerVector() {
return new Integer3Vector(
Math.round((float)x),
Math.round((float)y),
Math.round((float)z)
);
}
/**
* Converts this 3-vector to a complex 3-vector.
* @return a complex 3-vector
*/
public AbstractComplexVector toComplexVector() {
return new Complex3Vector(
x, 0.0,
y, 0.0,
z, 0.0
);
}
/**
* Returns a component of this vector.
* @param n index of the vector component
* @exception VectorDimensionException If attempting to access an invalid component.
*/
public double getComponent(final int n) {
switch(n) {
case 0 : return x;
case 1 : return y;
case 2 : return z;
default : throw new VectorDimensionException("Invalid component.");
}
}
/**
* Sets the value of a component of this vector.
* Should only be used to initialise this vector.
* @param n index of the vector component
* @param value a number
* @exception VectorDimensionException If attempting to access an invalid component.
*/
public void setComponent(final int n, final double value) {
switch(n) {
case 0 : x = value; break;
case 1 : y = value; break;
case 2 : z = value; break;
default : throw new VectorDimensionException("Invalid component.");
}
}
/**
* Returns the ln-norm.
*/
public double norm(final int n) {
final double answer = Math.pow(Math.abs(x), n)
+Math.pow(Math.abs(y), n)
+Math.pow(Math.abs(z), n);
return Math.pow(answer, 1.0/n);
}
/**
* Returns the l2-norm (magnitude).
*/
public double norm() {
return Math.sqrt(
x*x
+y*y
+z*z
);
}
/**
* Returns the l
-norm.
* @author Taber Smith
*/
public double infNorm() {
double infNorm = 0;
double abs;
abs = Math.abs(x);
if(abs > infNorm)
infNorm = abs;
abs = Math.abs(y);
if(abs > infNorm)
infNorm = abs;
abs = Math.abs(z);
if(abs > infNorm)
infNorm = abs;
return infNorm;
}
//============
// OPERATIONS
//============
/**
* Returns the negative of this vector.
*/
public AbelianGroup.Member negate() {
return new Double3Vector(
-x,
-y,
-z
);
}
// ADDITION
/**
* Returns the addition of this vector and another.
*/
public AbelianGroup.Member add(final AbelianGroup.Member vec) {
if(vec instanceof AbstractDoubleVector)
return add((AbstractDoubleVector)vec);
else
throw new IllegalArgumentException("Member class not recognised by this method.");
}
/**
* Returns the addition of this vector and another.
* @param vec a double 3-vector
*/
public AbstractDoubleVector add(final AbstractDoubleVector vec) {
if(vec.N == 3) {
return new Double3Vector(
x+vec.getComponent(0),
y+vec.getComponent(1),
z+vec.getComponent(2)
);
} else
throw new VectorDimensionException("Vectors are different sizes.");
}
// SUBTRACTION
/**
* Returns the subtraction of this vector by another.
*/
public AbelianGroup.Member subtract(final AbelianGroup.Member vec) {
if(vec instanceof AbstractDoubleVector)
return subtract((AbstractDoubleVector)vec);
else
throw new IllegalArgumentException("Member class not recognised by this method.");
}
/**
* Returns the subtraction of this vector by another.
* @param vec a double 3-vector
*/
public AbstractDoubleVector subtract(final AbstractDoubleVector vec) {
if(vec.N == 3) {
return new Double3Vector(
x-vec.getComponent(0),
y-vec.getComponent(1),
z-vec.getComponent(2)
);
} else
throw new VectorDimensionException("Vectors are different sizes.");
}
// SCALAR MULTIPLICATION
/**
* Returns the multiplication of this vector by a scalar.
*/
public Module.Member scalarMultiply(Ring.Member x) {
if(x instanceof MathInteger)
return scalarMultiply(((MathInteger)x).value());
else if(x instanceof MathDouble)
return scalarMultiply(((MathDouble)x).value());
else
throw new IllegalArgumentException("Member class not recognised by this method.");
}
/**
* Returns the multiplication of this vector by a scalar.
* @param k a double
* @return a double 3-vector
*/
public AbstractDoubleVector scalarMultiply(final double k) {
return new Double3Vector(
k*x,
k*y,
k*z
);
}
// SCALAR DIVISION
/**
* Returns the division of this vector by a scalar.
*/
public VectorSpace.Member scalarDivide(Field.Member x) {
if(x instanceof MathDouble)
return scalarDivide(((MathDouble)x).value());
else
throw new IllegalArgumentException("Member class not recognised by this method.");
}
/**
* Returns the division of this vector by a scalar.
* @param k a double
* @return a double 3-vector
* @exception ArithmeticException If divide by zero.
*/
public AbstractDoubleVector scalarDivide(final double k) {
return new Double3Vector(
x/k,
y/k,
z/k
);
}
// SCALAR PRODUCT
/**
* Returns the scalar product of this vector and another.
* @param vec a double 3-vector
*/
public double scalarProduct(final AbstractDoubleVector vec) {
if(vec.N == 3) {
return x*vec.getComponent(0)
+y*vec.getComponent(1)
+z*vec.getComponent(2);
} else
throw new VectorDimensionException("Vectors are different sizes.");
}
// VECTOR PRODUCT
/**
* Returns the vector product of this vector and another (so(3) algebra).
* @param vec a double 3-vector
*/
public Double3Vector multiply(final Double3Vector vec) {
return new Double3Vector(
y*vec.z - vec.y*z,
z*vec.x - vec.z*x,
x*vec.y - vec.x*y
);
}
// MAP COMPONENTS
/**
* Applies a function on all the vector components.
* @param mapping a user-defined function
* @return a double 3-vector
*/
public AbstractDoubleVector mapComponents(final Mapping mapping) {
return new Double3Vector(
mapping.map(x),
mapping.map(y),
mapping.map(z)
);
}
}
Ads help maintain this website.