commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r766485 [3/4] - in /commons/proper/math/trunk: ./ src/java/org/apache/commons/math/ src/java/org/apache/commons/math/linear/ src/java/org/apache/commons/math/linear/decomposition/ src/site/xdoc/ src/site/xdoc/userguide/ src/test/org/apache/...
Date Sun, 19 Apr 2009 16:39:41 GMT
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java?rev=766485&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java Sun Apr 19 16:39:40 2009
@@ -0,0 +1,802 @@
+/*
+ * 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.lang.reflect.Array;
+import java.util.Arrays;
+
+import org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+
+/**
+ * This class implements the {@link FieldVector<T>} interface with a {@link FieldElement} array.
+ * @param <T> the type of the field elements
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public class FieldVectorImpl<T extends FieldElement<T>> implements FieldVector<T> {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 7648186910365927050L;
+
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+
+    /** Entries of the vector. */
+    protected T[] data;
+
+    /** Build an array of elements.
+     * @param length size of the array to build
+     * @return a new array
+     */
+    @SuppressWarnings("unchecked")
+    private T[] buildArray(final int length) {
+        return (T[]) Array.newInstance(field.getZero().getClass(), length);
+    }
+
+    /**
+     * Build a 0-length vector.
+     * <p>Zero-length vectors may be used to initialized construction of vectors
+     * by data gathering. We start with zero-length and use either the {@link
+     * #FieldVectorImpl(FieldVectorImpl<T>, FieldVectorImpl<T>)} constructor
+     * or one of the <code>append</code> method ({@link #append(double)}, {@link
+     * #append(T[])}, {@link #append(FieldVectorImpl<T>)}) to gather data
+     * into this vector.</p>
+     * @param field field to which the elements belong
+     */
+    public FieldVectorImpl(final Field<T> field) {
+        this(field, 0);
+    }
+
+    /**
+     * Construct a (size)-length vector of zeros.
+     * @param field field to which the elements belong
+     * @param size size of the vector
+     */
+    public FieldVectorImpl(Field<T> field, int size) {
+        this.field = field;
+        data = buildArray(size);
+        Arrays.fill(data, field.getZero());
+    }
+
+    /**
+     * Construct an (size)-length vector with preset values.
+     * @param size size of the vector
+     * @param preset fill the vector with this scalar value
+     */
+    public FieldVectorImpl(int size, T preset) {
+        this(preset.getField(), size);
+        Arrays.fill(data, preset);
+    }
+
+    /**
+     * Construct a vector from an array, copying the input array.
+     * @param d array of Ts.
+     * @throws IllegalArgumentException if <code>d</code> is empty
+     */
+    public FieldVectorImpl(T[] d)
+        throws IllegalArgumentException {
+        try {
+            field = d[0].getField();
+            data = d.clone();
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                      "vector must have at least one element"); 
+        }
+    }
+
+    /**
+     * Create a new FieldVectorImpl using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * FieldVectorImpl and not used directly, the <code>copyArray</code> may be
+     * set to <code>false</code. This will prevent the copying and improve
+     * performance as no new array will be built and no data will be copied.</p>
+     * @param d data for new vector
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @throws IllegalArgumentException if <code>d</code> is empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #FieldVectorImpl(T[])
+     */
+    public FieldVectorImpl(T[] d, boolean copyArray)
+        throws NullPointerException, IllegalArgumentException {
+        try {
+            field = d[0].getField();
+            data = copyArray ? d.clone() :  d;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                      "vector must have at least one element");
+        }
+    }
+
+    /**
+     * Construct a vector from part of a array.
+     * @param d array of Ts.
+     * @param pos position of first entry
+     * @param size number of entries to copy
+     */
+    public FieldVectorImpl(T[] d, int pos, int size) {
+        if (d.length < pos + size) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    "position {0} and size {1} don't fit to the size of the input array {2}",
+                    pos, size, d.length);
+        }
+        field = d[0].getField();
+        data = buildArray(size);
+        System.arraycopy(d, pos, data, 0, size);
+    }
+
+    /**
+     * Construct a vector from another vector, using a deep copy.
+     * @param v vector to copy
+     */
+    public FieldVectorImpl(FieldVector<T> v) {
+        field = v.getField();
+        data = buildArray(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 FieldVectorImpl(FieldVectorImpl<T> v) {
+        field = v.getField();
+        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 FieldVectorImpl(FieldVectorImpl<T> v, boolean deep) {
+        field = v.getField();
+        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 FieldVectorImpl(FieldVectorImpl<T> v1, FieldVectorImpl<T> v2) {
+        field = v1.getField();
+        data = buildArray(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);
+    }
+
+    /**
+     * 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 FieldVectorImpl(FieldVectorImpl<T> v1, T[] v2) {
+        field = v1.getField();
+        data = buildArray(v1.data.length + v2.length);
+        System.arraycopy(v1.data, 0, data, 0, v1.data.length);
+        System.arraycopy(v2, 0, data, v1.data.length, v2.length);
+    }
+
+    /**
+     * 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 FieldVectorImpl(T[] v1, FieldVectorImpl<T> v2) {
+        field = v2.getField();
+        data = buildArray(v1.length + v2.data.length);
+        System.arraycopy(v1, 0, data, 0, v1.length);
+        System.arraycopy(v2.data, 0, data, v1.length, v2.data.length);
+    }
+
+    /**
+     * 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)
+     * @exception IllegalArgumentException if both vectors are empty
+     */
+    public FieldVectorImpl(T[] v1, T[] v2) {
+        try {
+            data = buildArray(v1.length + v2.length);
+            System.arraycopy(v1, 0, data, 0, v1.length);
+            System.arraycopy(v2, 0, data, v1.length, v2.length);
+            field = data[0].getField();
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                      "vector must have at least one element");
+        }
+    }
+
+    /** {@inheritDoc} */
+    public Field<T> getField() {
+        return field;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> copy() {
+        return new FieldVectorImpl<T>(this, true);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
+        try {
+            return add((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            T[] out = buildArray(data.length);
+            for (int i = 0; i < data.length; i++) {
+                out[i] = data[i].add(v.getEntry(i));
+            }
+            return new FieldVectorImpl<T>(out);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> add(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].add(v[i]);
+        }
+        return new FieldVectorImpl<T>(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 FieldVectorImpl<T> add(FieldVectorImpl<T> v)
+        throws IllegalArgumentException {
+        return (FieldVectorImpl<T>) add((T[]) v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> subtract(FieldVector<T> v) throws IllegalArgumentException {
+        try {
+            return subtract((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            T[] out = buildArray(data.length);
+            for (int i = 0; i < data.length; i++) {
+                out[i] = data[i].subtract(v.getEntry(i));
+            }
+            return new FieldVectorImpl<T>(out);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].subtract(v[i]);
+        }
+        return new FieldVectorImpl<T>(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 FieldVectorImpl<T> subtract(FieldVectorImpl<T> v)
+        throws IllegalArgumentException {
+        return (FieldVectorImpl<T>) subtract((T[]) v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapAdd(T d) {
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].add(d);
+        }
+        return new FieldVectorImpl<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapAddToSelf(T d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i].add(d);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapSubtract(T d) {
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].subtract(d);
+        }
+        return new FieldVectorImpl<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapSubtractToSelf(T d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i].subtract(d);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapMultiply(T d) {
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].multiply(d);
+        }
+        return new FieldVectorImpl<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapMultiplyToSelf(T d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i].multiply(d);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapDivide(T d) {
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].divide(d);
+        }
+        return new FieldVectorImpl<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapDivideToSelf(T d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i].divide(d);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapInv() {
+        T[] out = buildArray(data.length);
+        final T one = field.getOne();
+        for (int i = 0; i < data.length; i++) {
+            out[i] = one.divide(data[i]);
+        }
+        return new FieldVectorImpl<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> mapInvToSelf() {
+        final T one = field.getOne();
+        for (int i = 0; i < data.length; i++) {
+            data[i] = one.divide(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeMultiply(FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return ebeMultiply((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            T[] out = buildArray(data.length);
+            for (int i = 0; i < data.length; i++) {
+                out[i] = data[i].multiply(v.getEntry(i));
+            }
+            return new FieldVectorImpl<T>(out);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeMultiply(T[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+            out[i] = data[i].multiply(v[i]);
+        }
+        return new FieldVectorImpl<T>(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 FieldVectorImpl<T> ebeMultiply(FieldVectorImpl<T> v)
+        throws IllegalArgumentException {
+        return (FieldVectorImpl<T>) ebeMultiply(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeDivide(FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return ebeDivide((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            T[] out = buildArray(data.length);
+            for (int i = 0; i < data.length; i++) {
+                out[i] = data[i].divide(v.getEntry(i));
+            }
+            return new FieldVectorImpl<T>(out);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeDivide(T[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        T[] out = buildArray(data.length);
+        for (int i = 0; i < data.length; i++) {
+                out[i] = data[i].divide(v[i]);
+        }
+        return new FieldVectorImpl<T>(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 FieldVectorImpl<T> ebeDivide(FieldVectorImpl<T> v)
+        throws IllegalArgumentException {
+        return (FieldVectorImpl<T>) ebeDivide(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public T[] getData() {
+        return data.clone();
+    }
+
+    /**
+     * Returns a reference to the underlying data array.
+     * <p>Does not make a fresh copy of the underlying data.</p>
+     * @return array of entries
+     */
+    public T[] getDataRef() {
+        return data;
+    }
+
+    /** {@inheritDoc} */
+    public T dotProduct(FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return dotProduct((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            T dot = field.getZero();
+            for (int i = 0; i < data.length; i++) {
+                dot = dot.add(data[i].multiply(v.getEntry(i)));
+            }
+            return dot;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public T dotProduct(T[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        T dot = field.getZero();
+        for (int i = 0; i < data.length; i++) {
+            dot = dot.add(data[i].multiply(v[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 T dotProduct(FieldVectorImpl<T> v)
+        throws IllegalArgumentException {
+        return dotProduct(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> projection(FieldVector<T> v) {
+        return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> projection(T[] v) {
+        return projection(new FieldVectorImpl<T>(v, false));
+    }
+
+   /** 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 FieldVectorImpl<T> projection(FieldVectorImpl<T> v) {
+        return (FieldVectorImpl<T>) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> outerProduct(FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return outerProduct((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            final int m = data.length;
+            final FieldMatrix<T> out = new FieldMatrixImpl<T>(field, m, m);
+            for (int i = 0; i < data.length; i++) {
+                for (int j = 0; j < data.length; j++) {
+                    out.setEntry(i, j, data[i].multiply(v.getEntry(j)));
+                }
+            }
+            return 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 FieldMatrix<T> outerProduct(FieldVectorImpl<T> v)
+        throws IllegalArgumentException {
+        return outerProduct(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> outerProduct(T[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        final int m = data.length;
+        final FieldMatrix<T> out = new FieldMatrixImpl<T>(field, m, m);
+        for (int i = 0; i < data.length; i++) {
+            for (int j = 0; j < data.length; j++) {
+                out.setEntry(i, j, data[i].multiply(v[j]));
+            }
+        }
+        return out;
+    }
+
+    /** {@inheritDoc} */
+    public T getEntry(int index) throws MatrixIndexException {
+        return data[index];
+    }
+
+    /** {@inheritDoc} */
+    public int getDimension() {
+        return data.length;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(FieldVector<T> v) {
+        try {
+            return append((FieldVectorImpl<T>) v);
+        } catch (ClassCastException cce) {
+            return new FieldVectorImpl<T>(this,new FieldVectorImpl<T>(v));
+        }
+    }
+
+    /**
+     * Construct a vector by appending a vector to this vector.
+     * @param v vector to append to this one.
+     * @return a new vector
+     */
+    public FieldVectorImpl<T> append(FieldVectorImpl<T> v) {
+        return new FieldVectorImpl<T>(this, v);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(T in) {
+        final T[] out = buildArray(data.length + 1);
+        System.arraycopy(data, 0, out, 0, data.length);
+        out[data.length] = in;
+        return new FieldVectorImpl<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(T[] in) {
+        return new FieldVectorImpl<T>(this, in);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> getSubVector(int index, int n) {
+        FieldVectorImpl<T> out = new FieldVectorImpl<T>(field, n);
+        try {
+            System.arraycopy(data, index, out.data, 0, n);
+        } catch (IndexOutOfBoundsException e) {
+            checkIndex(index);
+            checkIndex(index + n - 1);
+        }
+        return out;
+    }
+
+    /** {@inheritDoc} */
+    public void setEntry(int index, T value) {
+        try {
+            data[index] = value;
+        } catch (IndexOutOfBoundsException e) {
+            checkIndex(index);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void setSubVector(int index, FieldVector<T> v) {
+        try {
+            try {
+                set(index, (FieldVectorImpl<T>) v);
+            } catch (ClassCastException cce) {
+                for (int i = index; i < index + v.getDimension(); ++i) {
+                    data[i] = v.getEntry(i-index);
+                }
+            }
+        } catch (IndexOutOfBoundsException e) {
+            checkIndex(index);
+            checkIndex(index + v.getDimension() - 1);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void setSubVector(int index, T[] v) {
+        try {
+            System.arraycopy(v, 0, data, index, v.length);
+        } catch (IndexOutOfBoundsException e) {
+            checkIndex(index);
+            checkIndex(index + v.length - 1);
+        }
+    }
+
+    /**
+     * 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, FieldVectorImpl<T> v)
+        throws MatrixIndexException {
+        setSubVector(index, v.data);
+    }
+
+    /** {@inheritDoc} */
+    public void set(T value) {
+        Arrays.fill(data, value);
+    }
+
+    /** {@inheritDoc} */
+    public T[] toArray(){
+        return data.clone();
+    }
+
+    /**
+     * 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
+     */
+    protected void checkVectorDimensions(FieldVector<T> 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
+     */
+    protected void checkVectorDimensions(int n)
+        throws IllegalArgumentException {
+        if (data.length != n) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    "vector length mismatch: got {0} but expected {1}",
+                    data.length, n);
+        }
+    }
+
+    /**
+     * Test for the equality of two real vectors.
+     * <p>
+     * If all coordinates of two real vectors are exactly the same, and none are
+     * <code>Double.NaN</code>, the two real vectors are considered to be equal.
+     * </p>
+     * <p>
+     * <code>NaN</code> 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 <code>Double.NaN</code>, the real vector is equal to
+     * a vector with all <code>Double.NaN</code> coordinates.
+     * </p>
+     *
+     * @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
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean equals(Object other) {
+
+      if (this == other) { 
+        return true;
+      }
+
+      if (other == null) {
+        return false;
+      }
+
+      try {
+
+          FieldVector<T> rhs = (FieldVector<T>) other;
+          if (data.length != rhs.getDimension()) {
+              return false;
+          }
+
+          for (int i = 0; i < data.length; ++i) {
+              if (!data[i].equals(rhs.getEntry(i))) {
+                  return false;
+              }
+          }
+          return true;
+
+      } catch (ClassCastException ex) {
+          // ignore exception
+          return false;
+      }
+
+    }
+    
+    /**
+     * Get a hashCode for the real vector.
+     * <p>All NaN values have the same hash code.</p>
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        int h = 3542;
+        for (final T a : data) {
+            h = h ^ a.hashCode();
+        }
+        return h;
+    }
+
+    /**
+     * Check if an index is valid.
+     * @param index index to check
+     * @exception MatrixIndexException if index is not valid
+     */
+    private void checkIndex(final int index)
+        throws MatrixIndexException {
+        if (index < 0 || index >= getDimension()) {
+            throw new MatrixIndexException(
+                    "index {0} out of allowed range [{1}, {2}]",
+                    index, 0, getDimension() - 1);
+        }
+    }
+
+}

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java?rev=766485&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java Sun Apr 19 16:39:40 2009
@@ -0,0 +1,91 @@
+/*
+ * 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.decomposition;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.FieldMatrix;
+import org.apache.commons.math.linear.FieldVector;
+import org.apache.commons.math.linear.InvalidMatrixException;
+
+
+/**
+ * Interface handling decomposition algorithms that can solve A &times; X = B.
+ * <p>Decomposition algorithms decompose an A matrix has a product of several specific
+ * matrices from which they can solve A &times; X = B in least squares sense: they find X
+ * such that ||A &times; X - B|| is minimal.</p>
+ * <p>Some solvers like {@link LUDecomposition} can only find the solution for
+ * square matrices and when the solution is an exact linear solution, i.e. when
+ * ||A &times; X - B|| is exactly 0. Other solvers can also find solutions
+ * with non-square matrix A and with non-null minimal norm. If an exact linear
+ * solution exists it is also the minimal norm solution.</p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public interface FieldDecompositionSolver<T extends FieldElement<T>> extends Serializable {
+
+    /** Solve the linear equation A &times; X = B for matrices A.
+     * <p>The A matrix is implicit, it is provided by the underlying
+     * decomposition algorithm.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; X - B
+     * @exception IllegalArgumentException if matrices dimensions don't match
+     * @exception InvalidMatrixException if decomposed matrix is singular
+     */
+    T[] solve(final T[] b)
+        throws IllegalArgumentException, InvalidMatrixException;
+
+    /** Solve the linear equation A &times; X = B for matrices A.
+     * <p>The A matrix is implicit, it is provided by the underlying
+     * decomposition algorithm.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a vector X that minimizes the two norm of A &times; X - B
+     * @exception IllegalArgumentException if matrices dimensions don't match
+     * @exception InvalidMatrixException if decomposed matrix is singular
+     */
+    FieldVector<T> solve(final FieldVector<T> b)
+        throws IllegalArgumentException, InvalidMatrixException;
+
+    /** Solve the linear equation A &times; X = B for matrices A.
+     * <p>The A matrix is implicit, it is provided by the underlying
+     * decomposition algorithm.</p>
+     * @param b right-hand side of the equation A &times; X = B
+     * @return a matrix X that minimizes the two norm of A &times; X - B
+     * @exception IllegalArgumentException if matrices dimensions don't match
+     * @exception InvalidMatrixException if decomposed matrix is singular
+     */
+    FieldMatrix<T> solve(final FieldMatrix<T> b)
+        throws IllegalArgumentException, InvalidMatrixException;
+
+    /**
+     * Check if the decomposed matrix is non-singular.
+     * @return true if the decomposed matrix is non-singular
+     */
+    boolean isNonSingular();
+
+    /** Get the inverse (or pseudo-inverse) of the decomposed matrix.
+     * @return inverse matrix
+     * @throws InvalidMatrixException if decomposed matrix is singular
+     */
+    FieldMatrix<T> getInverse()
+        throws InvalidMatrixException;
+
+}

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java?rev=766485&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java Sun Apr 19 16:39:40 2009
@@ -0,0 +1,97 @@
+/*
+ * 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.decomposition;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.FieldMatrix;
+
+/**
+ * An interface to classes that implement an algorithm to calculate the 
+ * LU-decomposition of a real matrix.
+ * <p>The LU-decomposition of matrix A is a set of three matrices: P, L and U
+ * such that P&times;A = L&times;U. P is a rows permutation matrix that is used
+ * to rearrange the rows of A before so that it can be decomposed. L is a lower
+ * triangular matrix with unit diagonal terms and U is an upper triangular matrix.</p>
+ * <p>This interface is based on the class with similar name from the now defunct
+ * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library.</p>
+ * <ul>
+ *   <li>a {@link #getP() getP} method has been added,</li>
+ *   <li>the <code>det</code> method has been renamed as {@link #getDeterminant()
+ *   getDeterminant},</li>
+ *   <li>the <code>getDoublePivot</code> method has been removed (but the int based
+ *   {@link #getPivot() getPivot} method has been kept),</li>
+ *   <li>the <code>solve</code> and <code>isNonSingular</code> methods have been replaced
+ *   by a {@link #getSolver() getSolver} method and the equivalent methods provided by
+ *   the returned {@link DecompositionSolver}.</li>
+ * </ul>
+ *   
+ * @param <T> the type of the field elements
+ * @see <a href="http://mathworld.wolfram.com/LUDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/LU_decomposition">Wikipedia</a>
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public interface FieldLUDecomposition<T extends FieldElement<T>> extends Serializable {
+
+    /**
+     * Returns the matrix L of the decomposition. 
+     * <p>L is an lower-triangular matrix</p>
+     * @return the L matrix (or null if decomposed matrix is singular)
+     */
+    FieldMatrix<T> getL();
+
+    /**
+     * Returns the matrix U of the decomposition. 
+     * <p>U is an upper-triangular matrix</p>
+     * @return the U matrix (or null if decomposed matrix is singular)
+     */
+    FieldMatrix<T> getU();
+
+    /**
+     * Returns the P rows permutation matrix.
+     * <p>P is a sparse matrix with exactly one element set to 1.0 in
+     * each row and each column, all other elements being set to 0.0.</p>
+     * <p>The positions of the 1 elements are given by the {@link #getPivot()
+     * pivot permutation vector}.</p>
+     * @return the P rows permutation matrix (or null if decomposed matrix is singular)
+     * @see #getPivot()
+     */
+    FieldMatrix<T> getP();
+
+    /**
+     * Returns the pivot permutation vector.
+     * @return the pivot permutation vector
+     * @see #getP()
+     */
+    int[] getPivot();
+
+    /**
+     * Return the determinant of the matrix
+     * @return determinant of the matrix
+     */
+    T getDeterminant();
+
+    /**
+     * Get a solver for finding the A &times; X = B solution in exact linear sense.
+     * @return a solver
+     */
+    FieldDecompositionSolver<T> getSolver();
+
+}

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java?rev=766485&view=auto
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java (added)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java Sun Apr 19 16:39:40 2009
@@ -0,0 +1,441 @@
+/*
+ * 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.decomposition;
+
+import java.lang.reflect.Array;
+
+import org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.linear.FieldMatrix;
+import org.apache.commons.math.linear.FieldMatrixImpl;
+import org.apache.commons.math.linear.FieldVector;
+import org.apache.commons.math.linear.FieldVectorImpl;
+import org.apache.commons.math.linear.InvalidMatrixException;
+
+/**
+ * Calculates the LUP-decomposition of a square matrix.
+ * <p>The LUP-decomposition of a matrix A consists of three matrices
+ * L, U and P that satisfy: PA = LU, L is lower triangular, and U is
+ * upper triangular and P is a permutation matrix. All matrices are
+ * m&times;m.</p>
+ * <p>Since {@link FieldElement field elements} do not provide an ordering
+ * operator, the permutation matrix is computed here only in order to avoid
+ * a zero pivot element, no attempt is done to get the largest pivot element.</p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision$ $Date$
+ * @since 2.0
+ */
+public class FieldLUDecompositionImpl<T extends FieldElement<T>> implements FieldLUDecomposition<T> {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 1954692554563387537L;
+
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+
+    /** Entries of LU decomposition. */
+    private T lu[][];
+
+    /** Pivot permutation associated with LU decomposition */
+    private int[] pivot;
+
+    /** Parity of the permutation associated with the LU decomposition */
+    private boolean even;
+
+    /** Singularity indicator. */
+    private boolean singular;
+
+    /** Cached value of L. */
+    private FieldMatrix<T> cachedL;
+
+    /** Cached value of U. */
+    private FieldMatrix<T> cachedU;
+
+    /** Cached value of P. */
+    private FieldMatrix<T> cachedP;
+
+    /**
+     * Calculates the LU-decomposition of the given matrix. 
+     * @param matrix The matrix to decompose.
+     * @exception NonSquareMatrixException if matrix is not square
+     */
+    public FieldLUDecompositionImpl(FieldMatrix<T> matrix)
+        throws NonSquareMatrixException {
+
+        if (!matrix.isSquare()) {
+            throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension());
+        }
+
+        final int m = matrix.getColumnDimension();
+        field = matrix.getField();
+        lu = matrix.getData();
+        pivot = new int[m];
+        cachedL = null;
+        cachedU = null;
+        cachedP = null;
+
+        // Initialize permutation array and parity
+        for (int row = 0; row < m; row++) {
+            pivot[row] = row;
+        }
+        even     = true;
+        singular = false;
+
+        // Loop over columns
+        for (int col = 0; col < m; col++) {
+
+            T sum = field.getZero();
+
+            // upper
+            for (int row = 0; row < col; row++) {
+                final T[] luRow = lu[row];
+                sum = luRow[col];
+                for (int i = 0; i < row; i++) {
+                    sum = sum.subtract(luRow[i].multiply(lu[i][col]));
+                }
+                luRow[col] = sum;
+            }
+
+            // lower
+            int nonZero = col; // permutation row
+            for (int row = col; row < m; row++) {
+                final T[] luRow = lu[row];
+                sum = luRow[col];
+                for (int i = 0; i < col; i++) {
+                    sum = sum.subtract(luRow[i].multiply(lu[i][col]));
+                }
+                luRow[col] = sum;
+
+                if (lu[nonZero][col].equals(field.getZero())) {
+                    // try to select a better permutation choice
+                    ++nonZero;
+                }
+            }
+
+            // Singularity check
+            if (nonZero >= m) {
+                singular = true;
+                return;
+            }
+
+            // Pivot if necessary
+            if (nonZero != col) {
+                T tmp = field.getZero();
+                for (int i = 0; i < m; i++) {
+                    tmp = lu[nonZero][i];
+                    lu[nonZero][i] = lu[col][i];
+                    lu[col][i] = tmp;
+                }
+                int temp = pivot[nonZero];
+                pivot[nonZero] = pivot[col];
+                pivot[col] = temp;
+                even = !even;
+            }
+
+            // Divide the lower elements by the "winning" diagonal elt.
+            final T luDiag = lu[col][col];
+            for (int row = col + 1; row < m; row++) {
+                final T[] luRow = lu[row];
+                luRow[col] = luRow[col].divide(luDiag);
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getL() {
+        if ((cachedL == null) && !singular) {
+            final int m = pivot.length;
+            cachedL = new FieldMatrixImpl<T>(field, m, m);
+            for (int i = 0; i < m; ++i) {
+                final T[] luI = lu[i];
+                for (int j = 0; j < i; ++j) {
+                    cachedL.setEntry(i, j, luI[j]);
+                }
+                cachedL.setEntry(i, i, field.getOne());
+            }
+        }
+        return cachedL;
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getU() {
+        if ((cachedU == null) && !singular) {
+            final int m = pivot.length;
+            cachedU = new FieldMatrixImpl<T>(field, m, m);
+            for (int i = 0; i < m; ++i) {
+                final T[] luI = lu[i];
+                for (int j = i; j < m; ++j) {
+                    cachedU.setEntry(i, j, luI[j]);
+                }
+            }
+        }
+        return cachedU;
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getP() {
+        if ((cachedP == null) && !singular) {
+            final int m = pivot.length;
+            cachedP = new FieldMatrixImpl<T>(field, m, m);
+            for (int i = 0; i < m; ++i) {
+                cachedP.setEntry(i, pivot[i], field.getOne());
+            }
+        }
+        return cachedP;
+    }
+
+    /** {@inheritDoc} */
+    public int[] getPivot() {
+        return pivot.clone();
+    }
+
+    /** {@inheritDoc} */
+    public T getDeterminant() {
+        if (singular) {
+            return field.getZero();
+        } else {
+            final int m = pivot.length;
+            T determinant = even ? field.getOne() : field.getZero().subtract(field.getOne());
+            for (int i = 0; i < m; i++) {
+                determinant = determinant.multiply(lu[i][i]);
+            }
+            return determinant;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public FieldDecompositionSolver<T> getSolver() {
+        return new Solver<T>(field, lu, pivot, singular);
+    }
+
+    /** Specialized solver. */
+    private static class Solver<T extends FieldElement<T>> implements FieldDecompositionSolver<T> {
+
+        /** Serializable version identifier. */
+        private static final long serialVersionUID = -6353105415121373022L;
+
+        /** Field to which the elements belong. */
+        private final Field<T> field;
+
+        /** Entries of LU decomposition. */
+        private final T lu[][];
+
+        /** Pivot permutation associated with LU decomposition. */
+        private final int[] pivot;
+
+        /** Singularity indicator. */
+        private final boolean singular;
+
+        /**
+         * Build a solver from decomposed matrix.
+         * @param field field to which the matrix elements belong
+         * @param lu entries of LU decomposition
+         * @param pivot pivot permutation associated with LU decomposition
+         * @param singular singularity indicator
+         */
+        private Solver(final Field<T> field, final T[][] lu,
+                       final int[] pivot, final boolean singular) {
+            this.field    = field;
+            this.lu       = lu;
+            this.pivot    = pivot;
+            this.singular = singular;
+        }
+
+        /** {@inheritDoc} */
+        public boolean isNonSingular() {
+            return !singular;
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("unchecked")
+        public T[] solve(T[] b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = pivot.length;
+            if (b.length != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        "vector length mismatch: got {0} but expected {1}",
+                        b.length, m);
+            }
+            if (singular) {
+                throw new SingularMatrixException();
+            }
+
+            final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m);
+
+            // Apply permutations to b
+            for (int row = 0; row < m; row++) {
+                bp[row] = b[pivot[row]];
+            }
+
+            // Solve LY = b
+            for (int col = 0; col < m; col++) {
+                final T bpCol = bp[col];
+                for (int i = col + 1; i < m; i++) {
+                    bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
+                }
+            }
+
+            // Solve UX = Y
+            for (int col = m - 1; col >= 0; col--) {
+                bp[col] = bp[col].divide(lu[col][col]);
+                final T bpCol = bp[col];
+                for (int i = 0; i < col; i++) {
+                    bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
+                }
+            }
+
+            return bp;
+
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("unchecked")
+        public FieldVector<T> solve(FieldVector<T> b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            try {
+                return solve((FieldVectorImpl<T>) b);
+            } catch (ClassCastException cce) {
+
+                final int m = pivot.length;
+                if (b.getDimension() != m) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            "vector length mismatch: got {0} but expected {1}",
+                            b.getDimension(), m);
+                }
+                if (singular) {
+                    throw new SingularMatrixException();
+                }
+
+                final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m);
+
+                // Apply permutations to b
+                for (int row = 0; row < m; row++) {
+                    bp[row] = b.getEntry(pivot[row]);
+                }
+
+                // Solve LY = b
+                for (int col = 0; col < m; col++) {
+                    final T bpCol = bp[col];
+                    for (int i = col + 1; i < m; i++) {
+                        bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
+                    }
+                }
+
+                // Solve UX = Y
+                for (int col = m - 1; col >= 0; col--) {
+                    bp[col] = bp[col].divide(lu[col][col]);
+                    final T bpCol = bp[col];
+                    for (int i = 0; i < col; i++) {
+                        bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
+                    }
+                }
+
+                return new FieldVectorImpl<T>(bp, false);
+
+            }
+        }
+
+        /** Solve the linear equation A &times; X = B.
+         * <p>The A matrix is implicit here. It is </p>
+         * @param b right-hand side of the equation A &times; X = B
+         * @return a vector X such that A &times; X = B
+         * @exception IllegalArgumentException if matrices dimensions don't match
+         * @exception InvalidMatrixException if decomposed matrix is singular
+         */
+        public FieldVectorImpl<T> solve(FieldVectorImpl<T> b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            return new FieldVectorImpl<T>(solve(b.getDataRef()), false);
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("unchecked")
+        public FieldMatrix<T> solve(FieldMatrix<T> b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = pivot.length;
+            if (b.getRowDimension() != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        "dimensions mismatch: got {0}x{1} but expected {2}x{3}",
+                        b.getRowDimension(), b.getColumnDimension(), m, "n");
+            }
+            if (singular) {
+                throw new SingularMatrixException();
+            }
+
+            final int nColB = b.getColumnDimension();
+
+            // Apply permutations to b
+            final T[][] bp = (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { m, nColB });
+            for (int row = 0; row < m; row++) {
+                final T[] bpRow = bp[row];
+                final int pRow = pivot[row];
+                for (int col = 0; col < nColB; col++) {
+                    bpRow[col] = b.getEntry(pRow, col);
+                }
+            }
+
+            // Solve LY = b
+            for (int col = 0; col < m; col++) {
+                final T[] bpCol = bp[col];
+                for (int i = col + 1; i < m; i++) {
+                    final T[] bpI = bp[i];
+                    final T luICol = lu[i][col];
+                    for (int j = 0; j < nColB; j++) {
+                        bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol));
+                    }
+                }
+            }
+
+            // Solve UX = Y
+            for (int col = m - 1; col >= 0; col--) {
+                final T[] bpCol = bp[col];
+                final T luDiag = lu[col][col];
+                for (int j = 0; j < nColB; j++) {
+                    bpCol[j] = bpCol[j].divide(luDiag);
+                }
+                for (int i = 0; i < col; i++) {
+                    final T[] bpI = bp[i];
+                    final T luICol = lu[i][col];
+                    for (int j = 0; j < nColB; j++) {
+                        bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol));
+                    }
+                }
+            }
+
+            return new FieldMatrixImpl<T>(bp, false);
+
+        }
+
+        /** {@inheritDoc} */
+        public FieldMatrix<T> getInverse() throws InvalidMatrixException {
+            final int m = pivot.length;
+            final T one = field.getOne();
+            FieldMatrix<T> identity = new FieldMatrixImpl<T>(field, m, m);
+            for (int i = 0; i < m; ++i) {
+                identity.setEntry(i, i, one);
+            }
+            return solve(identity);
+        }
+
+    }
+
+}

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/LUDecompositionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/LUDecompositionImpl.java?rev=766485&r1=766484&r2=766485&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/LUDecompositionImpl.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/LUDecompositionImpl.java Sun Apr 19 16:39:40 2009
@@ -28,7 +28,7 @@
 /**
  * Calculates the LUP-decomposition of a square matrix.
  * <p>The LUP-decomposition of a matrix A consists of three matrices
- * L, U and P that satisfy: A = LUP, L is lower triangular, and U is
+ * L, U and P that satisfy: PA = LU, L is lower triangular, and U is
  * upper triangular and P is a permutation matrix. All matrices are
  * m&times;m.</p>
  * <p>As shown by the presence of the P matrix, this decomposition is
@@ -146,10 +146,12 @@
             // Pivot if necessary
             if (max != col) {
                 double tmp = 0;
+                final double[] luMax = lu[max];
+                final double[] luCol = lu[col];
                 for (int i = 0; i < m; i++) {
-                    tmp = lu[max][i];
-                    lu[max][i] = lu[col][i];
-                    lu[col][i] = tmp;
+                    tmp = luMax[i];
+                    luMax[i] = luCol[i];
+                    luCol[i] = tmp;
                 }
                 int temp = pivot[max];
                 pivot[max] = pivot[col];
@@ -288,16 +290,18 @@
 
             // Solve LY = b
             for (int col = 0; col < m; col++) {
+                final double bpCol = bp[col];
                 for (int i = col + 1; i < m; i++) {
-                    bp[i] -= bp[col] * lu[i][col];
+                    bp[i] -= bpCol * lu[i][col];
                 }
             }
 
             // Solve UX = Y
             for (int col = m - 1; col >= 0; col--) {
                 bp[col] /= lu[col][col];
+                final double bpCol = bp[col];
                 for (int i = 0; i < col; i++) {
-                    bp[i] -= bp[col] * lu[i][col];
+                    bp[i] -= bpCol * lu[i][col];
                 }
             }
 
@@ -331,16 +335,18 @@
 
                 // Solve LY = b
                 for (int col = 0; col < m; col++) {
+                    final double bpCol = bp[col];
                     for (int i = col + 1; i < m; i++) {
-                        bp[i] -= bp[col] * lu[i][col];
+                        bp[i] -= bpCol * lu[i][col];
                     }
                 }
 
                 // Solve UX = Y
                 for (int col = m - 1; col >= 0; col--) {
                     bp[col] /= lu[col][col];
+                    final double bpCol = bp[col];
                     for (int i = 0; i < col; i++) {
-                        bp[i] -= bp[col] * lu[i][col];
+                        bp[i] -= bpCol * lu[i][col];
                     }
                 }
 

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=766485&r1=766484&r2=766485&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Apr 19 16:39:40 2009
@@ -40,6 +40,10 @@
   <body>
     <release version="2.0" date="TBD" description="TBD">
       <action dev="luc" type="add" >
+        Added support for any type of field in linear algebra (FielxMatrix, FieldVector,
+        FieldLUDecomposition)
+      </action>
+      <action dev="luc" type="add" >
         Added general Field and FieldElement interfaces to allow generic algorithms
         to operate on fields. The library already provides several implementations:
         Complex, Fraction, BigFraction and BigReal

Modified: commons/proper/math/trunk/src/site/xdoc/userguide/index.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/userguide/index.xml?rev=766485&r1=766484&r2=766485&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/userguide/index.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/userguide/index.xml Sun Apr 19 16:39:40 2009
@@ -62,6 +62,7 @@
                 <li><a href="linear.html#a3.3_Real_vectors">3.3 Real vectors</a></li>
                 <li><a href="linear.html#a3.4_Solving_linear_systems">3.4 Solving linear systems</a></li> 
                 <li><a href="linear.html#a3.5_Eigenvalueseigenvectors_and_singular_valuessingular_vectors">3.5 Eigenvalues/eigenvectors and singular values/singular vectors</a></li>
+                <li><a href="linear.html#a3.6_Non-real_fields_complex_fractions_...">3.6 Non-real fields (complex, fractions ...)</a></li>
                 </ul></li>             
             <li><a href="analysis.html">4. Numerical Analysis</a>
                 <ul>
@@ -84,7 +85,7 @@
                 <li><a href="utilities.html#a6.2_Double_array_utilities">6.2 Double array utilities</a></li>
                 <li><a href="utilities.html#a6.3_intdouble_hash_map">6.3 int/double hash map</a></li>
                 <li><a href="utilities.html#a6.4_Continued_Fractions">6.4 Continued Fractions</a></li>
-                <li><a href="utilities.html#a6.5_binomial_coefficients,_factorials_and_other_common_math_functions">6.5 binomial coefficients, factorials and other common math functions</a></li>
+                <li><a href="utilities.html#a6.5_binomial_coefficients_factorials_and_other_common_math_functions">6.5 binomial coefficients, factorials and other common math functions</a></li>
                 </ul></li>                                 
         <li><a href="complex.html">7. Complex Numbers</a>
                 <ul>

Modified: commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml?rev=766485&r1=766484&r2=766485&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml Sun Apr 19 16:39:40 2009
@@ -184,6 +184,19 @@
         vector spaces (which may have different dimensions).
         </p>
       </subsection>
+      <subsection name="3.6 Non-real fields (complex, fractions ...)" href="field">
+        <p>
+          In addition to the real field, matrices and vectors using non-real <a
+          href="../apidocs/org/apache/commons/math/FieldElement.html">field elements</a> can be used.
+          The fields already supported by the library are:
+          <ul>
+            <li><a href="../apidocs/org/apache/commons/math/complex/Complex.html">Complex</a></li>
+            <li><a href="../apidocs/org/apache/commons/math/fraction/Fraction.html">Fraction</a></li>
+            <li><a href="../apidocs/org/apache/commons/math/fraction/BigFraction.html">BigFraction</a></li>
+            <li><a href="../apidocs/org/apache/commons/math/util/BigReal.html">BigReal</a></li>
+          </ul>
+        </p>
+      </subsection>
     </section>
   </body>
 </document>

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/TestUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/TestUtils.java?rev=766485&r1=766484&r2=766485&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/TestUtils.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/TestUtils.java Sun Apr 19 16:39:40 2009
@@ -28,6 +28,7 @@
 
 import org.apache.commons.math.complex.Complex;
 import org.apache.commons.math.complex.ComplexFormat;
+import org.apache.commons.math.linear.FieldMatrix;
 import org.apache.commons.math.linear.RealMatrix;
 
 /**
@@ -282,6 +283,34 @@
         }
     }
     
+    /** verifies that two matrices are equal */              
+    public static void assertEquals(FieldMatrix<? extends FieldElement<?>> expected,
+                                    FieldMatrix<? extends FieldElement<?>> observed) {
+        
+        if (observed == null) {
+            Assert.fail("Observed is null");
+        }
+        
+        if (expected.getColumnDimension() != observed.getColumnDimension() || 
+                expected.getRowDimension() != observed.getRowDimension()) {
+            StringBuffer messageBuffer = new StringBuffer();
+            messageBuffer.append("Observed has incorrect dimensions."); 
+            messageBuffer.append("\nobserved is " + observed.getRowDimension() +
+                    " x " + observed.getColumnDimension());
+            messageBuffer.append("\nexpected " + expected.getRowDimension() +
+                    " x " + expected.getColumnDimension());
+            Assert.fail(messageBuffer.toString());
+        }
+
+        for (int i = 0; i < expected.getRowDimension(); ++i) {
+            for (int j = 0; j < expected.getColumnDimension(); ++j) {
+                FieldElement<?> eij = expected.getEntry(i, j);
+                FieldElement<?> oij = observed.getEntry(i, j);
+                Assert.assertEquals(eij, oij);
+            }
+        }
+    }
+    
     /** verifies that two arrays are close (sup norm) */
     public static void assertEquals(String msg, double[] m, double[] n,
         double tolerance) {
@@ -294,4 +323,15 @@
         }
     }
     
+    /** verifies that two arrays are equal */
+    public static void assertEquals(FieldElement<? extends FieldElement<?>>[] m,
+                                    FieldElement<? extends FieldElement<?>>[] n) {
+        if (m.length != n.length) {
+            Assert.fail("vectors not same length");
+        }
+        for (int i = 0; i < m.length; i++) {
+            Assert.assertEquals(m[i],n[i]);
+        }
+    }
+    
 }

Modified: commons/proper/math/trunk/src/test/org/apache/commons/math/linear/BigMatrixImplTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/linear/BigMatrixImplTest.java?rev=766485&r1=766484&r2=766485&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/org/apache/commons/math/linear/BigMatrixImplTest.java (original)
+++ commons/proper/math/trunk/src/test/org/apache/commons/math/linear/BigMatrixImplTest.java Sun Apr 19 16:39:40 2009
@@ -29,7 +29,7 @@
  *
  * @version $Revision$ $Date$
  */
-
+@Deprecated
 public final class BigMatrixImplTest extends TestCase {
     
     // Test data for String constructors



Mime
View raw message