2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or (at
5
* your option) any later version.
7
* This program is distributed in the hope that it will be useful, but
8
* WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
* General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
* Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
22
package weka.core.matrix;
24
import java.lang.reflect.Method;
25
import java.util.Arrays;
28
* A vector specialized on doubles.
31
* @version $Revision: 1.3 $
33
public class DoubleVector implements Cloneable {
35
double[] V; // array for internal storage of elements.
37
private int sizeOfVector; // size of the vector
39
/* ------------------------
41
* ------------------------ */
43
/** Constructs a null vector.
45
public DoubleVector() {
49
/** Constructs an n-vector of zeros.
52
public DoubleVector( int n ){
57
/** Constructs a constant n-vector.
59
@param s the scalar value used to fill the vector
61
public DoubleVector( int n, double s ){
66
/** Constructs a vector directly from a double array
69
public DoubleVector( double v[] ){
80
/* ------------------------
82
* ------------------------ */
84
/** Set a single element.
88
public void set( int i, double s ) {
93
/** Set all elements to a value
96
public void set( double s ) {
100
/** Set some elements to a value
101
* @param i0 the index of the first element
102
* @param i1 the index of the second element
105
public void set( int i0, int i1, double s ) {
107
for(int i = i0; i <= i1; i++ )
111
/** Set some elements using a 2-D array
112
* @param i0 the index of the first element
113
* @param i1 the index of the second element
114
* @param j0 the index of the starting element in the 2-D array
115
* @param v the values
117
public void set( int i0, int i1, double [] v, int j0){
118
for(int i = i0; i<= i1; i++)
119
V[i] = v[j0 + i - i0];
122
/** Set the elements using a DoubleVector
123
* @param v the DoubleVector
125
public void set( DoubleVector v ){
126
set( 0, v.size() - 1, v, 0);
129
/** Set some elements using a DoubleVector.
130
* @param i0 the index of the first element
131
* @param i1 the index of the second element
132
* @param v the DoubleVector
133
* @param j0 the index of the starting element in the DoubleVector
135
public void set( int i0, int i1, DoubleVector v, int j0){
136
for(int i = i0; i<= i1; i++)
137
V[i] = v.V[j0 + i - i0];
140
/** Access the internal one-dimensional array.
141
@return Pointer to the one-dimensional array of vector elements.
143
public double [] getArray() {
147
void setArray( double [] a ) {
151
/** Returns a copy of the DoubleVector usng a double array.
152
@return the one-dimensional array. */
153
public double[] getArrayCopy() {
154
double v[] = new double[size()];
156
for(int i= 0; i < size(); i++ )
162
/** Sorts the array in place */
164
Arrays.sort( V, 0, size() );
167
/** Sorts the array in place with index returned */
168
public IntVector sortWithIndex() {
169
IntVector index = IntVector.seq( 0, size()-1 );
170
sortWithIndex( 0, size()-1, index );
174
/** Sorts the array in place with index changed
175
* @param xi first index
176
* @param xj last index
177
* @param index array that stores all indices
179
public void sortWithIndex( int xi, int xj, IntVector index ) {
182
int xm = (int) (xi + xj) / 2; // median index
183
x = Math.min( V[xi], // median of three
184
Math.max( V[xm], V[xj]));
188
while( V[i] < x && i < xj ) i++;
189
while( V[j] > x && j > xi ) j--;
197
sortWithIndex(xi, j, index);
198
sortWithIndex(i, xj, index);
202
/** Gets the size of the vector.
210
* Sets the size of the vector
213
public void setSize( int m ){
215
throw new IllegalArgumentException("insufficient capacity");
219
/** Gets the capacity of the vector.
220
* @return the capacity.
222
public int capacity() {
223
if( V == null ) return 0;
227
/** Sets the capacity of the vector
228
* @param n the capacity.
230
public void setCapacity ( int n ) {
231
if( n == capacity() ) return;
233
int m = Math.min( n, size() );
236
set(0, m-1, oldV, 0);
239
/** Gets a single element.
241
* @return the value of the i-th element
243
public double get( int i ) {
248
* Adds a value to an element
249
* @param i the index of the element
252
public void setPlus( int i, double s ) {
257
* Multiplies a value to an element
258
* @param i the index of the element
261
public void setTimes( int i, double s ) {
266
* Adds an element into the vector
267
* @param x the value of the new element
269
public void addElement( double x ) {
270
if( capacity() == 0 ) setCapacity( 10 );
271
if( size() == capacity() ) setCapacity( 2 * capacity() );
273
setSize( size() + 1 );
277
* Returns the squared vector
279
public DoubleVector square() {
280
DoubleVector v = new DoubleVector( size() );
281
for(int i = 0; i < size(); i++ ) v.V[i] = V[i] * V[i];
286
* Returns the square-root of all the elements in the vector
288
public DoubleVector sqrt() {
289
DoubleVector v = new DoubleVector( size() );
290
for(int i = 0; i < size(); i++ ) v.V[i] = Math.sqrt(V[i]);
294
/** Makes a deep copy of the vector
296
public DoubleVector copy() {
297
return (DoubleVector) clone();
300
/** Clones the DoubleVector object.
302
public Object clone() {
304
DoubleVector u = new DoubleVector( n );
305
for( int i = 0; i < n; i++)
311
* Returns the inner product of two DoubleVectors
312
* @param v the second DoubleVector
313
* @return the product
315
public double innerProduct(DoubleVector v) {
316
if(size() != v.size())
317
throw new IllegalArgumentException("sizes unmatch");
319
for (int i = 0; i < size(); i++) {
326
* Returns the signs of all elements in terms of -1, 0 and +1.
328
public DoubleVector sign()
330
DoubleVector s = new DoubleVector( size() );
331
for( int i = 0; i < size(); i++ ) {
332
if( V[i] > 0 ) s.V[i] = 1;
333
else if( V[i] < 0 ) s.V[i] = -1;
339
/** Returns the sum of all elements in the vector.
344
for( int i=0; i< size(); i++) s += V[i];
348
/** Returns the squared sum of all elements in the vector.
353
for( int i=0; i< size(); i++) s2 += V[i] * V[i];
357
/** Returns the L1-norm of the vector
359
public double norm1()
362
for( int i=0; i< size(); i++) s += Math.abs(V[i]);
366
/** Returns the L2-norm of the vector
368
public double norm2()
370
return Math.sqrt( sum2() );
373
/** Returns ||u-v||^2
374
* @param v the second vector
376
public double sum2( DoubleVector v )
378
return minus( v ).sum2();
381
/** Returns a subvector.
382
* @param i0 the index of the first element
383
* @param i1 the index of the last element
386
public DoubleVector subvector( int i0, int i1 )
388
DoubleVector v = new DoubleVector( i1-i0+1 );
389
v.set(0, i1 - i0, this, i0);
393
/** Returns a subvector.
394
* @param index stores the indices of the needed elements
397
public DoubleVector subvector( IntVector index ) {
398
DoubleVector v = new DoubleVector( index.size() );
399
for( int i = 0; i < index.size(); i++ )
400
v.V[i] = V[index.V[i]];
404
/** Returns a vector from the pivoting indices. Elements not indexed are
406
* @param index stores the pivoting indices
407
* @param length the total number of the potential elements
408
* @return the subvector */
409
public DoubleVector unpivoting( IntVector index, int length ) {
410
if( index.size() > length )
411
throw new IllegalArgumentException("index.size() > length ");
412
DoubleVector u = new DoubleVector( length );
413
for( int i = 0; i < index.size(); i++ ) {
414
u.V[index.V[i]] = V[i];
419
/** Adds a value to all the elements
422
public DoubleVector plus ( double x ) {
423
return copy().plusEquals( x );
426
/** Adds a value to all the elements in place
429
public DoubleVector plusEquals ( double x ) {
430
for( int i = 0; i < size(); i++ )
436
* Adds another vector element by element
437
* @param v the second vector
439
public DoubleVector plus( DoubleVector v ) {
440
return copy().plusEquals( v );
444
* Adds another vector in place element by element
445
* @param v the second vector
447
public DoubleVector plusEquals( DoubleVector v ) {
448
for(int i = 0; i < size(); i++ )
457
public DoubleVector minus( double x ) {
462
* Subtracts a value in place
465
public DoubleVector minusEquals( double x ) {
471
* Subtracts another DoubleVector element by element
472
* @param v the second DoubleVector
474
public DoubleVector minus( DoubleVector v ) {
475
return copy().minusEquals( v );
479
* Subtracts another DoubleVector element by element in place
480
* @param v the second DoubleVector
482
public DoubleVector minusEquals( DoubleVector v ) {
483
for(int i = 0; i < size(); i++ )
488
/** Multiplies a scalar
492
public DoubleVector times( double s ) {
493
return copy().timesEquals( s );
496
/** Multiply a vector by a scalar in place, u = s * u
498
@return replace u by s * u
500
public DoubleVector timesEquals( double s ) {
501
for (int i = 0; i < size(); i++) {
508
* Multiplies another DoubleVector element by element
509
* @param v the second DoubleVector
511
public DoubleVector times( DoubleVector v ) {
512
return copy().timesEquals( v );
517
* Multiplies another DoubleVector element by element in place
518
* @param v the second DoubleVector
520
public DoubleVector timesEquals( DoubleVector v ) {
521
for(int i = 0; i < size(); i++ )
527
* Divided by another DoubleVector element by element
528
* @param v the second DoubleVector
530
public DoubleVector dividedBy ( DoubleVector v ) {
531
return copy().dividedByEquals( v );
535
* Divided by another DoubleVector element by element in place
536
* @param v the second DoubleVector
538
public DoubleVector dividedByEquals ( DoubleVector v ) {
539
for( int i = 0; i < size(); i++ ) {
546
* Checks if it is an empty vector
548
public boolean isEmpty() {
549
if( size() == 0 ) return true;
554
* Returns a vector that stores the cumulated values of the original
556
public DoubleVector cumulate()
558
return copy().cumulateInPlace();
562
* Cumulates the original vector in place
564
public DoubleVector cumulateInPlace()
566
for (int i = 1; i < size(); i++) {
573
* Returns the index of the maximum. <p>
574
* If multiple maximums exist, the index of the first is returned.
576
public int indexOfMax()
581
for( int i = 1; i < size(); i++ ){
592
* Returns true if vector not sorted
594
public boolean unsorted () {
595
if( size() < 2 ) return false;
596
for( int i = 1; i < size(); i++ ) {
604
* Combine two vectors together
605
* @param v the second vector
607
public DoubleVector cat( DoubleVector v ) {
608
DoubleVector w = new DoubleVector( size() + v.size() );
609
w.set(0, size() - 1, this, 0);
610
w.set(size(), size() + v.size()-1, v, 0);
615
* Swaps the values stored at i and j
616
* @param i the index i
617
* @param j the index j
619
public void swap( int i, int j ){
627
* Returns the maximum value of all elements
629
public double max () {
630
if( size() < 1 ) throw new IllegalArgumentException("zero size");
632
if( size() < 2 ) return ma;
633
for( int i = 1; i < size(); i++ ) {
634
if( V[i] > ma ) ma = V[i];
641
* Applies a method to the vector
642
* @param className the class name
643
* @param method the method
645
public DoubleVector map( String className, String method ) {
647
Class c = Class.forName( className );
648
Class [] cs = new Class[1];
649
cs[ 0 ] = Double.TYPE;
650
Method m = c.getMethod( method, cs );
652
DoubleVector w = new DoubleVector( size() );
653
Object [] obj = new Object[1];
654
for( int i = 0; i < size(); i++ ) {
655
obj[0] = new Double( V[i] );
656
w.set( i, Double.parseDouble(m.invoke( null, obj ).toString()) );
660
catch ( Exception e ) {
668
* Returns the reverse vector
670
public DoubleVector rev() {
672
DoubleVector w = new DoubleVector( n );
673
for(int i = 0; i < n; i++ )
679
* Returns a random vector of uniform distribution
680
* @param n the size of the vector
682
public static DoubleVector random( int n ) {
683
DoubleVector v = new DoubleVector( n );
684
for (int i = 0; i < n; i++) {
685
v.V[i] = Math.random();
690
/** Convert the DoubleVecor to a string
692
public String toString() {
693
return toString( 5, false );
696
/** Convert the DoubleVecor to a string
697
* @param digits the number of digits after decimal point
698
* @param trailing true if trailing zeros are to be shown
700
public String toString( int digits, boolean trailing ) {
701
if( isEmpty() ) return "null vector";
703
StringBuffer text = new StringBuffer();
704
FlexibleDecimalFormat nf = new FlexibleDecimalFormat( digits,
707
for( int i = 0; i < size(); i ++ ) nf.update( V[i] );
711
for( int i = 0; i < size(); i++ ) {
712
number = nf.format(V[i]);
713
count += 1 + number.length();
714
if( count > width-1 ) {
716
count = 1 + number.length();
718
text.append( " " + number );
721
return text.toString();
724
public static void main( String args[] ) {
727
DoubleVector u = random(10);
728
DoubleVector v = random(10);
729
DoubleVector a = random(10);
732
System.out.println( random(10).plus(v).plus(w) );