From b47b287663c57f8a96cba3d07c56bd5df605880b Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 27 Jul 2008 19:15:22 +0000 Subject: [PATCH] Support for one dimensional vectors has been added to the linear algebra package with a RealVector interface, a RealVectorImpl default implementation using a single double array to store elements and a RealVectorFormat class for input/output. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_0@680166 13f79535-47bb-0310-9956-ffa450edef68 --- findbugs-exclude-filter.xml | 5 + pom.xml | 3 + .../commons/math/linear/RealMatrix.java | 51 +- .../commons/math/linear/RealMatrixImpl.java | 193 ++- .../commons/math/linear/RealVector.java | 682 +++++++++ .../commons/math/linear/RealVectorFormat.java | 334 +++++ .../commons/math/linear/RealVectorImpl.java | 1295 +++++++++++++++++ src/site/xdoc/changes.xml | 6 + .../linear/FrenchRealVectorFormatTest.java | 32 + .../math/linear/RealMatrixImplTest.java | 65 +- .../linear/RealVectorFormatAbstractTest.java | 384 +++++ .../math/linear/RealVectorFormatTest.java | 31 + .../math/linear/RealVectorImplTest.java | 1137 +++++++++++++++ 13 files changed, 4199 insertions(+), 19 deletions(-) create mode 100644 src/java/org/apache/commons/math/linear/RealVector.java create mode 100644 src/java/org/apache/commons/math/linear/RealVectorFormat.java create mode 100644 src/java/org/apache/commons/math/linear/RealVectorImpl.java create mode 100644 src/test/org/apache/commons/math/linear/FrenchRealVectorFormatTest.java create mode 100644 src/test/org/apache/commons/math/linear/RealVectorFormatAbstractTest.java create mode 100644 src/test/org/apache/commons/math/linear/RealVectorFormatTest.java create mode 100644 src/test/org/apache/commons/math/linear/RealVectorImplTest.java diff --git a/findbugs-exclude-filter.xml b/findbugs-exclude-filter.xml index 508c314b8..2b962083f 100644 --- a/findbugs-exclude-filter.xml +++ b/findbugs-exclude-filter.xml @@ -82,6 +82,11 @@ + + + + + diff --git a/pom.xml b/pom.xml index 748f2e292..79befbe6a 100644 --- a/pom.xml +++ b/pom.xml @@ -126,6 +126,9 @@ Todd C. Parnell + + Andreas Rieger + Joni Salonen diff --git a/src/java/org/apache/commons/math/linear/RealMatrix.java b/src/java/org/apache/commons/math/linear/RealMatrix.java index 4c23d0ed1..e8f081f70 100644 --- a/src/java/org/apache/commons/math/linear/RealMatrix.java +++ b/src/java/org/apache/commons/math/linear/RealMatrix.java @@ -148,6 +148,26 @@ public interface RealMatrix { * @throws MatrixIndexException if the specified column index is invalid */ RealMatrix getColumnMatrix(int column) throws MatrixIndexException; + + /** + * Returns the entries in row number row + * as a vector. Row indices start at 0. + * + * @param row the row to be fetched + * @return row vector + * @throws MatrixIndexException if the specified row index is invalid + */ + RealVector getRowVector(int row) throws MatrixIndexException; + + /** + * Returns the entries in column number column + * as a column vector. Column indices start at 0. + * + * @param column the column to be fetched + * @return column vector + * @throws MatrixIndexException if the specified column index is invalid + */ + RealVector getColumnVector(int column) throws MatrixIndexException; /** * Returns the entries in row number row as an array. @@ -255,6 +275,15 @@ public interface RealMatrix { */ double[] operate(double[] v) throws IllegalArgumentException; + /** + * Returns the result of multiplying this by the vector v. + * + * @param v the vector to operate on + * @return this*v + * @throws IllegalArgumentException if columnDimension != v.size() + */ + RealVector operate(RealVector v) throws IllegalArgumentException; + /** * Returns the (row) vector result of premultiplying this by the vector v. * @@ -264,6 +293,15 @@ public interface RealMatrix { */ double[] preMultiply(double[] v) throws IllegalArgumentException; + /** + * Returns the (row) vector result of premultiplying this by the vector v. + * + * @param v the row vector to premultiply by + * @return v*this + * @throws IllegalArgumentException if rowDimension != v.size() + */ + RealVector preMultiply(RealVector v) throws IllegalArgumentException; + /** * Returns the solution vector for a linear system with coefficient * matrix = this and constant vector = b. @@ -275,6 +313,17 @@ public interface RealMatrix { */ double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException; + /** + * Returns the solution vector for a linear system with coefficient + * matrix = this and constant vector = b. + * + * @param b constant vector + * @return vector of solution values to AX = b, where A is *this + * @throws IllegalArgumentException if this.rowDimension != b.length + * @throws InvalidMatrixException if this matrix is not square or is singular + */ + RealVector solve(RealVector b) throws IllegalArgumentException, InvalidMatrixException; + /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of @@ -287,5 +336,5 @@ public interface RealMatrix { * @throws InvalidMatrixException if this matrix is not square or is singular */ RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException; -} +} diff --git a/src/java/org/apache/commons/math/linear/RealMatrixImpl.java b/src/java/org/apache/commons/math/linear/RealMatrixImpl.java index 3a717ff83..568dd4eea 100644 --- a/src/java/org/apache/commons/math/linear/RealMatrixImpl.java +++ b/src/java/org/apache/commons/math/linear/RealMatrixImpl.java @@ -52,7 +52,7 @@ import org.apache.commons.math.util.MathUtils; public class RealMatrixImpl implements RealMatrix, Serializable { /** Serializable version identifier */ - private static final long serialVersionUID = -4828886979278117018L; + private static final long serialVersionUID = 4970229902484487012L; /** Entries of the matrix */ protected double data[][] = null; @@ -600,7 +600,17 @@ public class RealMatrixImpl implements RealMatrix, Serializable { return new RealMatrixImpl(out, false); } - /** + /** {@inheritDoc} */ + public RealVector getColumnVector(int column) throws MatrixIndexException { + return new RealVectorImpl(getColumn(column), false); + } + + /** {@inheritDoc} */ + public RealVector getRowVector(int row) throws MatrixIndexException { + return new RealVectorImpl(getRow(row), false); + } + + /** * Returns the entries in row number row as an array. *

* Row indices start at 0. A MatrixIndexException is thrown @@ -788,6 +798,40 @@ public class RealMatrixImpl implements RealMatrix, Serializable { return out; } + /** {@inheritDoc} */ + public RealVector operate(RealVector v) throws IllegalArgumentException { + try { + return operate((RealVectorImpl) v); + } catch (ClassCastException cce) { + final int nRows = this.getRowDimension(); + final int nCols = this.getColumnDimension(); + if (v.getDimension() != nCols) { + throw new IllegalArgumentException("vector has wrong length"); + } + final double[] out = new double[nRows]; + for (int row = 0; row < nRows; row++) { + final double[] dataRow = data[row]; + double sum = 0; + for (int i = 0; i < nCols; i++) { + sum += dataRow[i] * v.getEntry(i); + } + out[row] = sum; + } + return new RealVectorImpl(out, false); + } + } + + /** + * Returns the result of multiplying this by the vector v. + * + * @param v the vector to operate on + * @return this*v + * @throws IllegalArgumentException if columnDimension != v.size() + */ + public RealVectorImpl operate(RealVectorImpl v) throws IllegalArgumentException { + return new RealVectorImpl(operate(v.getDataRef()), false); + } + /** * @param v vector to premultiply by * @throws IllegalArgumentException if rowDimension != v.length @@ -810,6 +854,39 @@ public class RealMatrixImpl implements RealMatrix, Serializable { return out; } + /** {@inheritDoc} */ + public RealVector preMultiply(RealVector v) throws IllegalArgumentException { + try { + return preMultiply((RealVectorImpl) v); + } catch (ClassCastException cce) { + final int nRows = this.getRowDimension(); + if (v.getDimension() != nRows) { + throw new IllegalArgumentException("vector has wrong length"); + } + final int nCols = this.getColumnDimension(); + final double[] out = new double[nCols]; + for (int col = 0; col < nCols; col++) { + double sum = 0; + for (int i = 0; i < nRows; i++) { + sum += data[i][col] * v.getEntry(i); + } + out[col] = sum; + } + return new RealVectorImpl(out, false); + } + } + + /** + * Returns the (row) vector result of premultiplying this by the vector v. + * + * @param v the row vector to premultiply by + * @return v*this + * @throws IllegalArgumentException if rowDimension != v.size() + */ + RealVectorImpl preMultiply(RealVectorImpl v) throws IllegalArgumentException { + return new RealVectorImpl(preMultiply(v.getDataRef()), false); + } + /** * Returns a matrix of (column) solution vectors for linear systems with * coefficient matrix = this and constant vectors = columns of @@ -822,17 +899,105 @@ public class RealMatrixImpl implements RealMatrix, Serializable { * @throws InvalidMatrixException if this matrix is not square or is singular */ public double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException { + final int nRows = this.getRowDimension(); + final int nCol = this.getColumnDimension(); + if (b.length != nRows) { throw new IllegalArgumentException("constant vector has wrong length"); } - final RealMatrix bMatrix = new RealMatrixImpl(b); - final double[][] solution = ((RealMatrixImpl) (solve(bMatrix))).getDataRef(); - final double[] out = new double[nRows]; - for (int row = 0; row < nRows; row++) { - out[row] = solution[row][0]; + if (!isSquare()) { + throw new InvalidMatrixException("coefficient matrix is not square"); } - return out; + if (isSingular()) { // side effect: compute LU decomp + throw new InvalidMatrixException("Matrix is singular."); + } + + final double[] bp = new double[nRows]; + + // Apply permutations to b + for (int row = 0; row < nRows; row++) { + bp[row] = b[permutation[row]]; + } + + // Solve LY = b + for (int col = 0; col < nCol; col++) { + for (int i = col + 1; i < nCol; i++) { + bp[i] -= bp[col] * lu[i][col]; + } + } + + // Solve UX = Y + for (int col = nCol - 1; col >= 0; col--) { + bp[col] /= lu[col][col]; + for (int i = 0; i < col; i++) { + bp[i] -= bp[col] * lu[i][col]; + } + } + + return bp; + + } + + /** {@inheritDoc} */ + public RealVector solve(RealVector b) + throws IllegalArgumentException, InvalidMatrixException { + try { + return solve((RealVectorImpl) b); + } catch (ClassCastException cce) { + + final int nRows = this.getRowDimension(); + final int nCol = this.getColumnDimension(); + + if (b.getDimension() != nRows) { + throw new IllegalArgumentException("constant vector has wrong length"); + } + if (!isSquare()) { + throw new InvalidMatrixException("coefficient matrix is not square"); + } + if (isSingular()) { // side effect: compute LU decomp + throw new InvalidMatrixException("Matrix is singular."); + } + + final double[] bp = new double[nRows]; + + // Apply permutations to b + for (int row = 0; row < nRows; row++) { + bp[row] = b.getEntry(permutation[row]); + } + + // Solve LY = b + for (int col = 0; col < nCol; col++) { + for (int i = col + 1; i < nCol; i++) { + bp[i] -= bp[col] * lu[i][col]; + } + } + + // Solve UX = Y + for (int col = nCol - 1; col >= 0; col--) { + bp[col] /= lu[col][col]; + for (int i = 0; i < col; i++) { + bp[i] -= bp[col] * lu[i][col]; + } + } + + return new RealVectorImpl(bp, false); + + } + } + + /** + * Returns the solution vector for a linear system with coefficient + * matrix = this and constant vector = b. + * + * @param b constant vector + * @return vector of solution values to AX = b, where A is *this + * @throws IllegalArgumentException if this.rowDimension != b.length + * @throws InvalidMatrixException if this matrix is not square or is singular + */ + RealVectorImpl solve(RealVectorImpl b) + throws IllegalArgumentException, InvalidMatrixException { + return new RealVectorImpl(solve(b.getDataRef()), false); } /** @@ -865,18 +1030,20 @@ public class RealMatrixImpl implements RealMatrix, Serializable { final double[][] bp = new double[nRowB][nColB]; for (int row = 0; row < nRowB; row++) { final double[] bpRow = bp[row]; + final int pRow = permutation[row]; for (int col = 0; col < nColB; col++) { - bpRow[col] = b.getEntry(permutation[row], col); + bpRow[col] = b.getEntry(pRow, col); } } // Solve LY = b for (int col = 0; col < nCol; col++) { + final double[] bpCol = bp[col]; for (int i = col + 1; i < nCol; i++) { final double[] bpI = bp[i]; - final double[] luI = lu[i]; + final double luICol = lu[i][col]; for (int j = 0; j < nColB; j++) { - bpI[j] -= bp[col][j] * luI[col]; + bpI[j] -= bpCol[j] * luICol; } } } @@ -890,9 +1057,9 @@ public class RealMatrixImpl implements RealMatrix, Serializable { } for (int i = 0; i < col; i++) { final double[] bpI = bp[i]; - final double[] luI = lu[i]; + final double luICol = lu[i][col]; for (int j = 0; j < nColB; j++) { - bpI[j] -= bp[col][j] * luI[col]; + bpI[j] -= bpCol[j] * luICol; } } } diff --git a/src/java/org/apache/commons/math/linear/RealVector.java b/src/java/org/apache/commons/math/linear/RealVector.java new file mode 100644 index 000000000..d3718e488 --- /dev/null +++ b/src/java/org/apache/commons/math/linear/RealVector.java @@ -0,0 +1,682 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.linear; + +/** + * Interface defining a real-valued vector with basic algebraic operations. + *

+ * vector element indexing is 0-based -- e.g., getEntry(0) + * returns the first element of the vector. + *

+ *

+ * The various mapXxx and mapXxxToSelf methods operate + * on vectors element-wise, i.e. they perform the same operation (adding a scalar, + * applying a function ...) on each element in turn. The mapXxx + * versions create a new vector to hold the result and do not change the instance. + * The mapXxxToSelf versions use the instance itself to store the + * results, so the instance is changed by these methods. In both cases, the result + * vector is returned by the methods, this allows to use the fluent API + * style, like this: + *

+ *
+ *   RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
+ * 
+ * + * @version $Revision$ $Date$ + * @since 2.0 + */ +public interface RealVector { + + /** + * Returns a (deep) copy of this. + * @return vector copy + */ + RealVector copy(); + + /** + * Compute the sum of this and v. + * @param v vector to be added + * @return this + v + * @throws IllegalArgumentException if v is not the same size as this + */ + RealVector add(RealVector v) + throws IllegalArgumentException; + + /** + * Compute this minus v. + * @param v vector to be subtracted + * @return this + v + * @throws IllegalArgumentException if v is not the same size as this + */ + RealVector subtract(RealVector v) + throws IllegalArgumentException; + + /** + * Map an addition operation to each entry. + * @param d value to be added to each entry + * @return this + d + */ + RealVector mapAdd(double d); + + /** + * Map an addition operation to each entry. + *

The instance is changed by this method.

+ * @param d value to be added to each entry + * @return for convenience, return this + */ + RealVector mapAddToSelf(double d); + + /** + * Map a subtraction operation to each entry. + * @param d value to be subtracted to each entry + * @return this - d + */ + RealVector mapSubtract(double d); + + /** + * Map a subtraction operation to each entry. + *

The instance is changed by this method.

+ * @param d value to be subtracted to each entry + * @return for convenience, return this + */ + RealVector mapSubtractToSelf(double d); + + /** + * Map a multiplication operation to each entry. + * @param d value to multiply all entries by + * @return this * d + */ + RealVector mapMultiply(double d); + + /** + * Map a multiplication operation to each entry. + *

The instance is changed by this method.

+ * @param d value to multiply all entries by + * @return for convenience, return this + */ + RealVector mapMultiplyToSelf(double d); + + /** + * Map a division operation to each entry. + * @param d value to divide all entries by + * @return this / d + */ + RealVector mapDivide(double d); + + /** + * Map a division operation to each entry. + *

The instance is changed by this method.

+ * @param d value to divide all entries by + * @return for convenience, return this + */ + RealVector mapDivideToSelf(double d); + + /** + * Map a power operation to each entry. + * @param d value to raise all entries to + * @return this ^ d + */ + RealVector mapPow(double d); + + /** + * Map a power operation to each entry. + *

The instance is changed by this method.

+ * @param d value to raise all entries to + * @return for convenience, return this + */ + RealVector mapPowToSelf(double d); + + /** + * Map the {@link Math#exp(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapExp(); + + /** + * Map the {@link Math#exp(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapExpToSelf(); + + /** + * Map the {@link Math#expm1(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapExpm1(); + + /** + * Map the {@link Math#expm1(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapExpm1ToSelf(); + + /** + * Map the {@link Math#log(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapLog(); + + /** + * Map the {@link Math#log(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapLogToSelf(); + + /** + * Map the {@link Math#log10(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapLog10(); + + /** + * Map the {@link Math#log10(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapLog10ToSelf(); + + /** + * Map the {@link Math#log1p(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapLog1p(); + + /** + * Map the {@link Math#log1p(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapLog1pToSelf(); + + /** + * Map the {@link Math#cosh(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapCosh(); + + /** + * Map the {@link Math#cosh(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapCoshToSelf(); + + /** + * Map the {@link Math#sinh(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapSinh(); + + /** + * Map the {@link Math#sinh(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapSinhToSelf(); + + /** + * Map the {@link Math#tanh(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapTanh(); + + /** + * Map the {@link Math#tanh(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapTanhToSelf(); + + /** + * Map the {@link Math#cos(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapCos(); + + /** + * Map the {@link Math#cos(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapCosToSelf(); + + /** + * Map the {@link Math#sin(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapSin(); + + /** + * Map the {@link Math#sin(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapSinToSelf(); + + /** + * Map the {@link Math#tan(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapTan(); + + /** + * Map the {@link Math#tan(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapTanToSelf(); + + /** + * Map the {@link Math#acos(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapAcos(); + + /** + * Map the {@link Math#acos(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapAcosToSelf(); + + /** + * Map the {@link Math#asin(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapAsin(); + + /** + * Map the {@link Math#asin(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapAsinToSelf(); + + /** + * Map the {@link Math#atan(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapAtan(); + + /** + * Map the {@link Math#atan(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapAtanToSelf(); + + /** + * Map the 1/x function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapInv(); + + /** + * Map the 1/x function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapInvToSelf(); + + /** + * Map the {@link Math#abs(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapAbs(); + + /** + * Map the {@link Math#abs(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapAbsToSelf(); + + /** + * Map the {@link Math#sqrt(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapSqrt(); + + /** + * Map the {@link Math#sqrt(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapSqrtToSelf(); + + /** + * Map the {@link Math#cbrt(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapCbrt(); + + /** + * Map the {@link Math#cbrt(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapCbrtToSelf(); + + /** + * Map the {@link Math#ceil(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapCeil(); + + /** + * Map the {@link Math#ceil(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapCeilToSelf(); + + /** + * Map the {@link Math#floor(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapFloor(); + + /** + * Map the {@link Math#floor(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapFloorToSelf(); + + /** + * Map the {@link Math#rint(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapRint(); + + /** + * Map the {@link Math#rint(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapRintToSelf(); + + /** + * Map the {@link Math#signum(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapSignum(); + + /** + * Map the {@link Math#signum(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapSignumToSelf(); + + /** + * Map the {@link Math#ulp(double)} function to each entry. + * @return a vector containing the result of applying the function to each entry + */ + RealVector mapUlp(); + + /** + * Map the {@link Math#ulp(double)} function to each entry. + *

The instance is changed by this method.

+ * @return for convenience, return this + */ + RealVector mapUlpToSelf(); + + /** + * Element-by-element multiplication. + * @param v vector by which instance elements must be multiplied + * @return a vector containing this[i] * v[i] for all i + * @throws IllegalArgumentException if v is not the same size as this + */ + public RealVector ebeMultiply(RealVector v) + throws IllegalArgumentException; + + /** + * Element-by-element division. + * @param v vector by which instance elements must be divided + * @return a vector containing this[i] / v[i] for all i + * @throws IllegalArgumentException if v is not the same size as this + */ + public RealVector ebeDivide(RealVector v) + throws IllegalArgumentException; + + /** + * Returns vector entries as a double array. + * @return double array of entries + */ + double[] getData(); + + /** + * Compute the dot product. + * @param v vector with which dot product should be computed + * @return the scalar dot product between instance and v + * @exception IllegalArgumentException if v is not the same size as this + */ + double dotProduct(RealVector v) + throws IllegalArgumentException; + + /** + * Returns the L2 norm of the vector. + *

The L2 norm is the root of the sum of + * the squared elements.

+ * @return norm + * @see #getL1Norm() + * @see #getLInfNorm() + * @see #getDistance(RealVector) + */ + double getNorm(); + + /** + * Returns the L1 norm of the vector. + *

The L1 norm is the sum of the absolute + * values of elements.

+ * @return norm + * @see #getNorm() + * @see #getLInfNorm() + * @see #getL1Distance(RealVector) + */ + double getL1Norm(); + + /** + * Returns the L&infty; norm of the vector. + *

The L&infty; norm is the max of the absolute + * values of elements.

+ * @return norm + * @see #getNorm() + * @see #getL1Norm() + * @see #getLInfDistance(RealVector) + */ + double getLInfNorm(); + + /** + * Distance between two vectors. + *

This method computes the distance consistent with the + * L2 norm, i.e. the square root of the sum of + * elements differences, or euclidian distance.

+ * @param v vector to which distance is requested + * @return distance between two vectors. + * @exception IllegalArgumentException if v is not the same size as this + * @see #getL1Distance(RealVector) + * @see #getLInfDistance(RealVector) + * @see #getNorm() + */ + double getDistance(RealVector v) + throws IllegalArgumentException; + + /** + * Distance between two vectors. + *

This method computes the distance consistent with + * L1 norm, i.e. the sum of the absolute values of + * elements differences.

+ * @param v vector to which distance is requested + * @return distance between two vectors. + * @exception IllegalArgumentException if v is not the same size as this + * @see #getDistance(RealVector) + * @see #getLInfDistance(RealVector) + * @see #getL1Norm() + */ + double getL1Distance(RealVector v) + throws IllegalArgumentException; + + /** + * Distance between two vectors. + *

This method computes the distance consistent with + * L&infty; norm, i.e. the max of the absolute values of + * elements differences.

+ * @param v vector to which distance is requested + * @return distance between two vectors. + * @exception IllegalArgumentException if v is not the same size as this + * @see #getDistance(RealVector) + * @see #getL1Distance(RealVector) + * @see #getLInfNorm() + */ + double getLInfDistance(RealVector v) + throws IllegalArgumentException; + + /** Creates a unit vector pointing in the direction of this vector. + *

The instance is not changed by this method.

+ * @return a unit vector pointing in direction of this vector + * @exception ArithmeticException if the norm is null + */ + RealVector unitVector(); + + /** Converts this vector into a unit vector. + *

The instance itself is changed by this method.

+ * @exception ArithmeticException if the norm is null + */ + void unitize(); + + /** Find the orthogonal projection of this vector onto another vector. + * @param v vector onto which instance must be projected + * @return projection of the instance onto v + * @throws IllegalArgumentException if v is not the same size as this + */ + RealVector projection(RealVector v) + throws IllegalArgumentException; + + /** + * Compute the outer product. + * @param v vector with which outer product should be computed + * @return the square matrix outer product between instance and v + * @exception IllegalArgumentException if v is not the same size as this + */ + RealMatrix outerProduct(RealVector v) + throws IllegalArgumentException; + + /** + * Returns the entry in the specified index. + *

+ * The index start at 0 and must be lesser than the size, + * otherwise a {@link MatrixIndexException} is thrown. + *

+ * @param index index location of entry to be fetched + * @return vector entry at index + * @throws MatrixIndexException if the index is not valid + */ + double getEntry(int index) + throws MatrixIndexException; + + /** + * Returns the size of the vector. + * @return size + */ + int getDimension(); + + /** + * Construct a vector by appending a vector to this vector. + * @param v vector to append to this one. + * @return a new vector + */ + RealVector append(RealVector v); + + /** + * Construct a vector by appending a double to this vector. + * @param d double to append. + * @return a new vector + */ + RealVector append(double d); + + /** + * Construct a vector by appending a double array to this vector. + * @param a double array to append. + * @return a new vector + */ + RealVector append(double[] a); + + /** + * Get a subvector from consecutive elements. + * @param index index of first element. + * @param n number of elements to be retrieved. + * @return a vector containing n elements. + * @exception MatrixIndexException if the index is + * inconsistent with vector size + */ + RealVector get(int index, int n) + throws MatrixIndexException; + + /** + * Set a single element. + * @param index element index. + * @param value new value for the element. + * @exception MatrixIndexException if the index is + * inconsistent with vector size + */ + void set(int index, double value) + throws MatrixIndexException; + + /** + * Set a set of consecutive elements. + * @param index index of first element to be set. + * @param v vector containing the values to set. + * @exception MatrixIndexException if the index is + * inconsistent with vector size + */ + void set(int index, RealVector v) + throws MatrixIndexException; + + /** + * Set all elements to a single value. + * @param value single value to set for all elements + */ + void set(double value); + + /** + * Convert the vector to a double array. + *

The array is independent from vector data, it's elements + * are copied.

+ * @return array containing a copy of vector elements + */ + double[] toArray(); + + /** + * Returns true if any coordinate of this vector is NaN; false otherwise + * @return true if any coordinate of this vector is NaN; false otherwise + */ + public boolean isNaN(); + + /** + * Returns true if any coordinate of this vector is infinite and none are NaN; + * false otherwise + * @return true if any coordinate of this vector is infinite and none are NaN; + * false otherwise + */ + public boolean isInfinite(); + +} diff --git a/src/java/org/apache/commons/math/linear/RealVectorFormat.java b/src/java/org/apache/commons/math/linear/RealVectorFormat.java new file mode 100644 index 000000000..2996a0339 --- /dev/null +++ b/src/java/org/apache/commons/math/linear/RealVectorFormat.java @@ -0,0 +1,334 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math.linear; + +import java.text.FieldPosition; +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.apache.commons.math.util.CompositeFormat; + +/** + * Formats a vector in components list format "{v0; v1; ...; vk-1}". + *

The prefix and suffix "{" and "}" and the separator "; " can be replaced by + * any user-defined strings. The number format for components can be configured.

+ *

White space is ignored at parse time, even if it is in the prefix, suffix + * or separator specifications. So even if the default separator does include a space + * character that is used at format time, both input string "{1;1;1}" and + * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be + * returned. In the second case, however, the parse position after parsing will be + * just after the closing curly brace, i.e. just before the trailing space.

+ * + * @version $Revision$ $Date$ + * @since 2.0 + */ +public class RealVectorFormat extends CompositeFormat { + + /** Serializable version identifier */ + private static final long serialVersionUID = -708767813036157690L; + + /** The default prefix: "{". */ + private static final String DEFAULT_PREFIX = "{"; + + /** The default suffix: "}". */ + private static final String DEFAULT_SUFFIX = "}"; + + /** The default separator: ", ". */ + private static final String DEFAULT_SEPARATOR = "; "; + + /** Prefix. */ + private final String prefix; + + /** Suffix. */ + private final String suffix; + + /** Separator. */ + private final String separator; + + /** Trimmed prefix. */ + private final String trimmedPrefix; + + /** Trimmed suffix. */ + private final String trimmedSuffix; + + /** Trimmed separator. */ + private final String trimmedSeparator; + + /** The format used for components. */ + private NumberFormat format; + + /** + * Create an instance with default settings. + *

The instance uses the default prefix, suffix and separator: + * "{", "}", and "; " and the default number format for components.

+ */ + public RealVectorFormat() { + this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, getDefaultNumberFormat()); + } + + /** + * Create an instance with a custom number format for components. + * @param format the custom format for components. + */ + public RealVectorFormat(final NumberFormat format) { + this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format); + } + + /** + * Create an instance with custom prefix, suffix and separator. + * @param prefix prefix to use instead of the default "{" + * @param suffix suffix to use instead of the default "}" + * @param separator separator to use instead of the default "; " + */ + public RealVectorFormat(final String prefix, final String suffix, + final String separator) { + this(prefix, suffix, separator, getDefaultNumberFormat()); + } + + /** + * Create an instance with custom prefix, suffix, separator and format + * for components. + * @param prefix prefix to use instead of the default "{" + * @param suffix suffix to use instead of the default "}" + * @param separator separator to use instead of the default "; " + * @param format the custom format for components. + */ + public RealVectorFormat(final String prefix, final String suffix, + final String separator, final NumberFormat format) { + this.prefix = prefix; + this.suffix = suffix; + this.separator = separator; + trimmedPrefix = prefix.trim(); + trimmedSuffix = suffix.trim(); + trimmedSeparator = separator.trim(); + this.format = format; + } + + /** + * Get the set of locales for which real vectors formats are available. + *

This is the same set as the {@link NumberFormat} set.

+ * @return available real vector format locales. + */ + public static Locale[] getAvailableLocales() { + return NumberFormat.getAvailableLocales(); + } + + /** + * Get the format prefix. + * @return format prefix. + */ + public String getPrefix() { + return prefix; + } + + /** + * Get the format suffix. + * @return format suffix. + */ + public String getSuffix() { + return suffix; + } + + /** + * Get the format separator between components. + * @return format separator. + */ + public String getSeparator() { + return separator; + } + + /** + * Get the components format. + * @return components format. + */ + public NumberFormat getFormat() { + return format; + } + + /** + * Returns the default real vector format for the current locale. + * @return the default real vector format. + */ + public static RealVectorFormat getInstance() { + return getInstance(Locale.getDefault()); + } + + /** + * Returns the default real vector format for the given locale. + * @param locale the specific locale used by the format. + * @return the real vector format specific to the given locale. + */ + public static RealVectorFormat getInstance(final Locale locale) { + return new RealVectorFormat(getDefaultNumberFormat(locale)); + } + + /** + * This static method calls {@link #format(Object)} on a default instance of + * RealVectorFormat. + * + * @param v RealVector object to format + * @return A formatted vector + */ + public static String formatRealVector(RealVector v) { + return getInstance().format(v); + } + + /** + * Formats a {@link RealVector} object to produce a string. + * @param vector the object to format. + * @param toAppendTo where the text is to be appended + * @param pos On input: an alignment field, if desired. On output: the + * offsets of the alignment field + * @return the value passed in as toAppendTo. + */ + public StringBuffer format(RealVector vector, StringBuffer toAppendTo, + FieldPosition pos) { + + pos.setBeginIndex(0); + pos.setEndIndex(0); + + // format prefix + toAppendTo.append(prefix); + + // format components + for (int i = 0; i < vector.getDimension(); ++i) { + if (i > 0) { + toAppendTo.append(separator); + } + formatDouble(vector.getEntry(i), format, toAppendTo, pos); + } + + // format suffix + toAppendTo.append(suffix); + + return toAppendTo; + + } + + /** + * Formats a object to produce a string. + *

obj must be a {@link RealVector} object. Any other type of + * object will result in an {@link IllegalArgumentException} being thrown.

+ * @param obj the object to format. + * @param toAppendTo where the text is to be appended + * @param pos On input: an alignment field, if desired. On output: the + * offsets of the alignment field + * @return the value passed in as toAppendTo. + * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) + * @throws IllegalArgumentException is obj is not a valid type. + */ + public StringBuffer format(Object obj, StringBuffer toAppendTo, + FieldPosition pos) { + + if (obj instanceof RealVector) { + return format( (RealVector)obj, toAppendTo, pos); + } + + throw new IllegalArgumentException("Cannot format given Object as a RealVector"); + + } + + /** + * Parses a string to produce a {@link RealVector} object. + * @param source the string to parse + * @return the parsed {@link RealVector} object. + * @exception ParseException if the beginning of the specified string + * cannot be parsed. + */ + public RealVectorImpl parse(String source) throws ParseException { + ParsePosition parsePosition = new ParsePosition(0); + RealVectorImpl result = parse(source, parsePosition); + if (parsePosition.getIndex() == 0) { + throw new ParseException("Unparseable real vector: \"" + source + + "\"", parsePosition.getErrorIndex()); + } + return result; + } + + /** + * Parses a string to produce a {@link RealVector} object. + * @param source the string to parse + * @param pos input/ouput parsing parameter. + * @return the parsed {@link RealVector} object. + */ + public RealVectorImpl parse(String source, ParsePosition pos) { + int initialIndex = pos.getIndex(); + + // parse prefix + parseAndIgnoreWhitespace(source, pos); + if (!parseFixedstring(source, trimmedPrefix, pos)) { + return null; + } + + // parse components + List components = new ArrayList(); + for (boolean loop = true; loop;){ + + if (!components.isEmpty()) { + parseAndIgnoreWhitespace(source, pos); + if (!parseFixedstring(source, trimmedSeparator, pos)) { + loop = false; + } + } + + if (loop) { + parseAndIgnoreWhitespace(source, pos); + Number component = parseNumber(source, format, pos); + if (component != null) { + components.add(component); + } else { + // invalid component + // set index back to initial, error index should already be set + pos.setIndex(initialIndex); + return null; + } + } + + } + + // parse suffix + parseAndIgnoreWhitespace(source, pos); + if (!parseFixedstring(source, trimmedSuffix, pos)) { + return null; + } + + // build vector + double[] data = new double[components.size()]; + for (int i = 0; i < data.length; ++i) { + data[i] = components.get(i).doubleValue(); + } + return new RealVectorImpl(data, false); + + } + + /** + * Parses a string to produce a object. + * @param source the string to parse + * @param pos input/ouput parsing parameter. + * @return the parsed object. + * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) + */ + public Object parseObject(String source, ParsePosition pos) { + return parse(source, pos); + } + +} diff --git a/src/java/org/apache/commons/math/linear/RealVectorImpl.java b/src/java/org/apache/commons/math/linear/RealVectorImpl.java new file mode 100644 index 000000000..f30524676 --- /dev/null +++ b/src/java/org/apache/commons/math/linear/RealVectorImpl.java @@ -0,0 +1,1295 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.linear; + +import java.io.Serializable; +import java.util.Arrays; + +import org.apache.commons.math.util.MathUtils; + +/** + * This class implements the {@link RealVector} interface with a double array. + * @version $Revision$ $Date$ + * @since 2.0 + */ +public class RealVectorImpl implements RealVector, Serializable { + + /** Serializable version identifier. */ + private static final long serialVersionUID = 7838747548772166404L; + + /** Default format. */ + private static final RealVectorFormat DEFAULT_FORMAT = + RealVectorFormat.getInstance(); + + /** Entries of the vector. */ + protected double data[]; + + /** + * Build a 0-length vector. + *

Zero-length vectors may be used to initialized construction of vectors + * by data gathering. We start with zero-length and use either the {@link + * #RealVectorImpl(RealVectorImpl, RealVectorImpl)} constructor + * or one of the append method ({@link #append(double)}, {@link + * #append(double[])}, {@link #append(RealVectorImpl)}) to gather data + * into this vector.

+ */ + public RealVectorImpl() { + data = new double[0]; + } + + /** + * Construct a (size)-length vector of zeros. + * @param size size of the vector + */ + public RealVectorImpl(int size) { + data = new double[size]; + } + + /** + * Construct an (size)-length vector with preset values. + * @param size size of the vector + * @param preset fill the vector with this scalar value + */ + public RealVectorImpl(int size, double preset) { + data = new double[size]; + Arrays.fill(data, preset); + } + + /** + * Construct a vector from an array, copying the input array. + * @param d array of doubles. + */ + public RealVectorImpl(double[] d) { + data = d.clone(); + } + + /** + * Create a new RealVectorImpl using the input array as the underlying + * data array. + *

If an array is built specially in order to be embedded in a + * RealVectorImpl and not used directly, the copyArray may be + * set to false + * @param d data for new vector + * @param copyArray if true, the input array will be copied, otherwise + * it will be referenced + * @throws IllegalArgumentException if d is empty + * @throws NullPointerException if d is null + * @see #RealVectorImpl(double[]) + */ + public RealVectorImpl(double[] d, boolean copyArray) + throws NullPointerException, IllegalArgumentException { + if (d == null) { + throw new NullPointerException(); + } + if (d.length == 0) { + throw new IllegalArgumentException("Vector must have at least one element."); + } + data = copyArray ? d.clone() : d; + } + + /** + * Construct a vector from part of a array. + * @param d array of doubles. + * @param pos position of first entry + * @param size number of entries to copy + */ + public RealVectorImpl(double[] d, int pos, int size) { + if (d.length < pos + size) { + throw new IllegalArgumentException("Position " + pos + " and size " + size + + " don't fit to the size of the input array " + + d.length); + } + data = new double[size]; + System.arraycopy(d, pos, data, 0, size); + } + + /** + * Construct a vector from an array. + * @param d array of Doubles. + */ + public RealVectorImpl(Double[] d) { + data = new double[d.length]; + for (int i = 0; i < d.length; i++) { + data[i] = d[i].doubleValue(); + } + } + + /** + * Construct a vector from part of a Double array + * @param d array of Doubles. + * @param pos position of first entry + * @param size number of entries to copy + */ + public RealVectorImpl(Double[] d, int pos, int size) { + if (d.length < pos + size) { + throw new IllegalArgumentException("Position " + pos + " and size " + size + + " don't fit to the size of the input array " + + d.length); + } + data = new double[size]; + for (int i = pos; i < pos + size; i++) { + data[i-pos] = d[i].doubleValue(); + } + } + + /** + * Construct a vector from another vector, using a deep copy. + * @param v vector to copy + */ + public RealVectorImpl(RealVector v) { + data = new double[v.getDimension()]; + for (int i = 0; i < data.length; ++i) { + data[i] = v.getEntry(i); + } + } + + /** + * Construct a vector from another vector, using a deep copy. + * @param v vector to copy + */ + public RealVectorImpl(RealVectorImpl v) { + data = v.data.clone(); + } + + /** + * Construct a vector from another vector. + * @param v vector to copy + * @param deep if true perform a deep copy otherwise perform a shallow copy + */ + public RealVectorImpl(RealVectorImpl v, boolean deep) { + data = deep ? v.data.clone() : v.data; + } + + /** + * Construct a vector by appending one vector to another vector. + * @param v1 first vector (will be put in front of the new vector) + * @param v2 second vector (will be put at back of the new vector) + */ + public RealVectorImpl(RealVectorImpl v1, RealVectorImpl v2) { + data = new double[v1.data.length + v2.data.length]; + System.arraycopy(v1.data, 0, data, 0, v1.data.length); + System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length); + } + + /** {@inheritDoc} */ + public RealVector copy() { + return new RealVectorImpl(this, true); + } + + /** {@inheritDoc} */ + public RealVector add(RealVector v) + throws IllegalArgumentException { + try { + return add((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] + v.getEntry(i); + } + return new RealVectorImpl(out); + } + } + + /** + * Compute the sum of this and v. + * @param v vector to be added + * @return this + v + * @throws IllegalArgumentException if v is not the same size as this + */ + public RealVectorImpl add(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] + v.data[i]; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector subtract(RealVector v) + throws IllegalArgumentException { + try { + return subtract((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] - v.getEntry(i); + } + return new RealVectorImpl(out); + } + } + + /** + * Compute this minus v. + * @param v vector to be subtracted + * @return this + v + * @throws IllegalArgumentException if v is not the same size as this + */ + public RealVectorImpl subtract(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] - v.data[i]; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapAdd(double d) { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] + d; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapAddToSelf(double d) { + for (int i = 0; i < data.length; i++) { + data[i] = data[i] + d; + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapSubtract(double d) { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] - d; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapSubtractToSelf(double d) { + for (int i = 0; i < data.length; i++) { + data[i] = data[i] - d; + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapMultiply(double d) { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] * d; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapMultiplyToSelf(double d) { + for (int i = 0; i < data.length; i++) { + data[i] = data[i] * d; + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapDivide(double d) { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] / d; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapDivideToSelf(double d) { + for (int i = 0; i < data.length; i++) { + data[i] = data[i] / d; + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapPow(double d) { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.pow(data[i], d); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapPowToSelf(double d) { + for (int i = 0; i < data.length; i++) { + data[i] = Math.pow(data[i], d); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapExp() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.exp(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapExpToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.exp(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapExpm1() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.expm1(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapExpm1ToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.expm1(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapLog() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.log(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapLogToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.log(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapLog10() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.log10(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapLog10ToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.log10(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapLog1p() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.log1p(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapLog1pToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.log1p(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapCosh() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.cosh(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapCoshToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.cosh(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapSinh() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.sinh(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapSinhToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.sinh(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapTanh() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.tanh(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapTanhToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.tanh(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapCos() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.cos(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapCosToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.cos(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapSin() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.sin(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapSinToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.sin(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapTan() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.tan(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapTanToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.tan(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapAcos() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.acos(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapAcosToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.acos(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapAsin() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.asin(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapAsinToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.asin(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapAtan() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.atan(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapAtanToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.atan(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapInv() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = 1.0 / data[i]; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapInvToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = 1.0 / data[i]; + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapAbs() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.abs(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapAbsToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.abs(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapSqrt() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.sqrt(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapSqrtToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.sqrt(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapCbrt() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.cbrt(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapCbrtToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.cbrt(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapCeil() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.ceil(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapCeilToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.ceil(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapFloor() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.floor(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapFloorToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.floor(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapRint() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.rint(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapRintToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.rint(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapSignum() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.signum(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapSignumToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.signum(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector mapUlp() { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = Math.ulp(data[i]); + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector mapUlpToSelf() { + for (int i = 0; i < data.length; i++) { + data[i] = Math.ulp(data[i]); + } + return this; + } + + /** {@inheritDoc} */ + public RealVector ebeMultiply(RealVector v) + throws IllegalArgumentException { + try { + return ebeMultiply((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] * v.getEntry(i); + } + return new RealVectorImpl(out); + } + } + + /** + * Element-by-element multiplication. + * @param v vector by which instance elements must be multiplied + * @return a vector containing this[i] * v[i] for all i + * @exception IllegalArgumentException if v is not the same size as this + */ + public RealVectorImpl ebeMultiply(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] * v.data[i]; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector ebeDivide(RealVector v) + throws IllegalArgumentException { + try { + return ebeDivide((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] / v.getEntry(i); + } + return new RealVectorImpl(out); + } + } + + /** + * Element-by-element division. + * @param v vector by which instance elements must be divided + * @return a vector containing this[i] / v[i] for all i + * @throws IllegalArgumentException if v is not the same size as this + */ + public RealVectorImpl ebeDivide(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] / v.data[i]; + } + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public double[] getData() { + return data.clone(); + } + + /** + * Returns a reference to the underlying data array. + *

Does not make a fresh copy of the underlying data.

+ * @return array of entries + */ + public double[] getDataRef() { + return data; + } + + /** {@inheritDoc} */ + public double dotProduct(RealVector v) + throws IllegalArgumentException { + try { + return dotProduct((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double dot = 0; + for (int i = 0; i < data.length; i++) { + dot += data[i] * v.getEntry(i); + } + return dot; + } + } + + /** + * Compute the dot product. + * @param v vector with which dot product should be computed + * @return the scalar dot product between instance and v + * @exception IllegalArgumentException if v is not the same size as this + */ + public double dotProduct(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double dot = 0; + for (int i = 0; i < data.length; i++) { + dot += data[i] * v.getEntry(i); + } + return dot; + } + + /** {@inheritDoc} */ + public double getNorm() { + double sum = 0; + for (double a : data) { + sum += a * a; + } + return Math.sqrt(sum); + } + + /** {@inheritDoc} */ + public double getL1Norm() { + double sum = 0; + for (double a : data) { + sum += Math.abs(a); + } + return sum; + } + + /** {@inheritDoc} */ + public double getLInfNorm() { + double max = 0; + for (double a : data) { + max += Math.max(max, Math.abs(a)); + } + return max; + } + + /** {@inheritDoc} */ + public double getDistance(RealVector v) + throws IllegalArgumentException { + try { + return getDistance((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double sum = 0; + for (int i = 0; i < data.length; ++i) { + final double delta = data[i] - v.getEntry(i); + sum += delta * delta; + } + return Math.sqrt(sum); + } + } + + /** + * Distance between two vectors. + *

This method computes the distance consistent with the + * L2 norm, i.e. the square root of the sum of + * elements differences, or euclidian distance.

+ * @param v vector to which distance is requested + * @return distance between two vectors. + * @exception IllegalArgumentException if v is not the same size as this + * @see #getDistance(RealVector) + * @see #getL1Distance(RealVectorImpl) + * @see #getLInfDistance(RealVectorImpl) + * @see #getNorm() + */ + public double getDistance(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double sum = 0; + for (int i = 0; i < data.length; ++i) { + final double delta = data[i] - v.data[i]; + sum += delta * delta; + } + return Math.sqrt(sum); + } + + /** {@inheritDoc} */ + public double getL1Distance(RealVector v) + throws IllegalArgumentException { + try { + return getL1Distance((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double sum = 0; + for (int i = 0; i < data.length; ++i) { + final double delta = data[i] - v.getEntry(i); + sum += Math.abs(delta); + } + return sum; + } + } + + /** + * Distance between two vectors. + *

This method computes the distance consistent with + * L1 norm, i.e. the sum of the absolute values of + * elements differences.

+ * @param v vector to which distance is requested + * @return distance between two vectors. + * @exception IllegalArgumentException if v is not the same size as this + * @see #getDistance(RealVector) + * @see #getL1Distance(RealVectorImpl) + * @see #getLInfDistance(RealVectorImpl) + * @see #getNorm() + */ + public double getL1Distance(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double sum = 0; + for (int i = 0; i < data.length; ++i) { + final double delta = data[i] - v.data[i]; + sum += Math.abs(delta); + } + return sum; + } + + /** {@inheritDoc} */ + public double getLInfDistance(RealVector v) + throws IllegalArgumentException { + try { + return getLInfDistance((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double max = 0; + for (int i = 0; i < data.length; ++i) { + final double delta = data[i] - v.getEntry(i); + max = Math.max(max, Math.abs(delta)); + } + return max; + } + } + + /** + * Distance between two vectors. + *

This method computes the distance consistent with + * L&infty; norm, i.e. the max of the absolute values of + * elements differences.

+ * @param v vector to which distance is requested + * @return distance between two vectors. + * @exception IllegalArgumentException if v is not the same size as this + * @see #getDistance(RealVector) + * @see #getL1Distance(RealVectorImpl) + * @see #getLInfDistance(RealVectorImpl) + * @see #getNorm() + */ + public double getLInfDistance(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double max = 0; + for (int i = 0; i < data.length; ++i) { + final double delta = data[i] - v.data[i]; + max = Math.max(max, Math.abs(delta)); + } + return max; + } + + /** {@inheritDoc} */ + public RealVector unitVector() throws ArithmeticException { + final double norm = getNorm(); + if (norm == 0) { + throw new ArithmeticException("null norm"); + } + return mapDivide(getNorm()); + } + + /** {@inheritDoc} */ + public void unitize() throws ArithmeticException { + final double norm = getNorm(); + if (norm == 0) { + throw new ArithmeticException("null norm"); + } + for (int i = 0; i < data.length; i++) { + data[i] /= norm; + } + } + + /** {@inheritDoc} */ + public RealVector projection(RealVector v) { + return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); + } + + /** Find the orthogonal projection of this vector onto another vector. + * @param v vector onto which instance must be projected + * @return projection of the instance onto v + * @throws IllegalArgumentException if v is not the same size as this + */ + public RealVectorImpl projection(RealVectorImpl v) { + return (RealVectorImpl) v.mapMultiply(dotProduct(v) / v.dotProduct(v)); + } + + /** {@inheritDoc} */ + public RealMatrix outerProduct(RealVector v) + throws IllegalArgumentException { + try { + return outerProduct((RealVectorImpl) v); + } catch (ClassCastException cce) { + checkVectorDimensions(v); + double[][] out = new double[data.length][data.length]; + for (int i = 0; i < data.length; i++) { + for (int j = 0; j < data.length; j++) { + out[i][j] = data[i] * v.getEntry(j); + } + } + return new RealMatrixImpl(out); + } + } + + /** + * Compute the outer product. + * @param v vector with which outer product should be computed + * @return the square matrix outer product between instance and v + * @exception IllegalArgumentException if v is not the same size as this + */ + public RealMatrixImpl outerProduct(RealVectorImpl v) + throws IllegalArgumentException { + checkVectorDimensions(v); + double[][] out = new double[data.length][data.length]; + for (int i = 0; i < data.length; i++) { + for (int j = 0; j < data.length; j++) { + out[i][j] = data[i] * v.data[j]; + } + } + return new RealMatrixImpl(out); + } + + /** {@inheritDoc} */ + public double getEntry(int index) throws MatrixIndexException { + return data[index]; + } + + /** {@inheritDoc} */ + public int getDimension() { + return data.length; + } + + /** {@inheritDoc} */ + public RealVector append(RealVector v) { + try { + return append((RealVectorImpl) v); + } catch (ClassCastException cce) { + return new RealVectorImpl(this,new RealVectorImpl(v)); + } + } + + /** + * Construct a vector by appending a vector to this vector. + * @param v vector to append to this one. + * @return a new vector + */ + public RealVectorImpl append(RealVectorImpl v) { + return new RealVectorImpl(this, v); + } + + /** {@inheritDoc} */ + public RealVector append(double in) { + final double[] out = new double[data.length + 1]; + System.arraycopy(data, 0, out, 0, data.length); + out[data.length] = in; + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector append(double[] in) { + final double[] out = new double[data.length + in.length]; + System.arraycopy(data, 0, out, 0, data.length); + System.arraycopy(in, 0, out, data.length, in.length); + return new RealVectorImpl(out); + } + + /** {@inheritDoc} */ + public RealVector get(int index, int n) { + try { + RealVectorImpl out = new RealVectorImpl(n); + System.arraycopy(data, index, out.data, 0, n); + + return out; + } catch (IndexOutOfBoundsException e) { + throw new MatrixIndexException(e.getMessage()); + } + } + + /** {@inheritDoc} */ + public void set(int index, double value) { + try { + data[index] = value; + } catch (IndexOutOfBoundsException e) { + throw new MatrixIndexException(e.getMessage()); + } + } + + /** {@inheritDoc} */ + public void set(int index, RealVector v) { + try { + try { + set(index, (RealVectorImpl) v); + } catch (ClassCastException cce) { + for (int i = index; i < index + v.getDimension(); ++i) { + data[i] = v.getEntry(i-index); + } + } + } catch (IndexOutOfBoundsException e) { + throw new MatrixIndexException(e.getMessage()); + } + } + + /** + * Set a set of consecutive elements. + * + * @param index index of first element to be set. + * @param v vector containing the values to set. + * @exception MatrixIndexException if the index is + * inconsistent with vector size + */ + public void set(int index, RealVectorImpl v) + throws MatrixIndexException { + try { + System.arraycopy(v.data, 0, data, index, v.data.length); + } catch (IndexOutOfBoundsException e) { + throw new MatrixIndexException(e.getMessage()); + } + } + + /** {@inheritDoc} */ + public void set(double value) { + Arrays.fill(data, value); + } + + /** {@inheritDoc} */ + public double[] toArray(){ + return data.clone(); + } + + /** {@inheritDoc} */ + public String toString(){ + return DEFAULT_FORMAT.format(this); + } + + /** + * Check if instance and specified vectors have the same dimension. + * @param v vector to compare instance with + * @exception IllegalArgumentException if the vectors do not + * have the same dimension + */ + public void checkVectorDimensions(RealVector v) + throws IllegalArgumentException { + checkVectorDimensions(v.getDimension()); + } + + /** + * Check if instance dimension is equal to some expected value. + * + * @param n expected dimension. + * @exception IllegalArgumentException if the dimension is + * inconsistent with vector size + */ + public void checkVectorDimensions(int n) + throws IllegalArgumentException { + if (data.length != n) { + throw new IllegalArgumentException("vector dimension is " + data.length + + ", not " + n + " as expected"); + } + } + + /** + * Returns true if any coordinate of this vector is NaN; false otherwise + * @return true if any coordinate of this vector is NaN; false otherwise + */ + public boolean isNaN() { + for (double v : data) { + if (Double.isNaN(v)) { + return true; + } + } + return false; + } + + /** + * Returns true if any coordinate of this vector is infinite and none are NaN; + * false otherwise + * @return true if any coordinate of this vector is infinite and none are NaN; + * false otherwise + */ + public boolean isInfinite() { + + if (isNaN()) { + return false; + } + + for (double v : data) { + if (Double.isInfinite(v)) { + return true; + } + } + + return false; + + } + + /** + * Test for the equality of two real vectors. + *

+ * If all coordinates of two real vectors are exactly the same, and none are + * Double.NaN, the two real vectors are considered to be equal. + *

+ *

+ * NaN coordinates are considered to affect globally the vector + * and be equals to each other - i.e, if either (or all) coordinates of the + * real vector are equal to Double.NaN, the real vector is equal to + * a vector with all Double.NaN coordinates. + *

+ * + * @param other Object to test for equality to this + * @return true if two 3D vector objects are equal, false if + * object is null, not an instance of Vector3D, or + * not equal to this Vector3D instance + * + */ + public boolean equals(Object other) { + + if (this == other) { + return true; + } + + if (other == null) { + return false; + } + + try { + + RealVector rhs = (RealVector) other; + if (data.length != rhs.getDimension()) { + return false; + } + + if (rhs.isNaN()) { + return this.isNaN(); + } + + for (int i = 0; i < data.length; ++i) { + if (Double.doubleToRawLongBits(data[i]) != + Double.doubleToRawLongBits(rhs.getEntry(i))) { + return false; + } + } + return true; + + } catch (ClassCastException ex) { + // ignore exception + return false; + } + + } + + /** + * Get a hashCode for the real vector. + *

All NaN values have the same hash code.

+ * @return a hash code value for this object + */ + public int hashCode() { + if (isNaN()) { + return 9; + } + return MathUtils.hash(data); + } + +} diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index b4be0990a..752fd48bf 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -39,6 +39,12 @@ The type attribute can be add,update,fix,remove. + + Support for one dimensional vectors has been added to the linear algebra + package with a RealVector interface, a RealVectorImpl default implementation + using a single double array to store elements and a RealVectorFormat for + input/output. + Changed OLS regression implementation added in MATH-203 to use QR decomposition to solve the normal equations. diff --git a/src/test/org/apache/commons/math/linear/FrenchRealVectorFormatTest.java b/src/test/org/apache/commons/math/linear/FrenchRealVectorFormatTest.java new file mode 100644 index 000000000..b45962e62 --- /dev/null +++ b/src/test/org/apache/commons/math/linear/FrenchRealVectorFormatTest.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math.linear; + +import java.util.Locale; + + +public class FrenchRealVectorFormatTest extends RealVectorFormatAbstractTest { + + protected char getDecimalCharacter() { + return ','; + } + + protected Locale getLocale() { + return Locale.FRENCH; + } +} diff --git a/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java b/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java index 383a9598e..3c174e70c 100644 --- a/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java +++ b/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java @@ -253,8 +253,10 @@ public final class RealMatrixImplTest extends TestCase { RealMatrixImpl m = new RealMatrixImpl(testData); RealMatrix mInv = new RealMatrixImpl(testDataInv); // being a bit slothful here -- actually testing that X = A^-1 * B - assertClose("inverse-operate",mInv.operate(testVector), - m.solve(testVector),normTolerance); + assertClose("inverse-operate", mInv.operate(testVector), + m.solve(testVector), normTolerance); + assertClose("inverse-operate", mInv.operate(testVector), + m.solve(new RealVectorImpl(testVector)).getData(), normTolerance); try { m.solve(testVector2); fail("expecting IllegalArgumentException"); @@ -332,8 +334,10 @@ public final class RealMatrixImplTest extends TestCase { /** test operate */ public void testOperate() { RealMatrix m = new RealMatrixImpl(id); - double[] x = m.operate(testVector); - assertClose("identity operate",testVector,x,entryTolerance); + assertClose("identity operate", testVector, + m.operate(testVector), entryTolerance); + assertClose("identity operate", testVector, + m.operate(new RealVectorImpl(testVector)).getData(), entryTolerance); m = new RealMatrixImpl(bigSingular); try { m.operate(testVector); @@ -368,7 +372,10 @@ public final class RealMatrixImplTest extends TestCase { /** test preMultiply by vector */ public void testPremultiplyVector() { RealMatrix m = new RealMatrixImpl(testData); - assertClose("premultiply",m.preMultiply(testVector),preMultTest,normTolerance); + assertClose("premultiply", m.preMultiply(testVector), + preMultTest, normTolerance); + assertClose("premultiply", m.preMultiply(new RealVectorImpl(testVector).getData()), + preMultTest, normTolerance); m = new RealMatrixImpl(bigSingular); try { m.preMultiply(testVector); @@ -607,6 +614,54 @@ public final class RealMatrixImplTest extends TestCase { // expected } } + + public void testGetRowVector() { + RealMatrix m = new RealMatrixImpl(subTestData); + RealVector mRow0 = new RealVectorImpl(subRow0[0]); + RealVector mRow3 = new RealVectorImpl(subRow3[0]); + assertEquals("Row0", mRow0, m.getRowVector(0)); + assertEquals("Row3", mRow3, m.getRowVector(3)); + try { + m.getRowVector(-1); + fail("Expecting MatrixIndexException"); + } catch (MatrixIndexException ex) { + // expected + } + try { + m.getRowVector(4); + fail("Expecting MatrixIndexException"); + } catch (MatrixIndexException ex) { + // expected + } + } + + public void testGetColumnVector() { + RealMatrix m = new RealMatrixImpl(subTestData); + RealVector mColumn1 = columnToVector(subColumn1); + RealVector mColumn3 = columnToVector(subColumn3); + assertEquals("Column1", mColumn1, m.getColumnVector(1)); + assertEquals("Column3", mColumn3, m.getColumnVector(3)); + try { + m.getColumnVector(-1); + fail("Expecting MatrixIndexException"); + } catch (MatrixIndexException ex) { + // expected + } + try { + m.getColumnVector(4); + fail("Expecting MatrixIndexException"); + } catch (MatrixIndexException ex) { + // expected + } + } + + private RealVector columnToVector(double[][] column) { + double[] data = new double[column.length]; + for (int i = 0; i < data.length; ++i) { + data[i] = column[i][0]; + } + return new RealVectorImpl(data, false); + } public void testEqualsAndHashCode() { RealMatrixImpl m = new RealMatrixImpl(testData); diff --git a/src/test/org/apache/commons/math/linear/RealVectorFormatAbstractTest.java b/src/test/org/apache/commons/math/linear/RealVectorFormatAbstractTest.java new file mode 100644 index 000000000..920fddf72 --- /dev/null +++ b/src/test/org/apache/commons/math/linear/RealVectorFormatAbstractTest.java @@ -0,0 +1,384 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math.linear; + +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.Locale; + +import junit.framework.TestCase; + +import org.apache.commons.math.util.CompositeFormat; + +public abstract class RealVectorFormatAbstractTest extends TestCase { + + RealVectorFormat realVectorFormat = null; + RealVectorFormat realVectorFormatSquare = null; + + protected abstract Locale getLocale(); + + protected abstract char getDecimalCharacter(); + + protected void setUp() throws Exception { + realVectorFormat = RealVectorFormat.getInstance(getLocale()); + final NumberFormat nf = NumberFormat.getInstance(getLocale()); + nf.setMaximumFractionDigits(2); + realVectorFormatSquare = new RealVectorFormat("[", "]", " : ", nf); + } + + public void testSimpleNoDecimals() { + RealVectorImpl c = new RealVectorImpl(new double[] {1, 1, 1}); + String expected = "{1; 1; 1}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testSimpleWithDecimals() { + RealVectorImpl c = new RealVectorImpl(new double[] {1.23, 1.43, 1.63}); + String expected = + "{1" + getDecimalCharacter() + + "23; 1" + getDecimalCharacter() + + "43; 1" + getDecimalCharacter() + + "63}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testSimpleWithDecimalsTrunc() { + RealVectorImpl c = new RealVectorImpl(new double[] {1.2323, 1.4343, 1.6333}); + String expected = + "{1" + getDecimalCharacter() + + "23; 1" + getDecimalCharacter() + + "43; 1" + getDecimalCharacter() + + "63}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testNegativeX() { + RealVectorImpl c = new RealVectorImpl(new double[] {-1.2323, 1.4343, 1.6333}); + String expected = + "{-1" + getDecimalCharacter() + + "23; 1" + getDecimalCharacter() + + "43; 1" + getDecimalCharacter() + + "63}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testNegativeY() { + RealVectorImpl c = new RealVectorImpl(new double[] {1.2323, -1.4343, 1.6333}); + String expected = + "{1" + getDecimalCharacter() + + "23; -1" + getDecimalCharacter() + + "43; 1" + getDecimalCharacter() + + "63}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testNegativeZ() { + RealVectorImpl c = new RealVectorImpl(new double[] {1.2323, 1.4343, -1.6333}); + String expected = + "{1" + getDecimalCharacter() + + "23; 1" + getDecimalCharacter() + + "43; -1" + getDecimalCharacter() + + "63}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testNonDefaultSetting() { + RealVectorImpl c = new RealVectorImpl(new double[] {1, 1, 1}); + String expected = "[1 : 1 : 1]"; + String actual = realVectorFormatSquare.format(c); + assertEquals(expected, actual); + } + + public void testStaticFormatRealVectorImpl() { + Locale defaultLocal = Locale.getDefault(); + Locale.setDefault(getLocale()); + + RealVectorImpl c = new RealVectorImpl(new double[] {232.222, -342.33, 432.444}); + String expected = + "{232" + getDecimalCharacter() + + "22; -342" + getDecimalCharacter() + + "33; 432" + getDecimalCharacter() + + "44}"; + String actual = RealVectorFormat.formatRealVector(c); + assertEquals(expected, actual); + + Locale.setDefault(defaultLocal); + } + + public void testNan() { + RealVectorImpl c = new RealVectorImpl(new double[] {Double.NaN, Double.NaN, Double.NaN}); + String expected = "{(NaN); (NaN); (NaN)}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testPositiveInfinity() { + RealVectorImpl c = new RealVectorImpl(new double[] { + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY + }); + String expected = "{(Infinity); (Infinity); (Infinity)}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void tesNegativeInfinity() { + RealVectorImpl c = new RealVectorImpl(new double[] { + Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY + }); + String expected = "{(-Infinity); (-Infinity); (-Infinity)}"; + String actual = realVectorFormat.format(c); + assertEquals(expected, actual); + } + + public void testParseSimpleNoDecimals() { + String source = "{1; 1; 1}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {1, 1, 1}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseIgnoredWhitespace() { + RealVectorImpl expected = new RealVectorImpl(new double[] {1, 1, 1}); + ParsePosition pos1 = new ParsePosition(0); + String source1 = "{1;1;1}"; + assertEquals(expected, realVectorFormat.parseObject(source1, pos1)); + assertEquals(source1.length(), pos1.getIndex()); + ParsePosition pos2 = new ParsePosition(0); + String source2 = " { 1 ; 1 ; 1 } "; + assertEquals(expected, realVectorFormat.parseObject(source2, pos2)); + assertEquals(source2.length() - 1, pos2.getIndex()); + } + + public void testParseSimpleWithDecimals() { + String source = + "{1" + getDecimalCharacter() + + "23; 1" + getDecimalCharacter() + + "43; 1" + getDecimalCharacter() + + "63}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {1.23, 1.43, 1.63}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseSimpleWithDecimalsTrunc() { + String source = + "{1" + getDecimalCharacter() + + "2323; 1" + getDecimalCharacter() + + "4343; 1" + getDecimalCharacter() + + "6333}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {1.2323, 1.4343, 1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNegativeX() { + String source = + "{-1" + getDecimalCharacter() + + "2323; 1" + getDecimalCharacter() + + "4343; 1" + getDecimalCharacter() + + "6333}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {-1.2323, 1.4343, 1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNegativeY() { + String source = + "{1" + getDecimalCharacter() + + "2323; -1" + getDecimalCharacter() + + "4343; 1" + getDecimalCharacter() + + "6333}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {1.2323, -1.4343, 1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNegativeZ() { + String source = + "{1" + getDecimalCharacter() + + "2323; 1" + getDecimalCharacter() + + "4343; -1" + getDecimalCharacter() + + "6333}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {1.2323, 1.4343, -1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNegativeAll() { + String source = + "{-1" + getDecimalCharacter() + + "2323; -1" + getDecimalCharacter() + + "4343; -1" + getDecimalCharacter() + + "6333}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {-1.2323, -1.4343, -1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseZeroX() { + String source = + "{0" + getDecimalCharacter() + + "0; -1" + getDecimalCharacter() + + "4343; 1" + getDecimalCharacter() + + "6333}"; + RealVectorImpl expected = new RealVectorImpl(new double[] {0.0, -1.4343, 1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNonDefaultSetting() { + String source = + "[1" + getDecimalCharacter() + + "2323 : 1" + getDecimalCharacter() + + "4343 : 1" + getDecimalCharacter() + + "6333]"; + RealVectorImpl expected = new RealVectorImpl(new double[] {1.2323, 1.4343, 1.6333}); + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormatSquare.parseObject(source); + assertEquals(expected, actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNan() { + String source = "{(NaN); (NaN); (NaN)}"; + try { + RealVectorImpl actual = (RealVectorImpl) realVectorFormat.parseObject(source); + assertEquals(new RealVectorImpl(new double[] {Double.NaN, Double.NaN, Double.NaN}), actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParsePositiveInfinity() { + String source = "{(Infinity); (Infinity); (Infinity)}"; + try { + RealVectorImpl actual = (RealVectorImpl)realVectorFormat.parseObject(source); + assertEquals(new RealVectorImpl(new double[] { + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY + }), actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNegativeInfinity() { + String source = "{(-Infinity); (-Infinity); (-Infinity)}"; + try { + RealVectorImpl actual = (RealVectorImpl)realVectorFormat.parseObject(source); + assertEquals(new RealVectorImpl(new double[] { + Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY + }), actual); + } catch (ParseException ex) { + fail(ex.getMessage()); + } + } + + public void testParseNoComponents() { + try { + realVectorFormat.parseObject("{ }"); + } catch (ParseException pe) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + } + + public void testParseManyComponents() throws ParseException { + RealVectorImpl parsed = + (RealVectorImpl) realVectorFormat.parseObject("{0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0}"); + assertEquals(24, parsed.getDimension()); + } + + public void testConstructorSingleFormat() { + NumberFormat nf = NumberFormat.getInstance(); + RealVectorFormat cf = new RealVectorFormat(nf); + assertNotNull(cf); + assertEquals(nf, cf.getFormat()); + } + + public void testFormatObject() { + try { + CompositeFormat cf = new RealVectorFormat(); + Object object = new Object(); + cf.format(object); + fail(); + } catch (IllegalArgumentException ex) { + // success + } + } + + public void testForgottenPrefix() { + ParsePosition pos = new ParsePosition(0); + assertNull(new RealVectorFormat().parse("1; 1; 1}", pos)); + assertEquals(0, pos.getErrorIndex()); + } + + public void testForgottenSeparator() { + ParsePosition pos = new ParsePosition(0); + assertNull(new RealVectorFormat().parse("{1; 1 1}", pos)); + assertEquals(6, pos.getErrorIndex()); + } + + public void testForgottenSuffix() { + ParsePosition pos = new ParsePosition(0); + assertNull(new RealVectorFormat().parse("{1; 1; 1 ", pos)); + assertEquals(8, pos.getErrorIndex()); + } + +} diff --git a/src/test/org/apache/commons/math/linear/RealVectorFormatTest.java b/src/test/org/apache/commons/math/linear/RealVectorFormatTest.java new file mode 100644 index 000000000..d73388103 --- /dev/null +++ b/src/test/org/apache/commons/math/linear/RealVectorFormatTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math.linear; + +import java.util.Locale; + + +public class RealVectorFormatTest extends RealVectorFormatAbstractTest { + protected char getDecimalCharacter() { + return '.'; + } + + protected Locale getLocale() { + return Locale.US; + } +} diff --git a/src/test/org/apache/commons/math/linear/RealVectorImplTest.java b/src/test/org/apache/commons/math/linear/RealVectorImplTest.java new file mode 100644 index 000000000..69db6dfbf --- /dev/null +++ b/src/test/org/apache/commons/math/linear/RealVectorImplTest.java @@ -0,0 +1,1137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.linear; + +import java.io.Serializable; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Test cases for the {@link RealVectorImpl} class. + * + * @version $Revision$ $Date$ + */ +public class RealVectorImplTest extends TestCase { + + // + protected double[][] ma1 = {{1d, 2d, 3d}, {4d, 5d, 6d}, {7d, 8d, 9d}}; + protected double[] vec1 = {1d, 2d, 3d}; + protected double[] vec2 = {4d, 5d, 6d}; + protected double[] vec3 = {7d, 8d, 9d}; + protected double[] vec4 = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d}; + protected double[] vec_null = {0d, 0d, 0d}; + protected Double[] dvec1 = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d}; + protected double[][] mat1 = {{1d, 2d, 3d}, {4d, 5d, 6d},{ 7d, 8d, 9d}}; + + // tolerances + protected double entryTolerance = 10E-16; + protected double normTolerance = 10E-14; + + // Testclass to test the RealVector interface + // only with enough content to support the test + public class RealVectorTestImpl implements RealVector, Serializable { + + /** Serializable version identifier. */ + private static final long serialVersionUID = 8731816072271374422L; + + /** Entries of the vector. */ + protected double data[]; + + public RealVectorTestImpl(double[] d) { + data = d.clone(); + } + + private UnsupportedOperationException unsupported() { + return new UnsupportedOperationException("Not supported, unneeded for test purposes"); + } + + public RealVector copy() { + throw unsupported(); + } + + public RealVector add(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public RealVector subtract(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public RealVector mapAdd(double d) { + throw unsupported(); + } + + public RealVector mapAddToSelf(double d) { + throw unsupported(); + } + + public RealVector mapSubtract(double d) { + throw unsupported(); + } + + public RealVector mapSubtractToSelf(double d) { + throw unsupported(); + } + + public RealVector mapMultiply(double d) { + double[] out = new double[data.length]; + for (int i = 0; i < data.length; i++) { + out[i] = data[i] * d; + } + return new RealVectorImpl(out); + } + + public RealVector mapMultiplyToSelf(double d) { + throw unsupported(); + } + + public RealVector mapDivide(double d) { + throw unsupported(); + } + + public RealVector mapDivideToSelf(double d) { + throw unsupported(); + } + + public RealVector mapPow(double d) { + throw unsupported(); + } + + public RealVector mapPowToSelf(double d) { + throw unsupported(); + } + + public RealVector mapExp() { + throw unsupported(); + } + + public RealVector mapExpToSelf() { + throw unsupported(); + } + + public RealVector mapExpm1() { + throw unsupported(); + } + + public RealVector mapExpm1ToSelf() { + throw unsupported(); + } + + public RealVector mapLog() { + throw unsupported(); + } + + public RealVector mapLogToSelf() { + throw unsupported(); + } + + public RealVector mapLog10() { + throw unsupported(); + } + + public RealVector mapLog10ToSelf() { + throw unsupported(); + } + + public RealVector mapLog1p() { + throw unsupported(); + } + + public RealVector mapLog1pToSelf() { + throw unsupported(); + } + + public RealVector mapCosh() { + throw unsupported(); + } + + public RealVector mapCoshToSelf() { + throw unsupported(); + } + + public RealVector mapSinh() { + throw unsupported(); + } + + public RealVector mapSinhToSelf() { + throw unsupported(); + } + + public RealVector mapTanh() { + throw unsupported(); + } + + public RealVector mapTanhToSelf() { + throw unsupported(); + } + + public RealVector mapCos() { + throw unsupported(); + } + + public RealVector mapCosToSelf() { + throw unsupported(); + } + + public RealVector mapSin() { + throw unsupported(); + } + + public RealVector mapSinToSelf() { + throw unsupported(); + } + + public RealVector mapTan() { + throw unsupported(); + } + + public RealVector mapTanToSelf() { + throw unsupported(); + } + + public RealVector mapAcos() { + throw unsupported(); + } + + public RealVector mapAcosToSelf() { + throw unsupported(); + } + + public RealVector mapAsin() { + throw unsupported(); + } + + public RealVector mapAsinToSelf() { + throw unsupported(); + } + + public RealVector mapAtan() { + throw unsupported(); + } + + public RealVector mapAtanToSelf() { + throw unsupported(); + } + + public RealVector mapInv() { + throw unsupported(); + } + + public RealVector mapInvToSelf() { + throw unsupported(); + } + + public RealVector mapAbs() { + throw unsupported(); + } + + public RealVector mapAbsToSelf() { + throw unsupported(); + } + + public RealVector mapSqrt() { + throw unsupported(); + } + + public RealVector mapSqrtToSelf() { + throw unsupported(); + } + + public RealVector mapCbrt() { + throw unsupported(); + } + + public RealVector mapCbrtToSelf() { + throw unsupported(); + } + + public RealVector mapCeil() { + throw unsupported(); + } + + public RealVector mapCeilToSelf() { + throw unsupported(); + } + + public RealVector mapFloor() { + throw unsupported(); + } + + public RealVector mapFloorToSelf() { + throw unsupported(); + } + + public RealVector mapRint() { + throw unsupported(); + } + + public RealVector mapRintToSelf() { + throw unsupported(); + } + + public RealVector mapSignum() { + throw unsupported(); + } + + public RealVector mapSignumToSelf() { + throw unsupported(); + } + + public RealVector mapUlp() { + throw unsupported(); + } + + public RealVector mapUlpToSelf() { + throw unsupported(); + } + + public RealVector ebeMultiply(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public RealVector ebeDivide(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public double[] getData() { + throw unsupported(); + } + + public double dotProduct(RealVector v) throws IllegalArgumentException { + + // checkVectorDimensions(v); + double dot = 0; + for (int i = 0; i < data.length; i++) { + dot += data[i] * v.getEntry(i); + } + return dot; + } + + public double getNorm() { + throw unsupported(); + } + + public double getL1Norm() { + throw unsupported(); + } + + public double getLInfNorm() { + throw unsupported(); + } + + public double getDistance(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public double getL1Distance(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public double getLInfDistance(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public RealVector unitVector() { + throw unsupported(); + } + + public void unitize() { + throw unsupported(); + } + + public RealVector projection(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { + throw unsupported(); + } + + public double getEntry(int index) throws MatrixIndexException { + return data[index]; + } + + public int getDimension() { + return data.length; + } + + public RealVector append(RealVector v) { + throw unsupported(); + } + + public RealVector append(double d) { + throw unsupported(); + } + + public RealVector append(double[] a) { + throw unsupported(); + } + + public RealVector get(int index, int n) throws MatrixIndexException { + throw unsupported(); + } + + public void set(int index, double value) throws MatrixIndexException { + throw unsupported(); + } + + public void set(int index, RealVector v) throws MatrixIndexException { + throw unsupported(); + } + + public void set(double value) { + throw unsupported(); + } + + public double[] toArray() { + throw unsupported(); + } + + public boolean isNaN() { + throw unsupported(); + } + + public boolean isInfinite() { + throw unsupported(); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite(RealVectorImplTest.class); + suite.setName("RealVectorImpl Tests"); + return suite; + } + + public void testConstructors() { + + RealVectorImpl v0 = new RealVectorImpl(); + assertEquals("testData len", 0, v0.getDimension()); + + RealVectorImpl v1 = new RealVectorImpl(7); + assertEquals("testData len", 7, v1.getDimension()); + assertEquals("testData is 0.0 ", 0.0, v1.getEntry(6)); + + RealVectorImpl v2 = new RealVectorImpl(5, 1.23); + assertEquals("testData len", 5, v2.getDimension()); + assertEquals("testData is 1.23 ", 1.23, v2.getEntry(4)); + + RealVectorImpl v3 = new RealVectorImpl(vec1); + assertEquals("testData len", 3, v3.getDimension()); + assertEquals("testData is 2.0 ", 2.0, v3.getEntry(1)); + + RealVectorImpl v4 = new RealVectorImpl(vec4, 3, 2); + assertEquals("testData len", 2, v4.getDimension()); + assertEquals("testData is 4.0 ", 4.0, v4.getEntry(0)); + try { + new RealVectorImpl(vec4, 8, 3); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVector v5_i = new RealVectorImpl(dvec1); + assertEquals("testData len", 9, v5_i.getDimension()); + assertEquals("testData is 9.0 ", 9.0, v5_i.getEntry(8)); + + RealVectorImpl v5 = new RealVectorImpl(dvec1); + assertEquals("testData len", 9, v5.getDimension()); + assertEquals("testData is 9.0 ", 9.0, v5.getEntry(8)); + + RealVectorImpl v6 = new RealVectorImpl(dvec1, 3, 2); + assertEquals("testData len", 2, v6.getDimension()); + assertEquals("testData is 4.0 ", 4.0, v6.getEntry(0)); + try { + new RealVectorImpl(dvec1, 8, 3); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v7 = new RealVectorImpl(v1); + assertEquals("testData len", 7, v7.getDimension()); + assertEquals("testData is 0.0 ", 0.0, v7.getEntry(6)); + + RealVectorTestImpl v7_i = new RealVectorTestImpl(vec1); + + RealVectorImpl v7_2 = new RealVectorImpl(v7_i); + assertEquals("testData len", 3, v7_2.getDimension()); + assertEquals("testData is 0.0 ", 2.0d, v7_2.getEntry(1)); + + RealVectorImpl v8 = new RealVectorImpl(v1, true); + assertEquals("testData len", 7, v8.getDimension()); + assertEquals("testData is 0.0 ", 0.0, v8.getEntry(6)); + assertNotSame("testData not same object ", v1.data, v8.data); + + RealVectorImpl v8_2 = new RealVectorImpl(v1, false); + assertEquals("testData len", 7, v8_2.getDimension()); + assertEquals("testData is 0.0 ", 0.0, v8_2.getEntry(6)); + assertEquals("testData same object ", v1.data, v8_2.data); + + RealVectorImpl v9 = new RealVectorImpl(v1, v3); + assertEquals("testData len", 10, v9.getDimension()); + assertEquals("testData is 1.0 ", 1.0, v9.getEntry(7)); + + } + + public void testDataInOut() { + + RealVectorImpl v1 = new RealVectorImpl(vec1); + RealVectorImpl v2 = new RealVectorImpl(vec2); + RealVectorImpl v4 = new RealVectorImpl(vec4); + RealVectorTestImpl v2_t = new RealVectorTestImpl(vec2); + + RealVector v_append_1 = v1.append(v2); + assertEquals("testData len", 6, v_append_1.getDimension()); + assertEquals("testData is 4.0 ", 4.0, v_append_1.getEntry(3)); + + RealVector v_append_2 = v1.append(2.0); + assertEquals("testData len", 4, v_append_2.getDimension()); + assertEquals("testData is 2.0 ", 2.0, v_append_2.getEntry(3)); + + RealVector v_append_3 = v1.append(vec2); + assertEquals("testData len", 6, v_append_3.getDimension()); + assertEquals("testData is ", 4.0, v_append_3.getEntry(3)); + + RealVector v_append_4 = v1.append(v2_t); + assertEquals("testData len", 6, v_append_4.getDimension()); + assertEquals("testData is 4.0 ", 4.0, v_append_4.getEntry(3)); + + RealVector v_copy = v1.copy(); + assertEquals("testData len", 3, v_copy.getDimension()); + assertNotSame("testData not same object ", v1.data, v_copy.getData()); + + double[] a_double = v1.toArray(); + assertEquals("testData len", 3, a_double.length); + assertNotSame("testData not same object ", v1.data, a_double); + + +// RealVectorImpl vout4 = (RealVectorImpl) v1.clone(); +// assertEquals("testData len", 3, vout4.getDimension()); +// assertEquals("testData not same object ", v1.data, vout4.data); + + + RealVector vout5 = v4.get(3, 3); + assertEquals("testData len", 3, vout5.getDimension()); + assertEquals("testData is 4.0 ", 5.0, vout5.getEntry(1)); + try { + v4.get(3, 7); + fail("MatrixIndexException expected"); + } catch (MatrixIndexException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v_set1 = (RealVectorImpl) v1.copy(); + v_set1.set(1, 11.0); + assertEquals("testData is 11.0 ", 11.0, v_set1.getEntry(1)); + try { + v_set1.set(3, 11.0); + fail("MatrixIndexException expected"); + } catch (MatrixIndexException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v_set2 = (RealVectorImpl) v4.copy(); + v_set2.set(3, v1); + assertEquals("testData is 1.0 ", 1.0, v_set2.getEntry(3)); + assertEquals("testData is 7.0 ", 7.0, v_set2.getEntry(6)); + try { + v_set2.set(7, v1); + fail("MatrixIndexException expected"); + } catch (MatrixIndexException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v_set3 = (RealVectorImpl) v1.copy(); + v_set3.set(13.0); + assertEquals("testData is 13.0 ", 13.0, v_set3.getEntry(2)); + + try { + v_set3.getEntry(23); + fail("ArrayIndexOutOfBoundsException expected"); + } catch (ArrayIndexOutOfBoundsException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v_set4 = (RealVectorImpl) v4.copy(); + v_set4.set(3, v2_t); + assertEquals("testData is 1.0 ", 4.0, v_set4.getEntry(3)); + assertEquals("testData is 7.0 ", 7.0, v_set4.getEntry(6)); + try { + v_set4.set(7, v2_t); + fail("MatrixIndexException expected"); + } catch (MatrixIndexException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + + RealVectorImpl vout10 = (RealVectorImpl) v1.copy(); + RealVectorImpl vout10_2 = (RealVectorImpl) v1.copy(); + assertEquals(vout10, vout10_2); + vout10_2.set(0, 1.1); + assertNotSame(vout10, vout10_2); + + } + + public void testMapFunctions() { + RealVectorImpl v1 = new RealVectorImpl(vec1); + + //octave = v1 .+ 2.0 + RealVector v_mapAdd = v1.mapAdd(2.0d); + double[] result_mapAdd = {3d, 4d, 5d}; + assertClose("compare vectors" ,result_mapAdd,v_mapAdd.getData(),normTolerance); + + //octave = v1 .+ 2.0 + RealVector v_mapAddToSelf = v1.copy(); + v_mapAddToSelf.mapAddToSelf(2.0d); + double[] result_mapAddToSelf = {3d, 4d, 5d}; + assertClose("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData(),normTolerance); + + //octave = v1 .- 2.0 + RealVector v_mapSubtract = v1.mapSubtract(2.0d); + double[] result_mapSubtract = {-1d, 0d, 1d}; + assertClose("compare vectors" ,result_mapSubtract,v_mapSubtract.getData(),normTolerance); + + //octave = v1 .- 2.0 + RealVector v_mapSubtractToSelf = v1.copy(); + v_mapSubtractToSelf.mapSubtractToSelf(2.0d); + double[] result_mapSubtractToSelf = {-1d, 0d, 1d}; + assertClose("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData(),normTolerance); + + //octave = v1 .* 2.0 + RealVector v_mapMultiply = v1.mapMultiply(2.0d); + double[] result_mapMultiply = {2d, 4d, 6d}; + assertClose("compare vectors" ,result_mapMultiply,v_mapMultiply.getData(),normTolerance); + + //octave = v1 .* 2.0 + RealVector v_mapMultiplyToSelf = v1.copy(); + v_mapMultiplyToSelf.mapMultiplyToSelf(2.0d); + double[] result_mapMultiplyToSelf = {2d, 4d, 6d}; + assertClose("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData(),normTolerance); + + //octave = v1 ./ 2.0 + RealVector v_mapDivide = v1.mapDivide(2.0d); + double[] result_mapDivide = {.5d, 1d, 1.5d}; + assertClose("compare vectors" ,result_mapDivide,v_mapDivide.getData(),normTolerance); + + //octave = v1 ./ 2.0 + RealVector v_mapDivideToSelf = v1.copy(); + v_mapDivideToSelf.mapDivideToSelf(2.0d); + double[] result_mapDivideToSelf = {.5d, 1d, 1.5d}; + assertClose("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData(),normTolerance); + + //octave = v1 .^ 2.0 + RealVector v_mapPow = v1.mapPow(2.0d); + double[] result_mapPow = {1d, 4d, 9d}; + assertClose("compare vectors" ,result_mapPow,v_mapPow.getData(),normTolerance); + + //octave = v1 .^ 2.0 + RealVector v_mapPowToSelf = v1.copy(); + v_mapPowToSelf.mapPowToSelf(2.0d); + double[] result_mapPowToSelf = {1d, 4d, 9d}; + assertClose("compare vectors" ,result_mapPowToSelf,v_mapPowToSelf.getData(),normTolerance); + + //octave = exp(v1) + RealVector v_mapExp = v1.mapExp(); + double[] result_mapExp = {2.718281828459045e+00d,7.389056098930650e+00d, 2.008553692318767e+01d}; + assertClose("compare vectors" ,result_mapExp,v_mapExp.getData(),normTolerance); + + //octave = exp(v1) + RealVector v_mapExpToSelf = v1.copy(); + v_mapExpToSelf.mapExpToSelf(); + double[] result_mapExpToSelf = {2.718281828459045e+00d,7.389056098930650e+00d, 2.008553692318767e+01d}; + assertClose("compare vectors" ,result_mapExpToSelf,v_mapExpToSelf.getData(),normTolerance); + + + //octave = ??? + RealVector v_mapExpm1 = v1.mapExpm1(); + double[] result_mapExpm1 = {1.718281828459045d,6.38905609893065d, 19.085536923187668d}; + assertClose("compare vectors" ,result_mapExpm1,v_mapExpm1.getData(),normTolerance); + + //octave = ??? + RealVector v_mapExpm1ToSelf = v1.copy(); + v_mapExpm1ToSelf.mapExpm1ToSelf(); + double[] result_mapExpm1ToSelf = {1.718281828459045d,6.38905609893065d, 19.085536923187668d}; + assertClose("compare vectors" ,result_mapExpm1ToSelf,v_mapExpm1ToSelf.getData(),normTolerance); + + //octave = log(v1) + RealVector v_mapLog = v1.mapLog(); + double[] result_mapLog = {0d,6.931471805599453e-01d, 1.098612288668110e+00d}; + assertClose("compare vectors" ,result_mapLog,v_mapLog.getData(),normTolerance); + + //octave = log(v1) + RealVector v_mapLogToSelf = v1.copy(); + v_mapLogToSelf.mapLogToSelf(); + double[] result_mapLogToSelf = {0d,6.931471805599453e-01d, 1.098612288668110e+00d}; + assertClose("compare vectors" ,result_mapLogToSelf,v_mapLogToSelf.getData(),normTolerance); + + //octave = log10(v1) + RealVector v_mapLog10 = v1.mapLog10(); + double[] result_mapLog10 = {0d,3.010299956639812e-01d, 4.771212547196624e-01d}; + assertClose("compare vectors" ,result_mapLog10,v_mapLog10.getData(),normTolerance); + + //octave = log(v1) + RealVector v_mapLog10ToSelf = v1.copy(); + v_mapLog10ToSelf.mapLog10ToSelf(); + double[] result_mapLog10ToSelf = {0d,3.010299956639812e-01d, 4.771212547196624e-01d}; + assertClose("compare vectors" ,result_mapLog10ToSelf,v_mapLog10ToSelf.getData(),normTolerance); + + //octave = ??? + RealVector v_mapLog1p = v1.mapLog1p(); + double[] result_mapLog1p = {0.6931471805599453d,1.0986122886681096d,1.3862943611198906d}; + assertClose("compare vectors" ,result_mapLog1p,v_mapLog1p.getData(),normTolerance); + + //octave = ??? + RealVector v_mapLog1pToSelf = v1.copy(); + v_mapLog1pToSelf.mapLog1pToSelf(); + double[] result_mapLog1pToSelf = {0.6931471805599453d,1.0986122886681096d,1.3862943611198906d}; + assertClose("compare vectors" ,result_mapLog1pToSelf,v_mapLog1pToSelf.getData(),normTolerance); + + //octave = cosh(v1) + RealVector v_mapCosh = v1.mapCosh(); + double[] result_mapCosh = {1.543080634815244e+00d,3.762195691083631e+00d, 1.006766199577777e+01d}; + assertClose("compare vectors" ,result_mapCosh,v_mapCosh.getData(),normTolerance); + + //octave = cosh(v1) + RealVector v_mapCoshToSelf = v1.copy(); + v_mapCoshToSelf.mapCoshToSelf(); + double[] result_mapCoshToSelf = {1.543080634815244e+00d,3.762195691083631e+00d, 1.006766199577777e+01d}; + assertClose("compare vectors" ,result_mapCoshToSelf,v_mapCoshToSelf.getData(),normTolerance); + + //octave = sinh(v1) + RealVector v_mapSinh = v1.mapSinh(); + double[] result_mapSinh = {1.175201193643801e+00d,3.626860407847019e+00d, 1.001787492740990e+01d}; + assertClose("compare vectors" ,result_mapSinh,v_mapSinh.getData(),normTolerance); + + //octave = sinh(v1) + RealVector v_mapSinhToSelf = v1.copy(); + v_mapSinhToSelf.mapSinhToSelf(); + double[] result_mapSinhToSelf = {1.175201193643801e+00d,3.626860407847019e+00d, 1.001787492740990e+01d}; + assertClose("compare vectors" ,result_mapSinhToSelf,v_mapSinhToSelf.getData(),normTolerance); + + //octave = tanh(v1) + RealVector v_mapTanh = v1.mapTanh(); + double[] result_mapTanh = {7.615941559557649e-01d,9.640275800758169e-01d,9.950547536867305e-01d}; + assertClose("compare vectors" ,result_mapTanh,v_mapTanh.getData(),normTolerance); + + //octave = tanh(v1) + RealVector v_mapTanhToSelf = v1.copy(); + v_mapTanhToSelf.mapTanhToSelf(); + double[] result_mapTanhToSelf = {7.615941559557649e-01d,9.640275800758169e-01d,9.950547536867305e-01d}; + assertClose("compare vectors" ,result_mapTanhToSelf,v_mapTanhToSelf.getData(),normTolerance); + + //octave = cos(v1) + RealVector v_mapCos = v1.mapCos(); + double[] result_mapCos = {5.403023058681398e-01d,-4.161468365471424e-01d, -9.899924966004454e-01d}; + assertClose("compare vectors" ,result_mapCos,v_mapCos.getData(),normTolerance); + + //octave = cos(v1) + RealVector v_mapCosToSelf = v1.copy(); + v_mapCosToSelf.mapCosToSelf(); + double[] result_mapCosToSelf = {5.403023058681398e-01d,-4.161468365471424e-01d, -9.899924966004454e-01d}; + assertClose("compare vectors" ,result_mapCosToSelf,v_mapCosToSelf.getData(),normTolerance); + + //octave = sin(v1) + RealVector v_mapSin = v1.mapSin(); + double[] result_mapSin = {8.414709848078965e-01d,9.092974268256817e-01d,1.411200080598672e-01d}; + assertClose("compare vectors" ,result_mapSin,v_mapSin.getData(),normTolerance); + + //octave = sin(v1) + RealVector v_mapSinToSelf = v1.copy(); + v_mapSinToSelf.mapSinToSelf(); + double[] result_mapSinToSelf = {8.414709848078965e-01d,9.092974268256817e-01d,1.411200080598672e-01d}; + assertClose("compare vectors" ,result_mapSinToSelf,v_mapSinToSelf.getData(),normTolerance); + + //octave = tan(v1) + RealVector v_mapTan = v1.mapTan(); + double[] result_mapTan = {1.557407724654902e+00d,-2.185039863261519e+00d,-1.425465430742778e-01d}; + assertClose("compare vectors" ,result_mapTan,v_mapTan.getData(),normTolerance); + + //octave = tan(v1) + RealVector v_mapTanToSelf = v1.copy(); + v_mapTanToSelf.mapTanToSelf(); + double[] result_mapTanToSelf = {1.557407724654902e+00d,-2.185039863261519e+00d,-1.425465430742778e-01d}; + assertClose("compare vectors" ,result_mapTanToSelf,v_mapTanToSelf.getData(),normTolerance); + + double[] vat_a = {0d, 0.5d, 1.0d}; + RealVectorImpl vat = new RealVectorImpl(vat_a); + + //octave = acos(vat) + RealVector v_mapAcos = vat.mapAcos(); + double[] result_mapAcos = {1.570796326794897e+00d,1.047197551196598e+00d, 0.0d}; + assertClose("compare vectors" ,result_mapAcos,v_mapAcos.getData(),normTolerance); + + //octave = acos(vat) + RealVector v_mapAcosToSelf = vat.copy(); + v_mapAcosToSelf.mapAcosToSelf(); + double[] result_mapAcosToSelf = {1.570796326794897e+00d,1.047197551196598e+00d, 0.0d}; + assertClose("compare vectors" ,result_mapAcosToSelf,v_mapAcosToSelf.getData(),normTolerance); + + //octave = asin(vat) + RealVector v_mapAsin = vat.mapAsin(); + double[] result_mapAsin = {0.0d,5.235987755982989e-01d,1.570796326794897e+00d}; + assertClose("compare vectors" ,result_mapAsin,v_mapAsin.getData(),normTolerance); + + //octave = asin(vat) + RealVector v_mapAsinToSelf = vat.copy(); + v_mapAsinToSelf.mapAsinToSelf(); + double[] result_mapAsinToSelf = {0.0d,5.235987755982989e-01d,1.570796326794897e+00d}; + assertClose("compare vectors" ,result_mapAsinToSelf,v_mapAsinToSelf.getData(),normTolerance); + + //octave = atan(vat) + RealVector v_mapAtan = vat.mapAtan(); + double[] result_mapAtan = {0.0d,4.636476090008061e-01d,7.853981633974483e-01d}; + assertClose("compare vectors" ,result_mapAtan,v_mapAtan.getData(),normTolerance); + + //octave = atan(vat) + RealVector v_mapAtanToSelf = vat.copy(); + v_mapAtanToSelf.mapAtanToSelf(); + double[] result_mapAtanToSelf = {0.0d,4.636476090008061e-01d,7.853981633974483e-01d}; + assertClose("compare vectors" ,result_mapAtanToSelf,v_mapAtanToSelf.getData(),normTolerance); + + //octave = v1 .^-1 + RealVector v_mapInv = v1.mapInv(); + double[] result_mapInv = {1d,0.5d,3.333333333333333e-01d}; + assertClose("compare vectors" ,result_mapInv,v_mapInv.getData(),normTolerance); + + //octave = v1 .^-1 + RealVector v_mapInvToSelf = v1.copy(); + v_mapInvToSelf.mapInvToSelf(); + double[] result_mapInvToSelf = {1d,0.5d,3.333333333333333e-01d}; + assertClose("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData(),normTolerance); + + double[] abs_a = {-1.0d, 0.0d, 1.0d}; + RealVectorImpl abs_v = new RealVectorImpl(abs_a); + + //octave = abs(abs_v) + RealVector v_mapAbs = abs_v.mapAbs(); + double[] result_mapAbs = {1d,0d,1d}; + assertClose("compare vectors" ,result_mapAbs,v_mapAbs.getData(),normTolerance); + + //octave = abs(abs_v) + RealVector v_mapAbsToSelf = abs_v.copy(); + v_mapAbsToSelf.mapAbsToSelf(); + double[] result_mapAbsToSelf = {1d,0d,1d}; + assertClose("compare vectors" ,result_mapAbsToSelf,v_mapAbsToSelf.getData(),normTolerance); + + //octave = sqrt(v1) + RealVector v_mapSqrt = v1.mapSqrt(); + double[] result_mapSqrt = {1d,1.414213562373095e+00d,1.732050807568877e+00d}; + assertClose("compare vectors" ,result_mapSqrt,v_mapSqrt.getData(),normTolerance); + + //octave = sqrt(v1) + RealVector v_mapSqrtToSelf = v1.copy(); + v_mapSqrtToSelf.mapSqrtToSelf(); + double[] result_mapSqrtToSelf = {1d,1.414213562373095e+00d,1.732050807568877e+00d}; + assertClose("compare vectors" ,result_mapSqrtToSelf,v_mapSqrtToSelf.getData(),normTolerance); + + double[] cbrt_a = {-2.0d, 0.0d, 2.0d}; + RealVectorImpl cbrt_v = new RealVectorImpl(cbrt_a); + + //octave = ??? + RealVector v_mapCbrt = cbrt_v.mapCbrt(); + double[] result_mapCbrt = {-1.2599210498948732d,0d,1.2599210498948732d}; + assertClose("compare vectors" ,result_mapCbrt,v_mapCbrt.getData(),normTolerance); + + //octave = ??? + RealVector v_mapCbrtToSelf = cbrt_v.copy(); + v_mapCbrtToSelf.mapCbrtToSelf(); + double[] result_mapCbrtToSelf = {-1.2599210498948732d,0d,1.2599210498948732d}; + assertClose("compare vectors" ,result_mapCbrtToSelf,v_mapCbrtToSelf.getData(),normTolerance); + + double[] ceil_a = {-1.1d, 0.9d, 1.1d}; + RealVectorImpl ceil_v = new RealVectorImpl(ceil_a); + + //octave = ceil(ceil_v) + RealVector v_mapCeil = ceil_v.mapCeil(); + double[] result_mapCeil = {-1d,1d,2d}; + assertClose("compare vectors" ,result_mapCeil,v_mapCeil.getData(),normTolerance); + + //octave = ceil(ceil_v) + RealVector v_mapCeilToSelf = ceil_v.copy(); + v_mapCeilToSelf.mapCeilToSelf(); + double[] result_mapCeilToSelf = {-1d,1d,2d}; + assertClose("compare vectors" ,result_mapCeilToSelf,v_mapCeilToSelf.getData(),normTolerance); + + //octave = floor(ceil_v) + RealVector v_mapFloor = ceil_v.mapFloor(); + double[] result_mapFloor = {-2d,0d,1d}; + assertClose("compare vectors" ,result_mapFloor,v_mapFloor.getData(),normTolerance); + + //octave = floor(ceil_v) + RealVector v_mapFloorToSelf = ceil_v.copy(); + v_mapFloorToSelf.mapFloorToSelf(); + double[] result_mapFloorToSelf = {-2d,0d,1d}; + assertClose("compare vectors" ,result_mapFloorToSelf,v_mapFloorToSelf.getData(),normTolerance); + + //octave = ??? + RealVector v_mapRint = ceil_v.mapRint(); + double[] result_mapRint = {-1d,1d,1d}; + assertClose("compare vectors" ,result_mapRint,v_mapRint.getData(),normTolerance); + + //octave = ??? + RealVector v_mapRintToSelf = ceil_v.copy(); + v_mapRintToSelf.mapRintToSelf(); + double[] result_mapRintToSelf = {-1d,1d,1d}; + assertClose("compare vectors" ,result_mapRintToSelf,v_mapRintToSelf.getData(),normTolerance); + + //octave = ??? + RealVector v_mapSignum = ceil_v.mapSignum(); + double[] result_mapSignum = {-1d,1d,1d}; + assertClose("compare vectors" ,result_mapSignum,v_mapSignum.getData(),normTolerance); + + //octave = ??? + RealVector v_mapSignumToSelf = ceil_v.copy(); + v_mapSignumToSelf.mapSignumToSelf(); + double[] result_mapSignumToSelf = {-1d,1d,1d}; + assertClose("compare vectors" ,result_mapSignumToSelf,v_mapSignumToSelf.getData(),normTolerance); + + + // Is with the used resolutions of limited value as test + //octave = ??? + RealVector v_mapUlp = ceil_v.mapUlp(); + double[] result_mapUlp = {2.220446049250313E-16d,1.1102230246251565E-16d,2.220446049250313E-16d}; + assertClose("compare vectors" ,result_mapUlp,v_mapUlp.getData(),normTolerance); + + //octave = ??? + RealVector v_mapUlpToSelf = ceil_v.copy(); + v_mapUlpToSelf.mapUlpToSelf(); + double[] result_mapUlpToSelf = {2.220446049250313E-16d,1.1102230246251565E-16d,2.220446049250313E-16d}; + assertClose("compare vectors" ,result_mapUlpToSelf,v_mapUlpToSelf.getData(),normTolerance); + + } + + public void testBasicFunctions() { + RealVectorImpl v1 = new RealVectorImpl(vec1); + RealVectorImpl v2 = new RealVectorImpl(vec2); + RealVectorImpl v_null = new RealVectorImpl(vec_null); + + RealVectorTestImpl v2_t = new RealVectorTestImpl(vec2); + + //octave = sqrt(sumsq(v1)) + double d_getNorm = v1.getNorm(); + assertEquals("compare values ", 3.7416573867739413,d_getNorm); + + double d_getL1Norm = v1.getL1Norm(); + assertEquals("compare values ",6.0, d_getL1Norm); + + double d_getLInfNorm = v1.getLInfNorm(); + assertEquals("compare values ",6.0, d_getLInfNorm); + + //octave = sqrt(sumsq(v1-v2)) + double dist = v1.getDistance(v2); + assertEquals("compare values ",v1.subtract(v2).getNorm(), dist ); + + //octave = sqrt(sumsq(v1-v2)) + double dist_2 = v1.getDistance(v2_t); + assertEquals("compare values ", v1.subtract(v2).getNorm(),dist_2 ); + + //octave = ??? + double d_getL1Distance = v1. getL1Distance(v2); + assertEquals("compare values ",9d, d_getL1Distance ); + + double d_getL1Distance_2 = v1. getL1Distance(v2_t); + assertEquals("compare values ",9d, d_getL1Distance_2 ); + + //octave = ??? + double d_getLInfDistance = v1. getLInfDistance(v2); + assertEquals("compare values ",3d, d_getLInfDistance ); + + double d_getLInfDistance_2 = v1. getLInfDistance(v2_t); + assertEquals("compare values ",3d, d_getLInfDistance_2 ); + + //octave = v1 + v2 + RealVectorImpl v_add = v1.add(v2); + double[] result_add = {5d, 7d, 9d}; + assertClose("compare vect" ,v_add.getData(),result_add,normTolerance); + + RealVectorTestImpl vt2 = new RealVectorTestImpl(vec2); + RealVector v_add_i = v1.add(vt2); + double[] result_add_i = {5d, 7d, 9d}; + assertClose("compare vect" ,v_add_i.getData(),result_add_i,normTolerance); + + //octave = v1 - v2 + RealVectorImpl v_subtract = v1.subtract(v2); + double[] result_subtract = {-3d, -3d, -3d}; + assertClose("compare vect" ,v_subtract.getData(),result_subtract,normTolerance); + + RealVector v_subtract_i = v1.subtract(vt2); + double[] result_subtract_i = {-3d, -3d, -3d}; + assertClose("compare vect" ,v_subtract_i.getData(),result_subtract_i,normTolerance); + + // octave v1 .* v2 + RealVectorImpl v_ebeMultiply = v1.ebeMultiply(v2); + double[] result_ebeMultiply = {4d, 10d, 18d}; + assertClose("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply,normTolerance); + + RealVector v_ebeMultiply_2 = v1.ebeMultiply(v2_t); + double[] result_ebeMultiply_2 = {4d, 10d, 18d}; + assertClose("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2,normTolerance); + + // octave v1 ./ v2 + RealVectorImpl v_ebeDivide = v1.ebeDivide(v2); + double[] result_ebeDivide = {0.25d, 0.4d, 0.5d}; + assertClose("compare vect" ,v_ebeDivide.getData(),result_ebeDivide,normTolerance); + + RealVector v_ebeDivide_2 = v1.ebeDivide(v2_t); + double[] result_ebeDivide_2 = {0.25d, 0.4d, 0.5d}; + assertClose("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2,normTolerance); + + // octave dot(v1,v2) + double dot = v1.dotProduct(v2); + assertEquals("compare val ",32d, dot); + + // octave dot(v1,v2_t) + double dot_2 = v1.dotProduct(v2_t); + assertEquals("compare val ",32d, dot_2); + + RealMatrixImpl m_outerProduct = v1.outerProduct(v2); + assertEquals("compare val ",4d, m_outerProduct.getEntry(0,0)); + + RealMatrix m_outerProduct_2 = v1.outerProduct(v2_t); + assertEquals("compare val ",4d, m_outerProduct_2.getEntry(0,0)); + + RealVector v_unitVector = v1.unitVector(); + RealVector v_unitVector_2 = v1.mapDivide(v1.getNorm()); + assertClose("compare vect" ,v_unitVector.getData(),v_unitVector_2.getData(),normTolerance); + + try { + v_null.unitVector(); + fail("Expecting ArithmeticException"); + } catch (ArithmeticException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v_unitize = (RealVectorImpl)v1.copy(); + v_unitize.unitize(); + assertClose("compare vect" ,v_unitVector_2.getData(),v_unitize.getData(),normTolerance); + try { + v_null.unitize(); + fail("Expecting ArithmeticException"); + } catch (ArithmeticException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + RealVectorImpl v_projection = v1.projection(v2); + double[] result_projection = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; + assertClose("compare vect", v_projection.getData(), result_projection, normTolerance); + + RealVector v_projection_2 = v1.projection(v2_t); + double[] result_projection_2 = {1.662337662337662, 2.0779220779220777, 2.493506493506493}; + assertClose("compare vect", v_projection_2.getData(), result_projection_2, normTolerance); + + } + + public void testMisc() { + RealVectorImpl v1 = new RealVectorImpl(vec1); + RealVectorImpl v4 = new RealVectorImpl(vec4); + RealVector v4_2 = new RealVectorImpl(vec4); + + String out1 = v1.toString(); + assertTrue("some output ", out1.length()!=0); + /* + double[] dout1 = v1.copyOut(); + assertEquals("testData len", 3, dout1.length); + assertNotSame("testData not same object ", v1.data, dout1); + */ + try { + v1.checkVectorDimensions(2); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + try { + v1.checkVectorDimensions(v4); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + try { + v1.checkVectorDimensions(v4_2); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + // expected behavior + } catch (Exception e) { + fail("wrong exception caught"); + } + + } + + public void testPredicates() { + + RealVectorImpl v = new RealVectorImpl(new double[] { 0, 1, 2 }); + + assertFalse(v.isNaN()); + v.set(1, Double.NaN); + assertTrue(v.isNaN()); + + assertFalse(v.isInfinite()); + v.set(0, Double.POSITIVE_INFINITY); + assertFalse(v.isInfinite()); + v.set(1, 1); + assertTrue(v.isInfinite()); + + v.set(0, 0); + assertEquals(v, new RealVectorImpl(new double[] { 0, 1, 2 })); + assertNotSame(v, new RealVectorImpl(new double[] { 0, 1, 2 + Math.ulp(2)})); + assertNotSame(v, new RealVectorImpl(new double[] { 0, 1, 2, 3 })); + + assertEquals(new RealVectorImpl(new double[] { Double.NaN, 1, 2 }).hashCode(), + new RealVectorImpl(new double[] { 0, Double.NaN, 2 }).hashCode()); + + assertTrue(new RealVectorImpl(new double[] { Double.NaN, 1, 2 }).hashCode() != + new RealVectorImpl(new double[] { 0, 1, 2 }).hashCode()); + + } + + /** verifies that two vectors are close (sup norm) */ + protected void assertClose(String msg, double[] m, double[] n, + double tolerance) { + if (m.length != n.length) { + fail("vectors have different lengths"); + } + for (int i = 0; i < m.length; i++) { + assertEquals(msg + " " + i + " elements differ", m[i],n[i],tolerance); + } + } + +}