weka.core.matrix.DoubleVector Maven / Gradle / Ivy
Show all versions of weka-stable Show documentation
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* DoubleVector.java
* Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
*
*/
package weka.core.matrix;
import weka.core.RevisionHandler;
import weka.core.RevisionUtils;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* A vector specialized on doubles.
*
* @author Yong Wang
* @version $Revision: 1.4 $
*/
public class DoubleVector
implements Cloneable, RevisionHandler {
double[] V; // array for internal storage of elements.
private int sizeOfVector; // size of the vector
/* ------------------------
Constructors
* ------------------------ */
/** Constructs a null vector.
*/
public DoubleVector() {
this( 0 );
}
/** Constructs an n-vector of zeros.
@param n length.
*/
public DoubleVector( int n ){
V = new double[ n ];
setSize( n );
}
/** Constructs a constant n-vector.
@param n length.
@param s the scalar value used to fill the vector
*/
public DoubleVector( int n, double s ){
this( n );
set( s );
}
/** Constructs a vector directly from a double array
* @param v the array
*/
public DoubleVector( double v[] ){
if( v == null ) {
V = new double[0];
setSize( 0 );
}
else {
V = v;
setSize( v.length );
}
}
/* ------------------------
* Public Methods
* ------------------------ */
/** Set a single element.
* @param i Index.
* @param s a[i].
*/
public void set( int i, double s ) {
V[i] = s;
}
/** Set all elements to a value
* @param s the value
*/
public void set( double s ) {
set(0, size()-1, s);
}
/** Set some elements to a value
* @param i0 the index of the first element
* @param i1 the index of the second element
* @param s the value
*/
public void set( int i0, int i1, double s ) {
for(int i = i0; i <= i1; i++ )
V[i] = s;
}
/** Set some elements using a 2-D array
* @param i0 the index of the first element
* @param i1 the index of the second element
* @param j0 the index of the starting element in the 2-D array
* @param v the values
*/
public void set( int i0, int i1, double [] v, int j0){
for(int i = i0; i<= i1; i++)
V[i] = v[j0 + i - i0];
}
/** Set the elements using a DoubleVector
* @param v the DoubleVector
*/
public void set( DoubleVector v ){
set( 0, v.size() - 1, v, 0);
}
/** Set some elements using a DoubleVector.
* @param i0 the index of the first element
* @param i1 the index of the second element
* @param v the DoubleVector
* @param j0 the index of the starting element in the DoubleVector
*/
public void set( int i0, int i1, DoubleVector v, int j0){
for(int i = i0; i<= i1; i++)
V[i] = v.V[j0 + i - i0];
}
/** Access the internal one-dimensional array.
@return Pointer to the one-dimensional array of vector elements.
*/
public double [] getArray() {
return V;
}
void setArray( double [] a ) {
V = a;
}
/** Returns a copy of the DoubleVector usng a double array.
@return the one-dimensional array. */
public double[] getArrayCopy() {
double v[] = new double[size()];
for(int i= 0; i < size(); i++ )
v[i] = V[i];
return v;
}
/** Sorts the array in place */
public void sort() {
Arrays.sort( V, 0, size() );
}
/** Sorts the array in place with index returned */
public IntVector sortWithIndex() {
IntVector index = IntVector.seq( 0, size()-1 );
sortWithIndex( 0, size()-1, index );
return index;
}
/** Sorts the array in place with index changed
* @param xi first index
* @param xj last index
* @param index array that stores all indices
*/
public void sortWithIndex( int xi, int xj, IntVector index ) {
if( xi < xj ) {
double x, f, k;
int xm = (int) (xi + xj) / 2; // median index
x = Math.min( V[xi], // median of three
Math.max( V[xm], V[xj]));
int i = xi;
int j = xj;
while( i < j ) {
while( V[i] < x && i < xj ) i++;
while( V[j] > x && j > xi ) j--;
if( i <= j ){
swap(i, j);
index.swap(i, j);
i++;
j--;
}
}
sortWithIndex(xi, j, index);
sortWithIndex(i, xj, index);
}
}
/** Gets the size of the vector.
@return the size
*/
public int size(){
return sizeOfVector;
}
/**
* Sets the size of the vector
* @param m the size
*/
public void setSize( int m ){
if( m > capacity() )
throw new IllegalArgumentException("insufficient capacity");
sizeOfVector = m;
}
/** Gets the capacity of the vector.
* @return the capacity.
*/
public int capacity() {
if( V == null ) return 0;
return V.length;
}
/** Sets the capacity of the vector
* @param n the capacity.
*/
public void setCapacity ( int n ) {
if( n == capacity() ) return;
double [] oldV = V;
int m = Math.min( n, size() );
V = new double[ n ];
setSize( m );
set(0, m-1, oldV, 0);
}
/** Gets a single element.
* @param i Index.
* @return the value of the i-th element
*/
public double get( int i ) {
return V[i];
}
/**
* Adds a value to an element
* @param i the index of the element
* @param s the value
*/
public void setPlus( int i, double s ) {
V[i] += s;
}
/**
* Multiplies a value to an element
* @param i the index of the element
* @param s the value
*/
public void setTimes( int i, double s ) {
V[i] *= s;
}
/**
* Adds an element into the vector
* @param x the value of the new element
*/
public void addElement( double x ) {
if( capacity() == 0 ) setCapacity( 10 );
if( size() == capacity() ) setCapacity( 2 * capacity() );
V[size()] = x;
setSize( size() + 1 );
}
/**
* Returns the squared vector
*/
public DoubleVector square() {
DoubleVector v = new DoubleVector( size() );
for(int i = 0; i < size(); i++ ) v.V[i] = V[i] * V[i];
return v;
}
/**
* Returns the square-root of all the elements in the vector
*/
public DoubleVector sqrt() {
DoubleVector v = new DoubleVector( size() );
for(int i = 0; i < size(); i++ ) v.V[i] = Math.sqrt(V[i]);
return v;
}
/** Makes a deep copy of the vector
*/
public DoubleVector copy() {
return (DoubleVector) clone();
}
/** Clones the DoubleVector object.
*/
public Object clone() {
int n = size();
DoubleVector u = new DoubleVector( n );
for( int i = 0; i < n; i++)
u.V[i] = V[i];
return u;
}
/**
* Returns the inner product of two DoubleVectors
* @param v the second DoubleVector
* @return the product
*/
public double innerProduct(DoubleVector v) {
if(size() != v.size())
throw new IllegalArgumentException("sizes unmatch");
double p = 0;
for (int i = 0; i < size(); i++) {
p += V[i] * v.V[i];
}
return p;
}
/**
* Returns the signs of all elements in terms of -1, 0 and +1.
*/
public DoubleVector sign()
{
DoubleVector s = new DoubleVector( size() );
for( int i = 0; i < size(); i++ ) {
if( V[i] > 0 ) s.V[i] = 1;
else if( V[i] < 0 ) s.V[i] = -1;
else s.V[i] = 0;
}
return s;
}
/** Returns the sum of all elements in the vector.
*/
public double sum()
{
double s = 0;
for( int i=0; i< size(); i++) s += V[i];
return s;
}
/** Returns the squared sum of all elements in the vector.
*/
public double sum2()
{
double s2 = 0;
for( int i=0; i< size(); i++) s2 += V[i] * V[i];
return s2;
}
/** Returns the L1-norm of the vector
*/
public double norm1()
{
double s = 0;
for( int i=0; i< size(); i++) s += Math.abs(V[i]);
return s;
}
/** Returns the L2-norm of the vector
*/
public double norm2()
{
return Math.sqrt( sum2() );
}
/** Returns ||u-v||^2
* @param v the second vector
*/
public double sum2( DoubleVector v )
{
return minus( v ).sum2();
}
/** Returns a subvector.
* @param i0 the index of the first element
* @param i1 the index of the last element
* @return v[i0:i1]
*/
public DoubleVector subvector( int i0, int i1 )
{
DoubleVector v = new DoubleVector( i1-i0+1 );
v.set(0, i1 - i0, this, i0);
return v;
}
/** Returns a subvector.
* @param index stores the indices of the needed elements
* @return v[index]
*/
public DoubleVector subvector( IntVector index ) {
DoubleVector v = new DoubleVector( index.size() );
for( int i = 0; i < index.size(); i++ )
v.V[i] = V[index.V[i]];
return v;
}
/** Returns a vector from the pivoting indices. Elements not indexed are
* set to zero.
* @param index stores the pivoting indices
* @param length the total number of the potential elements
* @return the subvector */
public DoubleVector unpivoting( IntVector index, int length ) {
if( index.size() > length )
throw new IllegalArgumentException("index.size() > length ");
DoubleVector u = new DoubleVector( length );
for( int i = 0; i < index.size(); i++ ) {
u.V[index.V[i]] = V[i];
}
return u;
}
/** Adds a value to all the elements
* @param x the value
*/
public DoubleVector plus ( double x ) {
return copy().plusEquals( x );
}
/** Adds a value to all the elements in place
* @param x the value
*/
public DoubleVector plusEquals ( double x ) {
for( int i = 0; i < size(); i++ )
V[i] += x;
return this;
}
/**
* Adds another vector element by element
* @param v the second vector
*/
public DoubleVector plus( DoubleVector v ) {
return copy().plusEquals( v );
}
/**
* Adds another vector in place element by element
* @param v the second vector
*/
public DoubleVector plusEquals( DoubleVector v ) {
for(int i = 0; i < size(); i++ )
V[i] += v.V[i];
return this;
}
/**
* Subtracts a value
* @param x the value
*/
public DoubleVector minus( double x ) {
return plus( -x );
}
/**
* Subtracts a value in place
* @param x the value
*/
public DoubleVector minusEquals( double x ) {
plusEquals( -x );
return this;
}
/**
* Subtracts another DoubleVector element by element
* @param v the second DoubleVector
*/
public DoubleVector minus( DoubleVector v ) {
return copy().minusEquals( v );
}
/**
* Subtracts another DoubleVector element by element in place
* @param v the second DoubleVector
*/
public DoubleVector minusEquals( DoubleVector v ) {
for(int i = 0; i < size(); i++ )
V[i] -= v.V[i];
return this;
}
/** Multiplies a scalar
@param s scalar
@return s * v
*/
public DoubleVector times( double s ) {
return copy().timesEquals( s );
}
/** Multiply a vector by a scalar in place, u = s * u
@param s scalar
@return replace u by s * u
*/
public DoubleVector timesEquals( double s ) {
for (int i = 0; i < size(); i++) {
V[i] *= s;
}
return this;
}
/**
* Multiplies another DoubleVector element by element
* @param v the second DoubleVector
*/
public DoubleVector times( DoubleVector v ) {
return copy().timesEquals( v );
}
/**
* Multiplies another DoubleVector element by element in place
* @param v the second DoubleVector
*/
public DoubleVector timesEquals( DoubleVector v ) {
for(int i = 0; i < size(); i++ )
V[i] *= v.V[i];
return this;
}
/**
* Divided by another DoubleVector element by element
* @param v the second DoubleVector
*/
public DoubleVector dividedBy ( DoubleVector v ) {
return copy().dividedByEquals( v );
}
/**
* Divided by another DoubleVector element by element in place
* @param v the second DoubleVector
*/
public DoubleVector dividedByEquals ( DoubleVector v ) {
for( int i = 0; i < size(); i++ ) {
V[i] /= v.V[i];
}
return this;
}
/**
* Checks if it is an empty vector
*/
public boolean isEmpty() {
if( size() == 0 ) return true;
return false;
}
/**
* Returns a vector that stores the cumulated values of the original
* vector */
public DoubleVector cumulate()
{
return copy().cumulateInPlace();
}
/**
* Cumulates the original vector in place
*/
public DoubleVector cumulateInPlace()
{
for (int i = 1; i < size(); i++) {
V[i] += V[i-1];
}
return this;
}
/**
* Returns the index of the maximum.
* If multiple maximums exist, the index of the first is returned.
*/
public int indexOfMax()
{
int index = 0;
double ma = V[0];
for( int i = 1; i < size(); i++ ){
if( ma < V[i] ) {
ma = V[i];
index = i;
}
}
return index;
}
/**
* Returns true if vector not sorted
*/
public boolean unsorted () {
if( size() < 2 ) return false;
for( int i = 1; i < size(); i++ ) {
if( V[i-1] > V[i] )
return true;
}
return false;
}
/**
* Combine two vectors together
* @param v the second vector
*/
public DoubleVector cat( DoubleVector v ) {
DoubleVector w = new DoubleVector( size() + v.size() );
w.set(0, size() - 1, this, 0);
w.set(size(), size() + v.size()-1, v, 0);
return w;
}
/**
* Swaps the values stored at i and j
* @param i the index i
* @param j the index j
*/
public void swap( int i, int j ){
if( i == j ) return;
double t = V[i];
V[i] = V[j];
V[j] = t;
}
/**
* Returns the maximum value of all elements
*/
public double max () {
if( size() < 1 ) throw new IllegalArgumentException("zero size");
double ma = V[0];
if( size() < 2 ) return ma;
for( int i = 1; i < size(); i++ ) {
if( V[i] > ma ) ma = V[i];
}
return ma;
}
/**
* Applies a method to the vector
* @param className the class name
* @param method the method
*/
public DoubleVector map( String className, String method ) {
try {
Class c = Class.forName( className );
Class [] cs = new Class[1];
cs[ 0 ] = Double.TYPE;
Method m = c.getMethod( method, cs );
DoubleVector w = new DoubleVector( size() );
Object [] obj = new Object[1];
for( int i = 0; i < size(); i++ ) {
obj[0] = new Double( V[i] );
w.set( i, Double.parseDouble(m.invoke( null, obj ).toString()) );
}
return w;
}
catch ( Exception e ) {
e.printStackTrace();
System.exit(1);
}
return null;
}
/**
* Returns the reverse vector
*/
public DoubleVector rev() {
int n = size();
DoubleVector w = new DoubleVector( n );
for(int i = 0; i < n; i++ )
w.V[i] = V[n-i-1];
return w;
}
/**
* Returns a random vector of uniform distribution
* @param n the size of the vector
*/
public static DoubleVector random( int n ) {
DoubleVector v = new DoubleVector( n );
for (int i = 0; i < n; i++) {
v.V[i] = Math.random();
}
return v;
}
/** Convert the DoubleVecor to a string
*/
public String toString() {
return toString( 5, false );
}
/** Convert the DoubleVecor to a string
* @param digits the number of digits after decimal point
* @param trailing true if trailing zeros are to be shown
*/
public String toString( int digits, boolean trailing ) {
if( isEmpty() ) return "null vector";
StringBuffer text = new StringBuffer();
FlexibleDecimalFormat nf = new FlexibleDecimalFormat( digits,
trailing );
nf.grouping( true );
for( int i = 0; i < size(); i ++ ) nf.update( V[i] );
int count = 0;
int width = 80;
String number;
for( int i = 0; i < size(); i++ ) {
number = nf.format(V[i]);
count += 1 + number.length();
if( count > width-1 ) {
text.append('\n');
count = 1 + number.length();
}
text.append( " " + number );
}
return text.toString();
}
/**
* Returns the revision string.
*
* @return the revision
*/
public String getRevision() {
return RevisionUtils.extract("$Revision: 1.4 $");
}
public static void main( String args[] ) {
DoubleVector u = random(10);
DoubleVector v = random(10);
DoubleVector a = random(10);
DoubleVector w = a;
System.out.println( random(10).plus(v).plus(w) );
}
}