de.tsl2.nano.math.vector.Vector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tsl2.nano.logicstructure Show documentation
Show all versions of tsl2.nano.logicstructure Show documentation
TSL2 Framework LogicTable/Tree/Vector (Excel-like table logic with equation solving through tsl2.nano.operation, mathemical Vector/Matrix-calculation)
The newest version!
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: ts
* created on: 05.01.2012
*
* Copyright: (c) Thomas Schneider 2012, all rights reserved
*/
package de.tsl2.nano.math.vector;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import de.tsl2.nano.collection.FloatArray;
import de.tsl2.nano.core.ManagedException;
import de.tsl2.nano.core.util.ByteUtil;
import de.tsl2.nano.core.util.FileUtil;
/**
* Simple-handling numeric n-dim vector with common calculations. See {@link Coordinate} for further informations.
*
* @author ts
*
*/
public class Vector extends Coordinate implements Comparable {
/** serialVersionUID */
private static final long serialVersionUID = -2179340122151337364L;
/**
* @param v any vector
*/
public Vector(float... v) {
super(v);
}
/**
* create
*
* @param dim dimension
* @param defaultValue default value for each cell
* @return new vector
*/
public static Vector create(int dim, float defaultValue) {
float v[] = new float[dim];
for (int i = 0; i < v.length; i++) {
v[i] = defaultValue;
}
return new Vector(v);
}
/**
* scale
*
* @param v vector to be scaled
* @param f scale factor
* @return new vector instance, scaled by f.
*/
public static Vector scale(Vector v, float f) {
v = v.clone(1);
v.scale(f);
return v;
}
/**
* add
*
* @param v vector to add
*/
public void add(Vector v) {
add(v.x);
}
/**
* add
*
* @param v1 source vector to add the vectors vv to.
* @param vv adding vectors
* @return new vector instance as sum of all vectors
*/
public static Vector add(Vector v1, Vector... vv) {
Vector v = v1.clone(1);
for (int i = 0; i < vv.length; i++) {
v.add(vv[i]);
}
return v;
}
/**
* {@inheritDoc}
*/
@Override
public void add(float... v) {
checkDimension(v);
for (int i = 0; i < v.length; i++) {
this.x[i] += v[i];
}
}
/**
* subtract
*
* @param v1 source vector to subtract the vectors vv from.
* @param vv subtractions vectors
* @return new vector instance as subtraction
*/
public static Vector subtract(Vector v1, Vector... vv) {
Vector v = v1.clone(1);
for (int i = 0; i < vv.length; i++) {
v.subtract(vv[i]);
}
return v;
}
/**
* subtract
*
* @param v vector to subtract
*/
protected void subtract(float... v) {
checkDimension(v);
for (int i = 0; i < v.length; i++) {
this.x[i] -= v[i];
}
}
/**
* subtract
*
* @param v vector to subtract
*/
public void subtract(Vector v) {
subtract(v.x);
}
// public void crossProduct(float... v) {
// checkDimension(v);
// for (int i = 0; i < x.length; i++) {
// x[i] = indexCrossProduct(i, v);
// }
// }
//
// private static final float indexCrossProduct(float x, float... v) {
// float r = 0;
// for (int j = 0; j < v.length; j++) {
// r += x * v[j];
// }
// return r;
// }
/**
* see {@link #scalar(float...)}
*/
public float scalar(Vector v) {
return scalar(v.x);
}
/**
* scalar / inner / dot product
*
* @param v second operand of scalar
* @return scalar product of this and v
*/
protected float scalar(float... v) {
checkDimension(v);
float result = 0;
for (int i = 0; i < v.length; i++) {
result += x[i] * v[i];
}
return result;
}
/**
* delegates to {@link #scalar(float...)}
*/
public float multiply(Vector v) {
return scalar(v.x);
}
/**
* through the scalar product it is possible to calculate the angle between two vectors.
*
* @param v another vector to calc the inner angle to
* @return inner angle between the two vectors
*/
public float angle(Vector v) {
float sp = scalar(v);
float cos = sp / (len() * v.len());
return (float) Math.acos(cos);
}
/**
* multiply with an equal-dim matrix
*
* @param m matrix
*/
public void multiply(float[]... m) {
// do only a simple check on first vector
checkDimension(m[0]);
float[] n = new float[x.length];
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
// error on indexes!
n[i] += x[i] * m[i][j];
}
}
System.arraycopy(n, 0, x, 0, x.length);
}
/**
* multiply with an equal-dim matrix
*
* @param m matrix
*/
public void multiply(Vector[] m) {
int dim = m[0].dimension();
float[] mf = new float[dim];
for (int i = 0; i < mf.length; i++) {
System.arraycopy(m[i].x, 0, mf, 0, dim);
}
scalar(mf);
}
/**
* length of current vector
*
* @return
*/
public float len() {
float l = 0;
for (int i = 0; i < x.length; i++) {
l += x[i] * x[i];
}
return (float) Math.sqrt(l);
}
/**
* distance between this and v2. see {@link #subtract(Vector, Vector...)}.
*
* @param v2 second operand
* @return distance between the two vectors
*/
public Vector distance(Vector v2) {
return Vector.subtract(this, v2);
}
/**
* distance as scalar.
*
* @param v second operand
* @return scalar distance
*/
public float distance(float... v) {
checkDimension(v);
float d = 0;
float id;
for (int i = 0; i < x.length; i++) {
id = x[i] - v[i];
d += id * id;
}
return (float) Math.sqrt(d);
}
/**
* normalize the given vector
*
* @param v vector to normalize
* @return new normalized vector instance
*/
public static Vector normalize(Vector v) {
v = v.clone(1);
v.normalize();
return v;
}
/**
* normalize vector
*/
public void normalize() {
float l = len();
if (l == 0) {
return;
}
for (int i = 0; i < x.length; i++) {
x[i] /= l;
}
}
/**
* orthogonizeInPlaneWith
*
* @param v2 second operand in plane with current vector.
*/
public void orthogonizeInPlaneWith(Vector v2) {
int a = isEVector(this);
if (a != -1) {
for (int i = 0; i < x.length; i++) {
if (i == a) {
continue;
}
Vector v1 = e(x.length, i);
if (v1.scalar(v2.x) != 0) {
x = v1.x;
break;
}
}
} else {
for (int i = 0; i < x.length; i++) {
if (x[i] == 0) {
continue;
}
Vector v1 = clone(1);
v1.x[i] = -v1.x[i];
if (v1.scalar(v2.x) != 0) {
x = v1.x;
break;
}
}
}
}
/**
* isEVector
*
* @return axis/row of 1
*/
protected static int isEVector(Vector v) {
if (v.len() != 1) {
return -1;
}
int u = 0;
int a = -1;
for (int i = 0; i < v.x.length; i++) {
if (v.x[i] == 1) {
a = i;
u++;
}
}
return u == 1 ? a : -1;
}
/**
* creates an n-dim normalized vector with number 1 on given row.
*
* @param dim dimension
* @param row coordinate position of 1.
* @return new vector instance
*/
public static Vector e(int dim, int row) {
float d[] = new float[dim];
d[row] = 1;
return new Vector(d);
}
/**
* invert given vector
*
* @param v vector to invert
* @return new vector instance
*/
public static Vector invert(Vector v) {
Vector n = v.clone(1);
for (int i = 0; i < v.x.length; i++) {
if (v.x[i] == 0) {
n.x[i] = 1;
} else {
n.x[i] = 0;
}
}
return n;
}
@Override
public int compareTo(Vector o) {
return (int) (len() - o.len());
}
public static List fromStream(InputStream stream) {
Scanner sc = new Scanner(stream);
final String CR = "\n";
FloatArray fa = new FloatArray();
List vlist = new LinkedList();
while (sc.hasNext()) {
Scanner line = new Scanner(sc.nextLine());
//read us floats
line.useLocale(Locale.US);
while (line.hasNext()) {
if (line.hasNextFloat()) {
fa.add(line.nextFloat());
} else {
line.next();
}
}
if (fa.size() > 0) {
vlist.add(new Vector(fa.toArray()));
fa.clear();
}
line.close();
}
sc.close();
return vlist;
}
public static InputStream toStream(List vl) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
final byte[] CR = "\n".getBytes(), TAB = "\t".getBytes();
try {
for (Vector v : vl) {
for (int i = 0; i < v.dimension(); i++) {
stream.write(/*DecimalFormat.getInstance().format*/Float.toString(v.x[i]).getBytes());
if (i < v.dimension() - 1)
stream.write(TAB);
}
stream.write(CR);
}
} catch (IOException e) {
ManagedException.forward(e);
} finally {
FileUtil.close(stream, false);
}
return ByteUtil.getInputStream(stream.toByteArray());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy