diff --git a/src/main/java/org/apache/commons/math/ArgumentOutsideDomainException.java b/src/main/java/org/apache/commons/math/ArgumentOutsideDomainException.java
new file mode 100644
index 0000000..a43c6b9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ArgumentOutsideDomainException.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when a method is called with an out of bounds argument.
+ *
+ * @since 1.2
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class ArgumentOutsideDomainException extends FunctionEvaluationException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -4965972841162580234L;
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param argument  the failing function argument
+     * @param lower lower bound of the domain
+     * @param upper upper bound of the domain
+     */
+    public ArgumentOutsideDomainException(double argument, double lower, double upper) {
+        super(argument, LocalizedFormats.ARGUMENT_OUTSIDE_DOMAIN, argument, lower, upper);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ConvergenceException.java b/src/main/java/org/apache/commons/math/ConvergenceException.java
new file mode 100644
index 0000000..0cc3959
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ConvergenceException.java
@@ -0,0 +1,99 @@
+/*
+ * 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;
+
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when a numerical computation can not be performed because the
+ * numerical result failed to converge to a finite value.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class ConvergenceException extends MathException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1111352570797662604L;
+
+    /**
+     * Default constructor.
+     */
+    public ConvergenceException() {
+        super(LocalizedFormats.CONVERGENCE_FAILED);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     * @deprecated as of 2.2 replaced by {@link #ConvergenceException(Localizable, Object...)}
+     */
+    @Deprecated
+    public ConvergenceException(String pattern, Object ... arguments) {
+        this(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public ConvergenceException(Localizable pattern, Object ... arguments) {
+        super(pattern, arguments);
+    }
+
+    /**
+     * Create an exception with a given root cause.
+     * @param cause  the exception or error that caused this exception to be thrown
+     */
+    public ConvergenceException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     * @deprecated as of 2.2 replaced by {@link #ConvergenceException(Throwable, Localizable, Object...)}
+     */
+    @Deprecated
+    public ConvergenceException(Throwable cause, String pattern, Object ... arguments) {
+        this(cause, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public ConvergenceException(Throwable cause, Localizable pattern, Object ... arguments) {
+        super(cause, pattern, arguments);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ConvergingAlgorithm.java b/src/main/java/org/apache/commons/math/ConvergingAlgorithm.java
new file mode 100644
index 0000000..128f169
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ConvergingAlgorithm.java
@@ -0,0 +1,141 @@
+/*
+ * 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;
+
+
+/**
+ * Interface for algorithms handling convergence settings.
+ * <p>
+ * This interface only deals with convergence parameters setting, not
+ * execution of the algorithms per se.
+ * </p>
+ * @see ConvergenceException
+ * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $
+ * @since 2.0
+ * @deprecated in 2.2 (to be removed in 3.0). The concept of "iteration" will
+ * be moved to a new {@code IterativeAlgorithm}. The concept of "accuracy" is
+ * currently is also contained in {@link org.apache.commons.math.optimization.SimpleRealPointChecker}
+ * and similar classes.
+ */
+@Deprecated
+public interface ConvergingAlgorithm {
+
+    /**
+     * Set the upper limit for the number of iterations.
+     * <p>
+     * Usually a high iteration count indicates convergence problems. However,
+     * the "reasonable value" varies widely for different algorithms. Users are
+     * advised to use the default value supplied by the algorithm.</p>
+     * <p>
+     * A {@link ConvergenceException} will be thrown if this number
+     * is exceeded.</p>
+     *
+     * @param count maximum number of iterations
+     */
+    void setMaximalIterationCount(int count);
+
+    /**
+     * Get the upper limit for the number of iterations.
+     *
+     * @return the actual upper limit
+     */
+    int getMaximalIterationCount();
+
+    /**
+     * Reset the upper limit for the number of iterations to the default.
+     * <p>
+     * The default value is supplied by the algorithm implementation.</p>
+     *
+     * @see #setMaximalIterationCount(int)
+     */
+    void resetMaximalIterationCount();
+
+    /**
+     * Set the absolute accuracy.
+     * <p>
+     * The default is usually chosen so that results in the interval
+     * -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the
+     * expected absolute value of your results is of much smaller magnitude, set
+     * this to a smaller value.</p>
+     * <p>
+     * Algorithms are advised to do a plausibility check with the relative
+     * accuracy, but clients should not rely on this.</p>
+     *
+     * @param accuracy the accuracy.
+     * @throws IllegalArgumentException if the accuracy can't be achieved by
+     * the solver or is otherwise deemed unreasonable.
+     */
+    void setAbsoluteAccuracy(double accuracy);
+
+    /**
+     * Get the actual absolute accuracy.
+     *
+     * @return the accuracy
+     */
+    double getAbsoluteAccuracy();
+
+    /**
+     * Reset the absolute accuracy to the default.
+     * <p>
+     * The default value is provided by the algorithm implementation.</p>
+     */
+    void resetAbsoluteAccuracy();
+
+    /**
+     * Set the relative accuracy.
+     * <p>
+     * This is used to stop iterations if the absolute accuracy can't be
+     * achieved due to large values or short mantissa length.</p>
+     * <p>
+     * If this should be the primary criterion for convergence rather then a
+     * safety measure, set the absolute accuracy to a ridiculously small value,
+     * like {@link org.apache.commons.math.util.MathUtils#SAFE_MIN MathUtils.SAFE_MIN}.</p>
+     *
+     * @param accuracy the relative accuracy.
+     * @throws IllegalArgumentException if the accuracy can't be achieved by
+     *  the algorithm or is otherwise deemed unreasonable.
+     */
+    void setRelativeAccuracy(double accuracy);
+
+    /**
+     * Get the actual relative accuracy.
+     * @return the accuracy
+     */
+    double getRelativeAccuracy();
+
+    /**
+     * Reset the relative accuracy to the default.
+     * The default value is provided by the algorithm implementation.
+     */
+    void resetRelativeAccuracy();
+
+    /**
+     * Get the number of iterations in the last run of the algorithm.
+     * <p>
+     * This is mainly meant for testing purposes. It may occasionally
+     * help track down performance problems: if the iteration count
+     * is notoriously high, check whether the problem is evaluated
+     * properly, and whether another algorithm is more amenable to the
+     * problem.</p>
+     *
+     * @return the last iteration count.
+     * @throws IllegalStateException if there is no result available, either
+     * because no result was yet computed or the last attempt failed.
+     */
+    int getIterationCount();
+
+}
diff --git a/src/main/java/org/apache/commons/math/ConvergingAlgorithmImpl.java b/src/main/java/org/apache/commons/math/ConvergingAlgorithmImpl.java
new file mode 100644
index 0000000..e15b9a9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ConvergingAlgorithmImpl.java
@@ -0,0 +1,155 @@
+/*
+ * 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;
+
+/**
+ * Provide a default implementation for several functions useful to generic
+ * converging algorithms.
+ *
+ * @version $Revision: 1062691 $ $Date: 2011-01-24 10:12:47 +0100 (lun. 24 janv. 2011) $
+ * @since 2.0
+ * @deprecated in 2.2 (to be removed in 3.0).
+ */
+public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm {
+
+    /** Maximum absolute error. */
+    protected double absoluteAccuracy;
+
+    /** Maximum relative error. */
+    protected double relativeAccuracy;
+
+    /** Maximum number of iterations. */
+    protected int maximalIterationCount;
+
+    /** Default maximum absolute error. */
+    protected double defaultAbsoluteAccuracy;
+
+    /** Default maximum relative error. */
+    protected double defaultRelativeAccuracy;
+
+    /** Default maximum number of iterations. */
+    protected int defaultMaximalIterationCount;
+
+    /** The last iteration count. */
+    protected int iterationCount;
+
+    /**
+     * Construct an algorithm with given iteration count and accuracy.
+     *
+     * @param defaultAbsoluteAccuracy maximum absolute error
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @throws IllegalArgumentException if f is null or the
+     * defaultAbsoluteAccuracy is not valid
+     * @deprecated in 2.2. Derived classes should use the "setter" methods
+     * in order to assign meaningful values to all the instances variables.
+     */
+    @Deprecated
+    protected ConvergingAlgorithmImpl(final int defaultMaximalIterationCount,
+                                      final double defaultAbsoluteAccuracy) {
+        this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy;
+        this.defaultRelativeAccuracy = 1.0e-14;
+        this.absoluteAccuracy = defaultAbsoluteAccuracy;
+        this.relativeAccuracy = defaultRelativeAccuracy;
+        this.defaultMaximalIterationCount = defaultMaximalIterationCount;
+        this.maximalIterationCount = defaultMaximalIterationCount;
+        this.iterationCount = 0;
+    }
+
+    /**
+     * Default constructor.
+     *
+     * @since 2.2
+     * @deprecated in 2.2 (to be removed as soon as the single non-default one
+     * has been removed).
+     */
+    @Deprecated
+    protected ConvergingAlgorithmImpl() {}
+
+    /** {@inheritDoc} */
+    public int getIterationCount() {
+        return iterationCount;
+    }
+
+    /** {@inheritDoc} */
+    public void setAbsoluteAccuracy(double accuracy) {
+        absoluteAccuracy = accuracy;
+    }
+
+    /** {@inheritDoc} */
+    public double getAbsoluteAccuracy() {
+        return absoluteAccuracy;
+    }
+
+    /** {@inheritDoc} */
+    public void resetAbsoluteAccuracy() {
+        absoluteAccuracy = defaultAbsoluteAccuracy;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaximalIterationCount(int count) {
+        maximalIterationCount = count;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaximalIterationCount() {
+        return maximalIterationCount;
+    }
+
+    /** {@inheritDoc} */
+    public void resetMaximalIterationCount() {
+        maximalIterationCount = defaultMaximalIterationCount;
+    }
+
+    /** {@inheritDoc} */
+    public void setRelativeAccuracy(double accuracy) {
+        relativeAccuracy = accuracy;
+    }
+
+    /** {@inheritDoc} */
+    public double getRelativeAccuracy() {
+        return relativeAccuracy;
+    }
+
+    /** {@inheritDoc} */
+    public void resetRelativeAccuracy() {
+        relativeAccuracy = defaultRelativeAccuracy;
+    }
+
+    /**
+     * Reset the iterations counter to 0.
+     *
+     * @since 2.2
+     */
+    protected void resetIterationsCounter() {
+        iterationCount = 0;
+    }
+
+    /**
+     * Increment the iterations counter by 1.
+     *
+     * @throws MaxIterationsExceededException if the maximal number
+     * of iterations is exceeded.
+     * @since 2.2
+     */
+    protected void incrementIterationsCounter()
+        throws MaxIterationsExceededException {
+        if (++iterationCount > maximalIterationCount) {
+            throw new MaxIterationsExceededException(maximalIterationCount);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/DimensionMismatchException.java b/src/main/java/org/apache/commons/math/DimensionMismatchException.java
new file mode 100644
index 0000000..b1c3dc4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/DimensionMismatchException.java
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when two dimensions differ.
+ *
+ * @since 1.2
+ * @version $Revision: 1061778 $ $Date: 2011-01-21 13:12:39 +0100 (ven. 21 janv. 2011) $
+ * @deprecated in 2.2 (to be removed in 3.0). Please use its equivalent from package
+ * {@link org.apache.commons.math.exception}.
+ */
+public class DimensionMismatchException extends MathException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1316089546353786411L;
+
+    /** First dimension. */
+    private final int dimension1;
+
+    /** Second dimension. */
+    private final int dimension2;
+
+    /**
+     * Construct an exception from the mismatched dimensions
+     * @param dimension1 first dimension
+     * @param dimension2 second dimension
+     */
+    public DimensionMismatchException(final int dimension1, final int dimension2) {
+        super(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, dimension1, dimension2);
+        this.dimension1 = dimension1;
+        this.dimension2 = dimension2;
+    }
+
+    /**
+     * Get the first dimension
+     * @return first dimension
+     */
+    public int getDimension1() {
+        return dimension1;
+    }
+
+    /**
+     * Get the second dimension
+     * @return second dimension
+     */
+    public int getDimension2() {
+        return dimension2;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/DuplicateSampleAbscissaException.java b/src/main/java/org/apache/commons/math/DuplicateSampleAbscissaException.java
new file mode 100644
index 0000000..125be75
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/DuplicateSampleAbscissaException.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception thrown when a sample contains several entries at the same abscissa.
+ *
+ * @since 1.2
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class DuplicateSampleAbscissaException extends MathException  {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -2271007547170169872L;
+
+    /**
+     * Construct an exception indicating the duplicate abscissa.
+     * @param abscissa duplicate abscissa
+     * @param i1 index of one entry having the duplicate abscissa
+     * @param i2 index of another entry having the duplicate abscissa
+     */
+    public DuplicateSampleAbscissaException(double abscissa, int i1, int i2) {
+        super(LocalizedFormats.DUPLICATED_ABSCISSA,
+              abscissa, i1, i2);
+    }
+
+    /**
+     * Get the duplicate abscissa.
+     * @return duplicate abscissa
+     */
+    public double getDuplicateAbscissa() {
+        return ((Double) getArguments()[0]).doubleValue();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/Field.java b/src/main/java/org/apache/commons/math/Field.java
new file mode 100644
index 0000000..7e69a8d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/Field.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/**
+ * Interface representing a <a href="http://mathworld.wolfram.com/Field.html">field</a>.
+ * <p>
+ * Classes implementing this interface will often be singletons.
+ * </p>
+ * @param <T> the type of the field elements
+ * @see FieldElement
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface Field<T> {
+
+    /** Get the additive identity of the field.
+     * <p>
+     * The additive identity is the element e<sub>0</sub> of the field such that
+     * for all elements a of the field, the equalities a + e<sub>0</sub> =
+     * e<sub>0</sub> + a = a hold.
+     * </p>
+     * @return additive identity of the field
+     */
+    T getZero();
+
+    /** Get the multiplicative identity of the field.
+     * <p>
+     * The multiplicative identity is the element e<sub>1</sub> of the field such that
+     * for all elements a of the field, the equalities a &times; e<sub>1</sub> =
+     * e<sub>1</sub> &times; a = a hold.
+     * </p>
+     * @return multiplicative identity of the field
+     */
+    T getOne();
+
+}
diff --git a/src/main/java/org/apache/commons/math/FieldElement.java b/src/main/java/org/apache/commons/math/FieldElement.java
new file mode 100644
index 0000000..29757d4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/FieldElement.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+
+/**
+ * Interface representing <a href="http://mathworld.wolfram.com/Field.html">field</a> elements.
+ * @param <T> the type of the field elements
+ * @see Field
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface FieldElement<T> {
+
+    /** Compute this + a.
+     * @param a element to add
+     * @return a new element representing this + a
+     */
+    T add(T a);
+
+    /** Compute this - a.
+     * @param a element to subtract
+     * @return a new element representing this - a
+     */
+    T subtract(T a);
+
+    /** Compute this &times; a.
+     * @param a element to multiply
+     * @return a new element representing this &times; a
+     */
+    T multiply(T a);
+
+    /** Compute this &divide; a.
+     * @param a element to add
+     * @return a new element representing this &divide; a
+     * @exception ArithmeticException if a is the zero of the
+     * additive operation (i.e. additive identity)
+     */
+    T divide(T a) throws ArithmeticException;
+
+    /** Get the {@link Field} to which the instance belongs.
+     * @return {@link Field} to which the instance belongs
+     */
+    Field<T> getField();
+
+}
diff --git a/src/main/java/org/apache/commons/math/FunctionEvaluationException.java b/src/main/java/org/apache/commons/math/FunctionEvaluationException.java
new file mode 100644
index 0000000..5d54d29
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/FunctionEvaluationException.java
@@ -0,0 +1,211 @@
+/*
+ * 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;
+
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.ArrayRealVector;
+
+/**
+ * Exception thrown when an error occurs evaluating a function.
+ * <p>
+ * Maintains an <code>argument</code> property holding the input value that
+ * caused the function evaluation to fail.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class FunctionEvaluationException extends MathException  {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 1384427981840836868L;
+
+    /** Argument causing function evaluation failure */
+    private double[] argument;
+
+    /**
+     * Construct an exception indicating the argument value
+     * that caused the function evaluation to fail.
+     *
+     * @param argument  the failing function argument
+     */
+    public FunctionEvaluationException(double argument) {
+        super(LocalizedFormats.EVALUATION_FAILED, argument);
+        this.argument = new double[] { argument };
+    }
+
+    /**
+     * Construct an exception indicating the argument value
+     * that caused the function evaluation to fail.
+     *
+     * @param argument  the failing function argument
+     * @since 2.0
+     */
+    public FunctionEvaluationException(double[] argument) {
+        super(LocalizedFormats.EVALUATION_FAILED, new ArrayRealVector(argument));
+        this.argument = argument.clone();
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     */
+    public FunctionEvaluationException(double argument,
+                                       String pattern, Object ... arguments) {
+        this(argument, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public FunctionEvaluationException(double argument,
+                                       Localizable pattern, Object ... arguments) {
+        super(pattern, arguments);
+        this.argument = new double[] { argument };
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.0
+     */
+    public FunctionEvaluationException(double[] argument,
+                                       String pattern, Object ... arguments) {
+        this(argument, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public FunctionEvaluationException(double[] argument,
+                                       Localizable pattern, Object ... arguments) {
+        super(pattern, arguments);
+        this.argument = argument.clone();
+    }
+
+    /**
+     * Constructs an exception with specified root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param argument  the failing function argument
+     * @since 1.2
+     */
+    public FunctionEvaluationException(Throwable cause, double argument) {
+        super(cause);
+        this.argument = new double[] { argument };
+    }
+
+    /**
+     * Constructs an exception with specified root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param argument  the failing function argument
+     * @since 2.0
+     */
+    public FunctionEvaluationException(Throwable cause, double[] argument) {
+        super(cause);
+        this.argument = argument.clone();
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     */
+    public FunctionEvaluationException(Throwable cause,
+                                       double argument, String pattern,
+                                       Object ... arguments) {
+        this(cause, argument, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public FunctionEvaluationException(Throwable cause,
+                                       double argument, Localizable pattern,
+                                       Object ... arguments) {
+        super(cause, pattern, arguments);
+        this.argument = new double[] { argument };
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.0
+     */
+    public FunctionEvaluationException(Throwable cause,
+                                       double[] argument, String pattern,
+                                       Object ... arguments) {
+        this(cause, argument, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param argument  the failing function argument
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public FunctionEvaluationException(Throwable cause,
+                                       double[] argument, Localizable pattern,
+                                       Object ... arguments) {
+        super(cause, pattern, arguments);
+        this.argument = argument.clone();
+    }
+
+    /**
+     * Returns the function argument that caused this exception.
+     *
+     * @return  argument that caused function evaluation to fail
+     */
+    public double[] getArgument() {
+        return argument.clone();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/MathConfigurationException.java b/src/main/java/org/apache/commons/math/MathConfigurationException.java
new file mode 100644
index 0000000..52a5b3e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/MathConfigurationException.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Signals a configuration problem with any of the factory methods.
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class MathConfigurationException extends MathException implements Serializable{
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 5261476508226103366L;
+
+    /**
+     * Default constructor.
+     */
+    public MathConfigurationException() {
+        super();
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     */
+    public MathConfigurationException(String pattern, Object ... arguments) {
+        this(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MathConfigurationException(Localizable pattern, Object ... arguments) {
+        super(pattern, arguments);
+    }
+
+    /**
+     * Create an exception with a given root cause.
+     * @param cause  the exception or error that caused this exception to be thrown
+     */
+    public MathConfigurationException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     */
+    public MathConfigurationException(Throwable cause, String pattern, Object ... arguments) {
+        this(cause, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message and root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param cause  the exception or error that caused this exception to be thrown
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MathConfigurationException(Throwable cause, Localizable pattern, Object ... arguments) {
+        super(cause, pattern, arguments);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/MathException.java b/src/main/java/org/apache/commons/math/MathException.java
new file mode 100644
index 0000000..5f1a566
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/MathException.java
@@ -0,0 +1,217 @@
+/*
+ * 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;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+import java.util.Locale;
+
+import org.apache.commons.math.exception.MathThrowable;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+
+/**
+ * Base class for commons-math checked exceptions.
+ * <p>
+ * Supports nesting, emulating JDK 1.4 behavior if necessary.</p>
+ * <p>
+ * Adapted from <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/FunctorException.html"/>.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class MathException extends Exception implements MathThrowable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 7428019509644517071L;
+
+    /**
+     * Pattern used to build the message.
+     */
+    private final Localizable pattern;
+
+    /**
+     * Arguments used to build the message.
+     */
+    private final Object[] arguments;
+
+    /**
+     * Constructs a new <code>MathException</code> with no
+     * detail message.
+     */
+    public MathException() {
+        this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
+        this.arguments = new Object[] { "" };
+    }
+
+    /**
+     * Constructs a new <code>MathException</code> with specified
+     * formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @deprecated as of 2.2 replaced by {@link #MathException(Localizable, Object...)}
+     */
+    @Deprecated
+    public MathException(String pattern, Object ... arguments) {
+      this(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>MathException</code> with specified
+     * formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MathException(Localizable pattern, Object ... arguments) {
+      this.pattern   = pattern;
+      this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
+    }
+
+    /**
+     * Constructs a new <code>MathException</code> with specified
+     * nested <code>Throwable</code> root cause.
+     *
+     * @param rootCause  the exception or error that caused this exception
+     *                   to be thrown.
+     */
+    public MathException(Throwable rootCause) {
+        super(rootCause);
+        this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
+        this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() };
+    }
+
+    /**
+     * Constructs a new <code>MathException</code> with specified
+     * formatted detail message and nested <code>Throwable</code> root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param rootCause the exception or error that caused this exception
+     * to be thrown.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 1.2
+     * @deprecated as of 2.2 replaced by {@link #MathException(Throwable, Localizable, Object...)}
+     */
+    @Deprecated
+    public MathException(Throwable rootCause, String pattern, Object ... arguments) {
+        this(rootCause, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>MathException</code> with specified
+     * formatted detail message and nested <code>Throwable</code> root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param rootCause the exception or error that caused this exception
+     * to be thrown.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MathException(Throwable rootCause, Localizable pattern, Object ... arguments) {
+      super(rootCause);
+      this.pattern   = pattern;
+      this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
+    }
+
+    /** Gets the pattern used to build the message of this throwable.
+     *
+     * @return the pattern used to build the message of this throwable
+     * @since 1.2
+     * @deprecated as of 2.2 replaced by {@link #getSpecificPattern()} and {@link #getGeneralPattern()}
+     */
+    @Deprecated
+    public String getPattern() {
+        return pattern.getSourceString();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 2.2
+     */
+    public Localizable getSpecificPattern() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 2.2
+     */
+    public Localizable getGeneralPattern() {
+        return pattern;
+    }
+
+    /** {@inheritDoc} */
+    public Object[] getArguments() {
+        return arguments.clone();
+    }
+
+    /** Gets the message in a specified locale.
+     *
+     * @param locale Locale in which the message should be translated
+     *
+     * @return localized message
+     * @since 1.2
+     */
+    public String getMessage(final Locale locale) {
+        if (pattern != null) {
+            return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments);
+        }
+        return "";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getMessage() {
+        return getMessage(Locale.US);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getLocalizedMessage() {
+        return getMessage(Locale.getDefault());
+    }
+
+    /**
+     * Prints the stack trace of this exception to the standard error stream.
+     */
+    @Override
+    public void printStackTrace() {
+        printStackTrace(System.err);
+    }
+
+    /**
+     * Prints the stack trace of this exception to the specified stream.
+     *
+     * @param out  the <code>PrintStream</code> to use for output
+     */
+    @Override
+    public void printStackTrace(PrintStream out) {
+        synchronized (out) {
+            PrintWriter pw = new PrintWriter(out, false);
+            printStackTrace(pw);
+            // Flush the PrintWriter before it's GC'ed.
+            pw.flush();
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/MathRuntimeException.java b/src/main/java/org/apache/commons/math/MathRuntimeException.java
new file mode 100644
index 0000000..3b9b89c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/MathRuntimeException.java
@@ -0,0 +1,717 @@
+/*
+ * 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;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.util.ConcurrentModificationException;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.math.exception.MathThrowable;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+* Base class for commons-math unchecked exceptions.
+*
+* @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+* @since 2.0
+*/
+public class MathRuntimeException extends RuntimeException implements MathThrowable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 9058794795027570002L;
+
+    /**
+     * Pattern used to build the message.
+     */
+    private final Localizable pattern;
+
+    /**
+     * Arguments used to build the message.
+     */
+    private final Object[] arguments;
+
+    /**
+     * Constructs a new <code>MathRuntimeException</code> with specified
+     * formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @deprecated as of 2.2 replaced by {@link #MathRuntimeException(Localizable, Object...)}
+     */
+    @Deprecated
+    public MathRuntimeException(final String pattern, final Object ... arguments) {
+        this(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>MathRuntimeException</code> with specified
+     * formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MathRuntimeException(final Localizable pattern, final Object ... arguments) {
+        this.pattern   = pattern;
+        this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
+    }
+
+    /**
+     * Constructs a new <code>MathRuntimeException</code> with specified
+     * nested <code>Throwable</code> root cause.
+     *
+     * @param rootCause  the exception or error that caused this exception
+     *                   to be thrown.
+     */
+    public MathRuntimeException(final Throwable rootCause) {
+        super(rootCause);
+        this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
+        this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() };
+    }
+
+    /**
+     * Constructs a new <code>MathRuntimeException</code> with specified
+     * formatted detail message and nested <code>Throwable</code> root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param rootCause the exception or error that caused this exception
+     * to be thrown.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @deprecated as of 2.2 replaced by {@link #MathRuntimeException(Throwable, Localizable, Object...)}
+     */
+    @Deprecated
+    public MathRuntimeException(final Throwable rootCause,
+                                final String pattern, final Object ... arguments) {
+        this(rootCause, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>MathRuntimeException</code> with specified
+     * formatted detail message and nested <code>Throwable</code> root cause.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param rootCause the exception or error that caused this exception
+     * to be thrown.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MathRuntimeException(final Throwable rootCause,
+                                final Localizable pattern, final Object ... arguments) {
+        super(rootCause);
+        this.pattern   = pattern;
+        this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
+    }
+
+    /**
+     * Builds a message string by from a pattern and its arguments.
+     * @param locale Locale in which the message should be translated
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return a message string
+     * @since 2.2
+     */
+    private static String buildMessage(final Locale locale, final Localizable pattern,
+                                       final Object ... arguments) {
+        return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments);
+    }
+
+    /** Gets the pattern used to build the message of this throwable.
+    *
+    * @return the pattern used to build the message of this throwable
+    * @deprecated as of 2.2 replaced by {@link #getSpecificPattern()} and {@link #getGeneralPattern()}
+    */
+    @Deprecated
+    public String getPattern() {
+        return pattern.getSourceString();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 2.2
+     */
+    public Localizable getSpecificPattern() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 2.2
+     */
+    public Localizable getGeneralPattern() {
+        return pattern;
+    }
+
+    /** {@inheritDoc} */
+    public Object[] getArguments() {
+        return arguments.clone();
+    }
+
+    /** Gets the message in a specified locale.
+     *
+     * @param locale Locale in which the message should be translated
+     *
+     * @return localized message
+     */
+    public String getMessage(final Locale locale) {
+        if (pattern != null) {
+            return buildMessage(locale, pattern, arguments);
+        }
+        return "";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getMessage() {
+        return getMessage(Locale.US);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getLocalizedMessage() {
+        return getMessage(Locale.getDefault());
+    }
+
+    /**
+     * Prints the stack trace of this exception to the standard error stream.
+     */
+    @Override
+    public void printStackTrace() {
+        printStackTrace(System.err);
+    }
+
+    /**
+     * Prints the stack trace of this exception to the specified stream.
+     *
+     * @param out  the <code>PrintStream</code> to use for output
+     */
+    @Override
+    public void printStackTrace(final PrintStream out) {
+        synchronized (out) {
+            PrintWriter pw = new PrintWriter(out, false);
+            printStackTrace(pw);
+            // Flush the PrintWriter before it's GC'ed.
+            pw.flush();
+        }
+    }
+
+    /**
+     * Constructs a new <code>ArithmeticException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createArithmeticException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static ArithmeticException createArithmeticException(final String pattern,
+                                                                final Object ... arguments) {
+        return createArithmeticException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>ArithmeticException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static ArithmeticException createArithmeticException(final Localizable pattern,
+                                                                final Object ... arguments) {
+        return new ArithmeticException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 5305498554076846637L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>ArrayIndexOutOfBoundsException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createArrayIndexOutOfBoundsException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static ArrayIndexOutOfBoundsException createArrayIndexOutOfBoundsException(final String pattern,
+                                                                                      final Object ... arguments) {
+        return createArrayIndexOutOfBoundsException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>ArrayIndexOutOfBoundsException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static ArrayIndexOutOfBoundsException createArrayIndexOutOfBoundsException(final Localizable pattern,
+                                                                                      final Object ... arguments) {
+        return new ArrayIndexOutOfBoundsException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 6718518191249632175L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>EOFException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createEOFException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static EOFException createEOFException(final String pattern,
+                                                  final Object ... arguments) {
+        return createEOFException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>EOFException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static EOFException createEOFException(final Localizable pattern,
+                                                  final Object ... arguments) {
+        return new EOFException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 6067985859347601503L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>IOException</code> with specified nested
+     * <code>Throwable</code> root cause.
+     * <p>This factory method allows chaining of other exceptions within an
+     * <code>IOException</code> even for Java 5. The constructor for
+     * <code>IOException</code> with a cause parameter was introduced only
+     * with Java 6.</p>
+     * @param rootCause the exception or error that caused this exception
+     * to be thrown.
+     * @return built exception
+     */
+    public static IOException createIOException(final Throwable rootCause) {
+        IOException ioe = new IOException(rootCause.getLocalizedMessage());
+        ioe.initCause(rootCause);
+        return ioe;
+    }
+
+    /**
+     * Constructs a new <code>IllegalArgumentException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createIllegalArgumentException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static IllegalArgumentException createIllegalArgumentException(final String pattern,
+                                                                          final Object ... arguments) {
+        return createIllegalArgumentException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>IllegalArgumentException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static IllegalArgumentException createIllegalArgumentException(final Localizable pattern,
+                                                                          final Object ... arguments) {
+        return new IllegalArgumentException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = -4284649691002411505L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>IllegalArgumentException</code> with specified nested
+     * <code>Throwable</code> root cause.
+     * @param rootCause the exception or error that caused this exception
+     * to be thrown.
+     * @return built exception
+     */
+    public static IllegalArgumentException createIllegalArgumentException(final Throwable rootCause) {
+        IllegalArgumentException iae = new IllegalArgumentException(rootCause.getLocalizedMessage());
+        iae.initCause(rootCause);
+        return iae;
+    }
+
+    /**
+     * Constructs a new <code>IllegalStateException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createIllegalStateException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static IllegalStateException createIllegalStateException(final String pattern,
+                                                                    final Object ... arguments) {
+        return createIllegalStateException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>IllegalStateException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static IllegalStateException createIllegalStateException(final Localizable pattern,
+                                                                    final Object ... arguments) {
+        return new IllegalStateException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 6880901520234515725L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>ConcurrentModificationException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createConcurrentModificationException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static ConcurrentModificationException createConcurrentModificationException(final String pattern,
+                                                                                        final Object ... arguments) {
+        return createConcurrentModificationException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>ConcurrentModificationException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static ConcurrentModificationException createConcurrentModificationException(final Localizable pattern,
+                                                                                        final Object ... arguments) {
+        return new ConcurrentModificationException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = -1878427236170442052L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>NoSuchElementException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createNoSuchElementException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static NoSuchElementException createNoSuchElementException(final String pattern,
+                                                                      final Object ... arguments) {
+        return createNoSuchElementException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>NoSuchElementException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static NoSuchElementException createNoSuchElementException(final Localizable pattern,
+                                                                      final Object ... arguments) {
+        return new NoSuchElementException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 1632410088350355086L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>UnsupportedOperationException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     * @deprecated in 2.2. Please use {@link org.apache.commons.math.exception.MathUnsupportedOperationException}
+     * instead.
+     */
+    @Deprecated
+    public static UnsupportedOperationException createUnsupportedOperationException(final Localizable pattern,
+                                                                                    final Object ... arguments) {
+        return new UnsupportedOperationException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = -4284649691002411505L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /**
+     * Constructs a new <code>NullPointerException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createNullPointerException(Localizable, Object...)}
+     */
+    @Deprecated
+    public static NullPointerException createNullPointerException(final String pattern,
+                                                                  final Object ... arguments) {
+        return createNullPointerException(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>NullPointerException</code> with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     * @deprecated in 2.2. Checks for "null" must not be performed in Commons-Math.
+     */
+    @Deprecated
+    public static NullPointerException createNullPointerException(final Localizable pattern,
+                                                                  final Object ... arguments) {
+        return new NullPointerException() {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 451965530686593945L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+   /**
+     * Constructs a new <code>ParseException</code> with specified
+     * formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param offset offset at which error occurred
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @deprecated as of 2.2 replaced by {@link #createParseException(int, Localizable, Object...)}
+     */
+    @Deprecated
+    public static ParseException createParseException(final int offset,
+                                                      final String pattern,
+                                                      final Object ... arguments) {
+        return createParseException(offset, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new <code>ParseException</code> with specified
+     * formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param offset offset at which error occurred
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @return built exception
+     * @since 2.2
+     */
+    public static ParseException createParseException(final int offset,
+                                                      final Localizable pattern,
+                                                      final Object ... arguments) {
+        return new ParseException(null, offset) {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = 8153587599409010120L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, pattern, arguments);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), pattern, arguments);
+            }
+
+        };
+    }
+
+    /** Create an {@link java.lang.RuntimeException} for an internal error.
+     * @param cause underlying cause
+     * @return an {@link java.lang.RuntimeException} for an internal error
+     */
+    public static RuntimeException createInternalError(final Throwable cause) {
+
+        final String argument = "https://issues.apache.org/jira/browse/MATH";
+
+        return new RuntimeException(cause) {
+
+            /** Serializable version identifier. */
+            private static final long serialVersionUID = -201865440834027016L;
+
+            /** {@inheritDoc} */
+            @Override
+            public String getMessage() {
+                return buildMessage(Locale.US, LocalizedFormats.INTERNAL_ERROR, argument);
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public String getLocalizedMessage() {
+                return buildMessage(Locale.getDefault(), LocalizedFormats.INTERNAL_ERROR, argument);
+            }
+
+        };
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/MaxEvaluationsExceededException.java b/src/main/java/org/apache/commons/math/MaxEvaluationsExceededException.java
new file mode 100644
index 0000000..06730bc
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/MaxEvaluationsExceededException.java
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when a numerical computation exceeds its allowed
+ * number of functions evaluations.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class MaxEvaluationsExceededException extends ConvergenceException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -5921271447220129118L;
+
+    /** Maximal number of evaluations allowed. */
+    private final int maxEvaluations;
+
+    /**
+     * Constructs an exception with a default detail message.
+     * @param maxEvaluations maximal number of evaluations allowed
+     */
+    public MaxEvaluationsExceededException(final int maxEvaluations) {
+        super(LocalizedFormats.MAX_EVALUATIONS_EXCEEDED, maxEvaluations);
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param maxEvaluations the exceeded maximal number of evaluations
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @deprecated as of 2.2 replaced by {@link #MaxEvaluationsExceededException(int, Localizable, Object...)}
+     */
+    @Deprecated
+    public MaxEvaluationsExceededException(final int maxEvaluations,
+                                          final String pattern, final Object ... arguments) {
+        this(maxEvaluations, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param maxEvaluations the exceeded maximal number of evaluations
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MaxEvaluationsExceededException(final int maxEvaluations,
+                                           final Localizable pattern, final Object ... arguments) {
+        super(pattern, arguments);
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** Get the maximal number of evaluations allowed.
+     * @return maximal number of evaluations allowed
+     */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/MaxIterationsExceededException.java b/src/main/java/org/apache/commons/math/MaxIterationsExceededException.java
new file mode 100644
index 0000000..51b2cce
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/MaxIterationsExceededException.java
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when a numerical computation exceeds its allowed
+ * number of iterations.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class MaxIterationsExceededException extends ConvergenceException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -7821226672760574694L;
+
+    /** Maximal number of iterations allowed. */
+    private final int maxIterations;
+
+    /**
+     * Constructs an exception with a default detail message.
+     * @param maxIterations maximal number of iterations allowed
+     */
+    public MaxIterationsExceededException(final int maxIterations) {
+        super(LocalizedFormats.MAX_ITERATIONS_EXCEEDED, maxIterations);
+        this.maxIterations = maxIterations;
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param maxIterations the exceeded maximal number of iterations
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @deprecated as of 2.2 replaced by {@link #MaxIterationsExceededException(int, Localizable, Object...)}
+     */
+    @Deprecated
+    public MaxIterationsExceededException(final int maxIterations,
+                                          final String pattern, final Object ... arguments) {
+        this(maxIterations, new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param maxIterations the exceeded maximal number of iterations
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MaxIterationsExceededException(final int maxIterations,
+                                           final Localizable pattern, final Object ... arguments) {
+        super(pattern, arguments);
+        this.maxIterations = maxIterations;
+    }
+
+    /** Get the maximal number of iterations allowed.
+     * @return maximal number of iterations allowed
+     */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java b/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
new file mode 100644
index 0000000..227b72e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
@@ -0,0 +1,120 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.util.FastMath;
+
+
+
+/**
+ * Base class for {@link BivariateRealFunction} that can be composed with other functions.
+ *
+ * @since 2.1
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ * @deprecated in 2.2
+ */
+@Deprecated
+public abstract class BinaryFunction implements BivariateRealFunction {
+
+    /** The + operator method wrapped as a {@link BinaryFunction}. */
+    public static final BinaryFunction ADD = new BinaryFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double x, double y) {
+            return x + y;
+        }
+    };
+
+    /** The - operator method wrapped as a {@link BinaryFunction}. */
+    public static final BinaryFunction SUBTRACT = new BinaryFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double x, double y) {
+            return x - y;
+        }
+    };
+
+    /** The * operator method wrapped as a {@link BinaryFunction}. */
+    public static final BinaryFunction MULTIPLY = new BinaryFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double x, double y) {
+            return x * y;
+        }
+    };
+
+    /** The / operator method wrapped as a {@link BinaryFunction}. */
+    public static final BinaryFunction DIVIDE = new BinaryFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double x, double y) {
+            return x / y;
+        }
+    };
+
+    /** The {@code FastMath.pow} method wrapped as a {@link BinaryFunction}. */
+    public static final BinaryFunction POW = new BinaryFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double x, double y) {
+            return FastMath.pow(x, y);
+        }
+    };
+
+    /** The {@code FastMath.atan2} method wrapped as a {@link BinaryFunction}. */
+    public static final BinaryFunction ATAN2 = new BinaryFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double x, double y) {
+            return FastMath.atan2(x, y);
+        }
+    };
+
+    /** {@inheritDoc} */
+    public abstract double value(double x, double y) throws FunctionEvaluationException;
+
+    /** Get a composable function by fixing the first argument of the instance.
+     * @param fixedX fixed value of the first argument
+     * @return a function such that {@code f.value(y) == value(fixedX, y)}
+     */
+    public ComposableFunction fix1stArgument(final double fixedX) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return BinaryFunction.this.value(fixedX, x);
+            }
+        };
+    }
+
+    /** Get a composable function by fixing the second argument of the instance.
+     * @param fixedY fixed value of the second argument
+     * @return a function such that {@code f.value(x) == value(x, fixedY)}
+     */
+    public ComposableFunction fix2ndArgument(final double fixedY) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return BinaryFunction.this.value(x, fixedY);
+            }
+        };
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java b/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
new file mode 100644
index 0000000..4b12312
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
@@ -0,0 +1,40 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a bivariate real function.
+ *
+ * @since 2.1
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ */
+public interface BivariateRealFunction {
+    /**
+     * Compute the value for the function.
+     *
+     * @param x Abscissa for which the function value should be computed.
+     * @param y Ordinate for which the function value should be computed.
+     * @return the value.
+     * @throws FunctionEvaluationException if the function evaluation fails.
+     */
+    double value(double x, double y)
+        throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java b/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java
new file mode 100644
index 0000000..91c8132
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java
@@ -0,0 +1,506 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Base class for {@link UnivariateRealFunction} that can be composed with other functions.
+ *
+ * @since 2.1
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public abstract class ComposableFunction implements UnivariateRealFunction {
+
+    /** The constant function always returning 0. */
+    public static final ComposableFunction ZERO = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return 0;
+        }
+    };
+
+    /** The constant function always returning 1. */
+    public static final ComposableFunction ONE = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return 1;
+        }
+    };
+
+    /** The identity function. */
+    public static final ComposableFunction IDENTITY = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return d;
+        }
+    };
+
+    /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction ABS = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.abs(d);
+        }
+    };
+
+    /** The - operator wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction NEGATE = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return -d;
+        }
+    };
+
+    /** The invert operator wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction INVERT = new ComposableFunction () {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d){
+            return 1/d;
+        }
+    };
+
+    /** The {@code FastMath.sin} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction SIN = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.sin(d);
+        }
+    };
+
+    /** The {@code FastMath.sqrt} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction SQRT = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.sqrt(d);
+        }
+    };
+
+    /** The {@code FastMath.sinh} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction SINH = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.sinh(d);
+        }
+    };
+
+    /** The {@code FastMath.exp} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction EXP = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.exp(d);
+        }
+    };
+
+    /** The {@code FastMath.expm1} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction EXPM1 = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.expm1(d);
+        }
+    };
+
+    /** The {@code FastMath.asin} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction ASIN = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.asin(d);
+        }
+    };
+
+    /** The {@code FastMath.atan} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction ATAN = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.atan(d);
+        }
+    };
+
+    /** The {@code FastMath.tan} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction TAN = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.tan(d);
+        }
+    };
+
+    /** The {@code FastMath.tanh} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction TANH = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.tanh(d);
+        }
+    };
+
+    /** The {@code FastMath.cbrt} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction CBRT = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.cbrt(d);
+        }
+    };
+
+    /** The {@code FastMath.ceil} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction CEIL = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.ceil(d);
+        }
+    };
+
+    /** The {@code FastMath.floor} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction FLOOR = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.floor(d);
+        }
+    };
+
+    /** The {@code FastMath.log} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction LOG = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.log(d);
+        }
+    };
+
+    /** The {@code FastMath.log10} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction LOG10 = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.log10(d);
+        }
+    };
+
+    /** The {@code FastMath.log1p} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction LOG1P = new ComposableFunction () {
+        @Override
+        public double value(double d){
+            return FastMath.log1p(d);
+        }
+    };
+
+    /** The {@code FastMath.cos} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction COS = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.cos(d);
+        }
+    };
+
+    /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction ACOS = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.acos(d);
+        }
+    };
+
+    /** The {@code FastMath.cosh} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction COSH = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.cosh(d);
+        }
+    };
+
+    /** The {@code FastMath.rint} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction RINT = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.rint(d);
+        }
+    };
+
+    /** The {@code FastMath.signum} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction SIGNUM = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.signum(d);
+        }
+    };
+
+    /** The {@code FastMath.ulp} method wrapped as a {@link ComposableFunction}. */
+    public static final ComposableFunction ULP = new ComposableFunction() {
+        /** {@inheritDoc} */
+        @Override
+        public double value(double d) {
+            return FastMath.ulp(d);
+        }
+    };
+
+    /** Precompose the instance with another function.
+     * <p>
+     * The composed function h created by {@code h = g.of(f)} is such
+     * that {@code h.value(x) == g.value(f.value(x))} for all x.
+     * </p>
+     * @param f function to compose with
+     * @return a new function which computes {@code this.value(f.value(x))}
+     * @see #postCompose(UnivariateRealFunction)
+     */
+    public ComposableFunction of(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(f.value(x));
+            }
+        };
+    }
+
+    /** Postcompose the instance with another function.
+     * <p>
+     * The composed function h created by {@code h = g.postCompose(f)} is such
+     * that {@code h.value(x) == f.value(g.value(x))} for all x.
+     * </p>
+     * @param f function to compose with
+     * @return a new function which computes {@code f.value(this.value(x))}
+     * @see #of(UnivariateRealFunction)
+     */
+    public ComposableFunction postCompose(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return f.value(ComposableFunction.this.value(x));
+            }
+        };
+    }
+
+    /**
+     * Return a function combining the instance and another function.
+     * <p>
+     * The function h created by {@code h = g.combine(f, combiner)} is such that
+     * {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x.
+     * </p>
+     * @param f function to combine with the instance
+     * @param combiner bivariate function used for combining
+     * @return a new function which computes {@code combine.value(this.value(x), f.value(x))}
+     */
+    public ComposableFunction combine(final UnivariateRealFunction f,
+                                      final BivariateRealFunction combiner) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return combiner.value(ComposableFunction.this.value(x), f.value(x));
+            }
+        };
+    }
+
+    /**
+     * Return a function adding the instance and another function.
+     * @param f function to combine with the instance
+     * @return a new function which computes {@code this.value(x) + f.value(x)}
+     */
+    public ComposableFunction add(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) + f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Return a function adding a constant term to the instance.
+     * @param a term to add
+     * @return a new function which computes {@code this.value(x) + a}
+     */
+    public ComposableFunction add(final double a) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) + a;
+            }
+        };
+    }
+
+    /**
+     * Return a function subtracting another function from the instance.
+     * @param f function to combine with the instance
+     * @return a new function which computes {@code this.value(x) - f.value(x)}
+     */
+    public ComposableFunction subtract(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) - f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Return a function multiplying the instance and another function.
+     * @param f function to combine with the instance
+     * @return a new function which computes {@code this.value(x) * f.value(x)}
+     */
+    public ComposableFunction multiply(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) * f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Return a function scaling the instance by a constant factor.
+     * @param scaleFactor constant scaling factor
+     * @return a new function which computes {@code this.value(x) * scaleFactor}
+     */
+    public ComposableFunction multiply(final double scaleFactor) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) * scaleFactor;
+            }
+        };
+    }
+    /**
+     * Return a function dividing the instance by another function.
+     * @param f function to combine with the instance
+     * @return a new function which computes {@code this.value(x) / f.value(x)}
+     */
+    public ComposableFunction divide(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {@inheritDoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) / f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * The generated function behaves as follows:
+     * <ul>
+     *   <li>initialize result = initialValue</li>
+     *   <li>iterate: {@code result = combiner.value(result,
+     *   this.value(nextMultivariateEntry));}</li>
+     *   <li>return result</li>
+     * </ul>
+     * </p>
+     * @param combiner combiner to use between entries
+     * @param initialValue initial value to use before first entry
+     * @return a new function that iteratively apply instance function on all
+     * elements of an array.
+     */
+    public MultivariateRealFunction asCollector(final BivariateRealFunction combiner,
+                                                final double initialValue) {
+        return new MultivariateRealFunction() {
+            /** {@inheritDoc} */
+            public double value(double[] point)
+                throws FunctionEvaluationException, IllegalArgumentException {
+                double result = initialValue;
+                for (final double entry : point) {
+                    result = combiner.value(result, ComposableFunction.this.value(entry));
+                }
+                return result;
+            }
+        };
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * Calling this method is equivalent to call {@link
+     * #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}.
+     * </p>
+     * @param combiner combiner to use between entries
+     * @return a new function that iteratively apply instance function on all
+     * elements of an array.
+     * @see #asCollector(BivariateRealFunction, double)
+     */
+    public  MultivariateRealFunction asCollector(final BivariateRealFunction combiner) {
+        return asCollector(combiner, 0.0);
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * Calling this method is equivalent to call {@link
+     * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}.
+     * </p>
+     * @param initialValue initial value to use before first entry
+     * @return a new function that iteratively apply instance function on all
+     * elements of an array.
+     * @see #asCollector(BivariateRealFunction, double)
+     * @see BinaryFunction#ADD
+     */
+    public  MultivariateRealFunction asCollector(final double initialValue) {
+        return asCollector(BinaryFunction.ADD, initialValue);
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * Calling this method is equivalent to call {@link
+     * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}.
+     * </p>
+     * @return a new function that iteratively apply instance function on all
+     * elements of an array.
+     * @see #asCollector(BivariateRealFunction, double)
+     * @see BinaryFunction#ADD
+     */
+    public  MultivariateRealFunction asCollector() {
+        return asCollector(BinaryFunction.ADD, 0.0);
+    }
+
+    /** {@inheritDoc} */
+    public abstract double value(double x) throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateRealFunction.java b/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateRealFunction.java
new file mode 100644
index 0000000..8d4f0c9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateRealFunction.java
@@ -0,0 +1,51 @@
+/*
+ * 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.analysis;
+
+/**
+ * Extension of {@link MultivariateRealFunction} representing a differentiable
+ * multivariate real function.
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface DifferentiableMultivariateRealFunction extends MultivariateRealFunction {
+
+    /**
+     * Returns the partial derivative of the function with respect to a point coordinate.
+     * <p>
+     * The partial derivative is defined with respect to point coordinate
+     * x<sub>k</sub>. If the partial derivatives with respect to all coordinates are
+     * needed, it may be more efficient to use the {@link #gradient()} method which will
+     * compute them all at once.
+     * </p>
+     * @param k index of the coordinate with respect to which the partial
+     * derivative is computed
+     * @return the partial derivative function with respect to k<sup>th</sup> point coordinate
+     */
+    MultivariateRealFunction partialDerivative(int k);
+
+    /**
+     * Returns the gradient function.
+     * <p>If only one partial derivative with respect to a specific coordinate is
+     * needed, it may be more efficient to use the {@link #partialDerivative(int)} method
+     * which will compute only the specified component.</p>
+     * @return the gradient function
+     */
+    MultivariateVectorialFunction gradient();
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateVectorialFunction.java b/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateVectorialFunction.java
new file mode 100644
index 0000000..cc4ab8e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/DifferentiableMultivariateVectorialFunction.java
@@ -0,0 +1,36 @@
+/*
+ * 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.analysis;
+
+
+/**
+ * Extension of {@link MultivariateVectorialFunction} representing a differentiable
+ * multivariate vectorial function.
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface DifferentiableMultivariateVectorialFunction
+    extends MultivariateVectorialFunction {
+
+    /**
+     * Returns the jacobian function.
+     * @return the jacobian function
+     */
+    MultivariateMatrixFunction jacobian();
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFunction.java b/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFunction.java
new file mode 100644
index 0000000..5f2f11b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFunction.java
@@ -0,0 +1,35 @@
+/*
+ * 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.analysis;
+
+/**
+ * Extension of {@link UnivariateMatrixFunction} representing a differentiable univariate matrix function.
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public interface DifferentiableUnivariateMatrixFunction
+    extends UnivariateMatrixFunction {
+
+    /**
+     * Returns the derivative of the function
+     *
+     * @return  the derivative function
+     */
+    UnivariateMatrixFunction derivative();
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunction.java b/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunction.java
new file mode 100644
index 0000000..1faaad3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunction.java
@@ -0,0 +1,34 @@
+/*
+ * 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.analysis;
+
+/**
+ * Extension of {@link UnivariateRealFunction} representing a differentiable univariate real function.
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ */
+public interface DifferentiableUnivariateRealFunction
+    extends UnivariateRealFunction {
+
+    /**
+     * Returns the derivative of the function
+     *
+     * @return  the derivative function
+     */
+    UnivariateRealFunction derivative();
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateVectorialFunction.java b/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateVectorialFunction.java
new file mode 100644
index 0000000..6566afe
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/DifferentiableUnivariateVectorialFunction.java
@@ -0,0 +1,35 @@
+/*
+ * 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.analysis;
+
+/**
+ * Extension of {@link UnivariateVectorialFunction} representing a differentiable univariate vectorial function.
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public interface DifferentiableUnivariateVectorialFunction
+    extends UnivariateVectorialFunction {
+
+    /**
+     * Returns the derivative of the function
+     *
+     * @return  the derivative function
+     */
+    UnivariateVectorialFunction derivative();
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/MultivariateMatrixFunction.java b/src/main/java/org/apache/commons/math/analysis/MultivariateMatrixFunction.java
new file mode 100644
index 0000000..a5bad26
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/MultivariateMatrixFunction.java
@@ -0,0 +1,40 @@
+/*
+ * 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.analysis;
+
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a multivariate matrix function.
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface MultivariateMatrixFunction {
+
+    /**
+     * Compute the value for the function at the given point.
+     * @param point point at which the function must be evaluated
+     * @return function value for the given point
+     * @exception FunctionEvaluationException if the function evaluation fails
+     * @exception IllegalArgumentException if points dimension is wrong
+     */
+    double[][] value(double[] point)
+        throws FunctionEvaluationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/MultivariateRealFunction.java b/src/main/java/org/apache/commons/math/analysis/MultivariateRealFunction.java
new file mode 100644
index 0000000..f054c51
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/MultivariateRealFunction.java
@@ -0,0 +1,39 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a multivariate real function.
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public interface MultivariateRealFunction {
+
+    /**
+     * Compute the value for the function at the given point.
+     * @param point point at which the function must be evaluated
+     * @return function value for the given point
+     * @exception FunctionEvaluationException if the function evaluation fails
+     * @exception IllegalArgumentException if points dimension is wrong
+     */
+    double value(double[] point)
+        throws FunctionEvaluationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/MultivariateVectorialFunction.java b/src/main/java/org/apache/commons/math/analysis/MultivariateVectorialFunction.java
new file mode 100644
index 0000000..7e83a7c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/MultivariateVectorialFunction.java
@@ -0,0 +1,39 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a multivariate vectorial function.
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public interface MultivariateVectorialFunction {
+
+    /**
+     * Compute the value for the function at the given point.
+     * @param point point at which the function must be evaluated
+     * @return function value for the given point
+     * @exception FunctionEvaluationException if the function evaluation fails
+     * @exception IllegalArgumentException if points dimension is wrong
+     */
+    double[] value(double[] point)
+        throws FunctionEvaluationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/TrivariateRealFunction.java b/src/main/java/org/apache/commons/math/analysis/TrivariateRealFunction.java
new file mode 100644
index 0000000..3ebf24d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/TrivariateRealFunction.java
@@ -0,0 +1,40 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a trivariate real function.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public interface TrivariateRealFunction {
+    /**
+     * Compute the value for the function.
+     *
+     * @param x x-coordinate for which the function value should be computed.
+     * @param y y-coordinate for which the function value should be computed.
+     * @param z z-coordinate for which the function value should be computed.
+     * @return the value.
+     * @throws FunctionEvaluationException if the function evaluation fails.
+     */
+    double value(double x, double y, double z)
+        throws FunctionEvaluationException;
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/UnivariateMatrixFunction.java b/src/main/java/org/apache/commons/math/analysis/UnivariateMatrixFunction.java
new file mode 100644
index 0000000..2db7349
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/UnivariateMatrixFunction.java
@@ -0,0 +1,37 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a univariate matrix function.
+ *
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+public interface UnivariateMatrixFunction {
+
+    /**
+     * Compute the value for the function.
+     * @param x the point for which the function value should be computed
+     * @return the value
+     * @throws FunctionEvaluationException if the function evaluation fails
+     */
+    double[][] value(double x) throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunction.java b/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunction.java
new file mode 100644
index 0000000..298d8a7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunction.java
@@ -0,0 +1,36 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a univariate real function.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public interface UnivariateRealFunction {
+
+    /**
+     * Compute the value for the function.
+     * @param x the point for which the function value should be computed
+     * @return the value
+     * @throws FunctionEvaluationException if the function evaluation fails
+     */
+    double value(double x) throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/UnivariateVectorialFunction.java b/src/main/java/org/apache/commons/math/analysis/UnivariateVectorialFunction.java
new file mode 100644
index 0000000..64e7e15
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/UnivariateVectorialFunction.java
@@ -0,0 +1,37 @@
+/*
+ * 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.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a univariate vectorial function.
+ *
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+public interface UnivariateVectorialFunction {
+
+    /**
+     * Compute the value for the function.
+     * @param x the point for which the function value should be computed
+     * @return the value
+     * @throws FunctionEvaluationException if the function evaluation fails
+     */
+    double[] value(double x) throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegrator.java b/src/main/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegrator.java
new file mode 100644
index 0000000..db6b76c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/LegendreGaussIntegrator.java
@@ -0,0 +1,236 @@
+/*
+ * 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.analysis.integration;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/Legendre-GaussQuadrature.html">
+ * Legendre-Gauss</a> quadrature formula.
+ * <p>
+ * Legendre-Gauss integrators are efficient integrators that can
+ * accurately integrate functions with few functions evaluations. A
+ * Legendre-Gauss integrator using an n-points quadrature formula can
+ * integrate exactly 2n-1 degree polynomials.
+ * </p>
+ * <p>
+ * These integrators evaluate the function on n carefully chosen
+ * abscissas in each step interval (mapped to the canonical [-1  1] interval).
+ * The evaluation abscissas are not evenly spaced and none of them are
+ * at the interval endpoints. This implies the function integrated can be
+ * undefined at integration interval endpoints.
+ * </p>
+ * <p>
+ * The evaluation abscissas x<sub>i</sub> are the roots of the degree n
+ * Legendre polynomial. The weights a<sub>i</sub> of the quadrature formula
+ * integrals from -1 to +1 &int; Li<sup>2</sup> where Li (x) =
+ * &prod; (x-x<sub>k</sub>)/(x<sub>i</sub>-x<sub>k</sub>) for k != i.
+ * </p>
+ * <p>
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+
+public class LegendreGaussIntegrator extends UnivariateRealIntegratorImpl {
+
+    /** Abscissas for the 2 points method. */
+    private static final double[] ABSCISSAS_2 = {
+        -1.0 / FastMath.sqrt(3.0),
+         1.0 / FastMath.sqrt(3.0)
+    };
+
+    /** Weights for the 2 points method. */
+    private static final double[] WEIGHTS_2 = {
+        1.0,
+        1.0
+    };
+
+    /** Abscissas for the 3 points method. */
+    private static final double[] ABSCISSAS_3 = {
+        -FastMath.sqrt(0.6),
+         0.0,
+         FastMath.sqrt(0.6)
+    };
+
+    /** Weights for the 3 points method. */
+    private static final double[] WEIGHTS_3 = {
+        5.0 / 9.0,
+        8.0 / 9.0,
+        5.0 / 9.0
+    };
+
+    /** Abscissas for the 4 points method. */
+    private static final double[] ABSCISSAS_4 = {
+        -FastMath.sqrt((15.0 + 2.0 * FastMath.sqrt(30.0)) / 35.0),
+        -FastMath.sqrt((15.0 - 2.0 * FastMath.sqrt(30.0)) / 35.0),
+         FastMath.sqrt((15.0 - 2.0 * FastMath.sqrt(30.0)) / 35.0),
+         FastMath.sqrt((15.0 + 2.0 * FastMath.sqrt(30.0)) / 35.0)
+    };
+
+    /** Weights for the 4 points method. */
+    private static final double[] WEIGHTS_4 = {
+        (90.0 - 5.0 * FastMath.sqrt(30.0)) / 180.0,
+        (90.0 + 5.0 * FastMath.sqrt(30.0)) / 180.0,
+        (90.0 + 5.0 * FastMath.sqrt(30.0)) / 180.0,
+        (90.0 - 5.0 * FastMath.sqrt(30.0)) / 180.0
+    };
+
+    /** Abscissas for the 5 points method. */
+    private static final double[] ABSCISSAS_5 = {
+        -FastMath.sqrt((35.0 + 2.0 * FastMath.sqrt(70.0)) / 63.0),
+        -FastMath.sqrt((35.0 - 2.0 * FastMath.sqrt(70.0)) / 63.0),
+         0.0,
+         FastMath.sqrt((35.0 - 2.0 * FastMath.sqrt(70.0)) / 63.0),
+         FastMath.sqrt((35.0 + 2.0 * FastMath.sqrt(70.0)) / 63.0)
+    };
+
+    /** Weights for the 5 points method. */
+    private static final double[] WEIGHTS_5 = {
+        (322.0 - 13.0 * FastMath.sqrt(70.0)) / 900.0,
+        (322.0 + 13.0 * FastMath.sqrt(70.0)) / 900.0,
+        128.0 / 225.0,
+        (322.0 + 13.0 * FastMath.sqrt(70.0)) / 900.0,
+        (322.0 - 13.0 * FastMath.sqrt(70.0)) / 900.0
+    };
+
+    /** Abscissas for the current method. */
+    private final double[] abscissas;
+
+    /** Weights for the current method. */
+    private final double[] weights;
+
+    /**
+     * Build a Legendre-Gauss integrator.
+     * @param n number of points desired (must be between 2 and 5 inclusive)
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @exception IllegalArgumentException if the number of points is not
+     * in the supported range
+     */
+    public LegendreGaussIntegrator(final int n, final int defaultMaximalIterationCount)
+        throws IllegalArgumentException {
+        super(defaultMaximalIterationCount);
+        switch(n) {
+        case 2 :
+            abscissas = ABSCISSAS_2;
+            weights   = WEIGHTS_2;
+            break;
+        case 3 :
+            abscissas = ABSCISSAS_3;
+            weights   = WEIGHTS_3;
+            break;
+        case 4 :
+            abscissas = ABSCISSAS_4;
+            weights   = WEIGHTS_4;
+            break;
+        case 5 :
+            abscissas = ABSCISSAS_5;
+            weights   = WEIGHTS_5;
+            break;
+        default :
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED,
+                    n, 2, 5);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double integrate(final double min, final double max)
+        throws ConvergenceException,  FunctionEvaluationException, IllegalArgumentException {
+        return integrate(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    public double integrate(final UnivariateRealFunction f, final double min, final double max)
+        throws ConvergenceException,  FunctionEvaluationException, IllegalArgumentException {
+
+        clearResult();
+        verifyInterval(min, max);
+        verifyIterationCount();
+
+        // compute first estimate with a single step
+        double oldt = stage(f, min, max, 1);
+
+        int n = 2;
+        for (int i = 0; i < maximalIterationCount; ++i) {
+
+            // improve integral with a larger number of steps
+            final double t = stage(f, min, max, n);
+
+            // estimate error
+            final double delta = FastMath.abs(t - oldt);
+            final double limit =
+                FastMath.max(absoluteAccuracy,
+                         relativeAccuracy * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5);
+
+            // check convergence
+            if ((i + 1 >= minimalIterationCount) && (delta <= limit)) {
+                setResult(t, i);
+                return result;
+            }
+
+            // prepare next iteration
+            double ratio = FastMath.min(4, FastMath.pow(delta / limit, 0.5 / abscissas.length));
+            n = FastMath.max((int) (ratio * n), n + 1);
+            oldt = t;
+
+        }
+
+        throw new MaxIterationsExceededException(maximalIterationCount);
+
+    }
+
+    /**
+     * Compute the n-th stage integral.
+     * @param f the integrand function
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n number of steps
+     * @return the value of n-th stage integral
+     * @throws FunctionEvaluationException if an error occurs evaluating the
+     * function
+     */
+    private double stage(final UnivariateRealFunction f,
+                         final double min, final double max, final int n)
+        throws FunctionEvaluationException {
+
+        // set up the step for the current stage
+        final double step     = (max - min) / n;
+        final double halfStep = step / 2.0;
+
+        // integrate over all elementary steps
+        double midPoint = min + halfStep;
+        double sum = 0.0;
+        for (int i = 0; i < n; ++i) {
+            for (int j = 0; j < abscissas.length; ++j) {
+                sum += weights[j] * f.value(midPoint + halfStep * abscissas[j]);
+            }
+            midPoint += step;
+        }
+
+        return halfStep * sum;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java b/src/main/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java
new file mode 100644
index 0000000..9650af5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java
@@ -0,0 +1,121 @@
+/*
+ * 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.analysis.integration;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/RombergIntegration.html">
+ * Romberg Algorithm</a> for integration of real univariate functions. For
+ * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
+ * chapter 3.
+ * <p>
+ * Romberg integration employs k successive refinements of the trapezoid
+ * rule to remove error terms less than order O(N^(-2k)). Simpson's rule
+ * is a special case of k = 2.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class RombergIntegrator extends UnivariateRealIntegratorImpl {
+
+    /**
+     * Construct an integrator for the given function.
+     *
+     * @param f function to integrate
+     * @deprecated as of 2.0 the integrand function is passed as an argument
+     * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
+     */
+    @Deprecated
+    public RombergIntegrator(UnivariateRealFunction f) {
+        super(f, 32);
+    }
+
+    /**
+     * Construct an integrator.
+     */
+    public RombergIntegrator() {
+        super(32);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double integrate(final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
+        return integrate(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    public double integrate(final UnivariateRealFunction f, final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
+
+        final int m = maximalIterationCount + 1;
+        double previousRow[] = new double[m];
+        double currentRow[]  = new double[m];
+
+        clearResult();
+        verifyInterval(min, max);
+        verifyIterationCount();
+
+        TrapezoidIntegrator qtrap = new TrapezoidIntegrator();
+        currentRow[0] = qtrap.stage(f, min, max, 0);
+        double olds = currentRow[0];
+        for (int i = 1; i <= maximalIterationCount; ++i) {
+
+            // switch rows
+            final double[] tmpRow = previousRow;
+            previousRow = currentRow;
+            currentRow = tmpRow;
+
+            currentRow[0] = qtrap.stage(f, min, max, i);
+            for (int j = 1; j <= i; j++) {
+                // Richardson extrapolation coefficient
+                final double r = (1L << (2 * j)) - 1;
+                final double tIJm1 = currentRow[j - 1];
+                currentRow[j] = tIJm1 + (tIJm1 - previousRow[j - 1]) / r;
+            }
+            final double s = currentRow[i];
+            if (i >= minimalIterationCount) {
+                final double delta  = FastMath.abs(s - olds);
+                final double rLimit = relativeAccuracy * (FastMath.abs(olds) + FastMath.abs(s)) * 0.5;
+                if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
+                    setResult(s, i);
+                    return result;
+                }
+            }
+            olds = s;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void verifyIterationCount() throws IllegalArgumentException {
+        super.verifyIterationCount();
+        // at most 32 bisection refinements due to higher order divider
+        if (maximalIterationCount > 32) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INVALID_ITERATIONS_LIMITS,
+                    0, 32);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java b/src/main/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java
new file mode 100644
index 0000000..045b54e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java
@@ -0,0 +1,112 @@
+/*
+ * 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.analysis.integration;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/SimpsonsRule.html">
+ * Simpson's Rule</a> for integration of real univariate functions. For
+ * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
+ * chapter 3.
+ * <p>
+ * This implementation employs basic trapezoid rule as building blocks to
+ * calculate the Simpson's rule of alternating 2/3 and 4/3.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class SimpsonIntegrator extends UnivariateRealIntegratorImpl {
+
+    /**
+     * Construct an integrator for the given function.
+     *
+     * @param f function to integrate
+     * @deprecated as of 2.0 the integrand function is passed as an argument
+     * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
+     */
+    @Deprecated
+    public SimpsonIntegrator(UnivariateRealFunction f) {
+        super(f, 64);
+    }
+
+    /**
+     * Construct an integrator.
+     */
+    public SimpsonIntegrator() {
+        super(64);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double integrate(final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
+        return integrate(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    public double integrate(final UnivariateRealFunction f, final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
+
+        clearResult();
+        verifyInterval(min, max);
+        verifyIterationCount();
+
+        TrapezoidIntegrator qtrap = new TrapezoidIntegrator();
+        if (minimalIterationCount == 1) {
+            final double s = (4 * qtrap.stage(f, min, max, 1) - qtrap.stage(f, min, max, 0)) / 3.0;
+            setResult(s, 1);
+            return result;
+        }
+        // Simpson's rule requires at least two trapezoid stages.
+        double olds = 0;
+        double oldt = qtrap.stage(f, min, max, 0);
+        for (int i = 1; i <= maximalIterationCount; ++i) {
+            final double t = qtrap.stage(f, min, max, i);
+            final double s = (4 * t - oldt) / 3.0;
+            if (i >= minimalIterationCount) {
+                final double delta = FastMath.abs(s - olds);
+                final double rLimit =
+                    relativeAccuracy * (FastMath.abs(olds) + FastMath.abs(s)) * 0.5;
+                if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
+                    setResult(s, i);
+                    return result;
+                }
+            }
+            olds = s;
+            oldt = t;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void verifyIterationCount() throws IllegalArgumentException {
+        super.verifyIterationCount();
+        // at most 64 bisection refinements
+        if (maximalIterationCount > 64) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INVALID_ITERATIONS_LIMITS,
+                    0, 64);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java b/src/main/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
new file mode 100644
index 0000000..88903f5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
@@ -0,0 +1,142 @@
+/*
+ * 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.analysis.integration;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/TrapezoidalRule.html">
+ * Trapezoidal Rule</a> for integration of real univariate functions. For
+ * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
+ * chapter 3.
+ * <p>
+ * The function should be integrable.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class TrapezoidIntegrator extends UnivariateRealIntegratorImpl {
+
+    /** Intermediate result. */
+    private double s;
+
+    /**
+     * Construct an integrator for the given function.
+     *
+     * @param f function to integrate
+     * @deprecated as of 2.0 the integrand function is passed as an argument
+     * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
+     */
+    @Deprecated
+    public TrapezoidIntegrator(UnivariateRealFunction f) {
+        super(f, 64);
+    }
+
+    /**
+     * Construct an integrator.
+     */
+    public TrapezoidIntegrator() {
+        super(64);
+    }
+
+    /**
+     * Compute the n-th stage integral of trapezoid rule. This function
+     * should only be called by API <code>integrate()</code> in the package.
+     * To save time it does not verify arguments - caller does.
+     * <p>
+     * The interval is divided equally into 2^n sections rather than an
+     * arbitrary m sections because this configuration can best utilize the
+     * alrealy computed values.</p>
+     *
+     * @param f the integrand function
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the stage of 1/2 refinement, n = 0 is no refinement
+     * @return the value of n-th stage integral
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     */
+    double stage(final UnivariateRealFunction f,
+                 final double min, final double max, final int n)
+        throws FunctionEvaluationException {
+
+        if (n == 0) {
+            s = 0.5 * (max - min) * (f.value(min) + f.value(max));
+            return s;
+        } else {
+            final long np = 1L << (n-1);           // number of new points in this stage
+            double sum = 0;
+            final double spacing = (max - min) / np; // spacing between adjacent new points
+            double x = min + 0.5 * spacing;    // the first new point
+            for (long i = 0; i < np; i++) {
+                sum += f.value(x);
+                x += spacing;
+            }
+            // add the new sum to previously calculated result
+            s = 0.5 * (s + sum * spacing);
+            return s;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double integrate(final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
+        return integrate(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    public double integrate(final UnivariateRealFunction f, final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
+
+        clearResult();
+        verifyInterval(min, max);
+        verifyIterationCount();
+
+        double oldt = stage(f, min, max, 0);
+        for (int i = 1; i <= maximalIterationCount; ++i) {
+            final double t = stage(f, min, max, i);
+            if (i >= minimalIterationCount) {
+                final double delta = FastMath.abs(t - oldt);
+                final double rLimit =
+                    relativeAccuracy * (FastMath.abs(oldt) + FastMath.abs(t)) * 0.5;
+                if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
+                    setResult(t, i);
+                    return result;
+                }
+            }
+            oldt = t;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void verifyIterationCount() throws IllegalArgumentException {
+        super.verifyIterationCount();
+        // at most 64 bisection refinements
+        if (maximalIterationCount > 64) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INVALID_ITERATIONS_LIMITS,
+                    0, 64);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java b/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java
new file mode 100644
index 0000000..184bb44
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java
@@ -0,0 +1,106 @@
+/*
+ * 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.analysis.integration;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.ConvergingAlgorithm;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+/**
+ * Interface for univariate real integration algorithms.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public interface UnivariateRealIntegrator extends ConvergingAlgorithm {
+
+   /**
+     * Set the lower limit for the number of iterations.
+     * <p>
+     * Minimal iteration is needed to avoid false early convergence, e.g.
+     * the sample points happen to be zeroes of the function. Users can
+     * use the default value or choose one that they see as appropriate.</p>
+     * <p>
+     * A <code>ConvergenceException</code> will be thrown if this number
+     * is not met.</p>
+     *
+     * @param count minimum number of iterations
+     */
+    void setMinimalIterationCount(int count);
+
+    /**
+     * Get the lower limit for the number of iterations.
+     *
+     * @return the actual lower limit
+     */
+    int getMinimalIterationCount();
+
+    /**
+     * Reset the lower limit for the number of iterations to the default.
+     * <p>
+     * The default value is supplied by the implementation.</p>
+     *
+     * @see #setMinimalIterationCount(int)
+     */
+    void resetMinimalIterationCount();
+
+    /**
+     * Integrate the function in the given interval.
+     *
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the value of integral
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the integrator detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the
+     * function
+     * @throws IllegalArgumentException if min > max or the endpoints do not
+     * satisfy the requirements specified by the integrator
+     * @deprecated replaced by {@link #integrate(UnivariateRealFunction, double, double)}
+     * since 2.0
+     */
+    @Deprecated
+    double integrate(double min, double max)
+        throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException;
+
+    /**
+     * Integrate the function in the given interval.
+     *
+     * @param f the integrand function
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the value of integral
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the integrator detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the endpoints do not
+     * satisfy the requirements specified by the integrator
+     */
+    double integrate(UnivariateRealFunction f, double min, double max)
+        throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException;
+
+    /**
+     * Get the result of the last run of the integrator.
+     *
+     * @return the last result
+     * @throws IllegalStateException if there is no result available, either
+     * because no result was yet computed or the last attempt failed
+     */
+    double getResult() throws IllegalStateException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java b/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
new file mode 100644
index 0000000..655a852
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
@@ -0,0 +1,183 @@
+/*
+ * 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.analysis.integration;
+
+import org.apache.commons.math.ConvergingAlgorithmImpl;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * Provide a default implementation for several generic functions.
+ *
+ * @version $Revision: 1072409 $ $Date: 2011-02-19 19:50:36 +0100 (sam. 19 févr. 2011) $
+ * @since 1.2
+ */
+public abstract class UnivariateRealIntegratorImpl
+    extends ConvergingAlgorithmImpl implements UnivariateRealIntegrator {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 6248808456637441533L;
+
+    /** minimum number of iterations */
+    protected int minimalIterationCount;
+
+    /** default minimum number of iterations */
+    protected int defaultMinimalIterationCount;
+
+    /** indicates whether an integral has been computed */
+    protected boolean resultComputed = false;
+
+    /** the last computed integral */
+    protected double result;
+
+    /**
+     * The integrand function.
+     *
+     * @deprecated as of 2.0 the integrand function is passed as an argument
+     * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
+     */
+    @Deprecated
+    protected UnivariateRealFunction f;
+
+    /**
+     * Construct an integrator with given iteration count and accuracy.
+     *
+     * @param f the integrand function
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @throws IllegalArgumentException if f is null or the iteration
+     * limits are not valid
+     * @deprecated as of 2.0 the integrand function is passed as an argument
+     * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
+     */
+    @Deprecated
+    protected UnivariateRealIntegratorImpl(final UnivariateRealFunction f,
+                                           final int defaultMaximalIterationCount)
+        throws IllegalArgumentException {
+        super(defaultMaximalIterationCount, 1.0e-15);
+        if (f == null) {
+            throw new NullArgumentException(LocalizedFormats.FUNCTION);
+        }
+
+        this.f = f;
+
+        // parameters that are problem specific
+        setRelativeAccuracy(1.0e-6);
+        this.defaultMinimalIterationCount = 3;
+        this.minimalIterationCount = defaultMinimalIterationCount;
+
+        verifyIterationCount();
+    }
+
+    /**
+     * Construct an integrator with given iteration count and accuracy.
+     *
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @throws IllegalArgumentException if f is null or the iteration
+     * limits are not valid
+     */
+    protected UnivariateRealIntegratorImpl(final int defaultMaximalIterationCount)
+        throws IllegalArgumentException {
+        super(defaultMaximalIterationCount, 1.0e-15);
+
+        // parameters that are problem specific
+        setRelativeAccuracy(1.0e-6);
+        this.defaultMinimalIterationCount = 3;
+        this.minimalIterationCount = defaultMinimalIterationCount;
+
+        verifyIterationCount();
+    }
+
+    /**
+     * Access the last computed integral.
+     *
+     * @return the last computed integral
+     * @throws IllegalStateException if no integral has been computed
+     */
+    public double getResult() throws IllegalStateException {
+        if (resultComputed) {
+            return result;
+        } else {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE);
+        }
+    }
+
+    /**
+     * Convenience function for implementations.
+     *
+     * @param newResult the result to set
+     * @param iterationCount the iteration count to set
+     */
+    protected final void setResult(double newResult, int iterationCount) {
+        this.result         = newResult;
+        this.iterationCount = iterationCount;
+        this.resultComputed = true;
+    }
+
+    /**
+     * Convenience function for implementations.
+     */
+    protected final void clearResult() {
+        this.iterationCount = 0;
+        this.resultComputed = false;
+    }
+
+    /** {@inheritDoc} */
+    public void setMinimalIterationCount(int count) {
+        minimalIterationCount = count;
+    }
+
+    /** {@inheritDoc} */
+    public int getMinimalIterationCount() {
+        return minimalIterationCount;
+    }
+
+    /** {@inheritDoc} */
+    public void resetMinimalIterationCount() {
+        minimalIterationCount = defaultMinimalIterationCount;
+    }
+
+    /**
+     * Verifies that the endpoints specify an interval.
+     *
+     * @param lower lower endpoint
+     * @param upper upper endpoint
+     * @throws IllegalArgumentException if not interval
+     */
+    protected void verifyInterval(double lower, double upper) throws
+        IllegalArgumentException {
+        if (lower >= upper) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
+                    lower, upper);
+        }
+    }
+
+    /**
+     * Verifies that the upper and lower limits of iterations are valid.
+     *
+     * @throws IllegalArgumentException if not valid
+     */
+    protected void verifyIterationCount() throws IllegalArgumentException {
+        if ((minimalIterationCount <= 0) || (maximalIterationCount <= minimalIterationCount)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INVALID_ITERATIONS_LIMITS,
+                    minimalIterationCount, maximalIterationCount);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/integration/package.html b/src/main/java/org/apache/commons/math/analysis/integration/package.html
new file mode 100644
index 0000000..5bbab0e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/integration/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+     Numerical integration (quadrature) algorithms for univariate real functions.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java b/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java
new file mode 100644
index 0000000..c786a4d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java
@@ -0,0 +1,558 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.exception.OutOfRangeException;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Function that implements the
+ * <a href="http://en.wikipedia.org/wiki/Bicubic_interpolation">
+ * bicubic spline interpolation</a>.
+ *
+ * @version $Revision$ $Date$
+ * @since 2.1
+ */
+public class BicubicSplineInterpolatingFunction
+    implements BivariateRealFunction {
+    /**
+     * Matrix to compute the spline coefficients from the function values
+     * and function derivatives values
+     */
+    private static final double[][] AINV = {
+        { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 },
+        { -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0 },
+        { 2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 },
+        { 0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0 },
+        { 0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0 },
+        { -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0 },
+        { 0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0 },
+        { 9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1 },
+        { -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1 },
+        { 2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0 },
+        { 0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0 },
+        { -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1 },
+        { 4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 }
+    };
+
+    /** Samples x-coordinates */
+    private final double[] xval;
+    /** Samples y-coordinates */
+    private final double[] yval;
+    /** Set of cubic splines patching the whole data grid */
+    private final BicubicSplineFunction[][] splines;
+    /**
+     * Partial derivatives
+     * The value of the first index determines the kind of derivatives:
+     * 0 = first partial derivatives wrt x
+     * 1 = first partial derivatives wrt y
+     * 2 = second partial derivatives wrt x
+     * 3 = second partial derivatives wrt y
+     * 4 = cross partial derivatives
+     */
+    private BivariateRealFunction[][][] partialDerivatives = null;
+
+    /**
+     * @param x Sample values of the x-coordinate, in increasing order.
+     * @param y Sample values of the y-coordinate, in increasing order.
+     * @param f Values of the function on every grid point.
+     * @param dFdX Values of the partial derivative of function with respect
+     * to x on every grid point.
+     * @param dFdY Values of the partial derivative of function with respect
+     * to y on every grid point.
+     * @param d2FdXdY Values of the cross partial derivative of function on
+     * every grid point.
+     * @throws DimensionMismatchException if the various arrays do not contain
+     * the expected number of elements.
+     * @throws org.apache.commons.math.exception.NonMonotonousSequenceException
+     * if {@code x} or {@code y} are not strictly increasing.
+     * @throws NoDataException if any of the arrays has zero length.
+     */
+    public BicubicSplineInterpolatingFunction(double[] x,
+                                              double[] y,
+                                              double[][] f,
+                                              double[][] dFdX,
+                                              double[][] dFdY,
+                                              double[][] d2FdXdY)
+        throws DimensionMismatchException {
+        final int xLen = x.length;
+        final int yLen = y.length;
+
+        if (xLen == 0 || yLen == 0 || f.length == 0 || f[0].length == 0) {
+            throw new NoDataException();
+        }
+        if (xLen != f.length) {
+            throw new DimensionMismatchException(xLen, f.length);
+        }
+        if (xLen != dFdX.length) {
+            throw new DimensionMismatchException(xLen, dFdX.length);
+        }
+        if (xLen != dFdY.length) {
+            throw new DimensionMismatchException(xLen, dFdY.length);
+        }
+        if (xLen != d2FdXdY.length) {
+            throw new DimensionMismatchException(xLen, d2FdXdY.length);
+        }
+
+        MathUtils.checkOrder(x);
+        MathUtils.checkOrder(y);
+
+        xval = x.clone();
+        yval = y.clone();
+
+        final int lastI = xLen - 1;
+        final int lastJ = yLen - 1;
+        splines = new BicubicSplineFunction[lastI][lastJ];
+
+        for (int i = 0; i < lastI; i++) {
+            if (f[i].length != yLen) {
+                throw new DimensionMismatchException(f[i].length, yLen);
+            }
+            if (dFdX[i].length != yLen) {
+                throw new DimensionMismatchException(dFdX[i].length, yLen);
+            }
+            if (dFdY[i].length != yLen) {
+                throw new DimensionMismatchException(dFdY[i].length, yLen);
+            }
+            if (d2FdXdY[i].length != yLen) {
+                throw new DimensionMismatchException(d2FdXdY[i].length, yLen);
+            }
+            final int ip1 = i + 1;
+            for (int j = 0; j < lastJ; j++) {
+                final int jp1 = j + 1;
+                final double[] beta = new double[] {
+                    f[i][j], f[ip1][j], f[i][jp1], f[ip1][jp1],
+                    dFdX[i][j], dFdX[ip1][j], dFdX[i][jp1], dFdX[ip1][jp1],
+                    dFdY[i][j], dFdY[ip1][j], dFdY[i][jp1], dFdY[ip1][jp1],
+                    d2FdXdY[i][j], d2FdXdY[ip1][j], d2FdXdY[i][jp1], d2FdXdY[ip1][jp1]
+                };
+
+                splines[i][j] = new BicubicSplineFunction(computeSplineCoefficients(beta));
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double value(double x, double y) {
+        final int i = searchIndex(x, xval);
+        if (i == -1) {
+            throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]);
+        }
+        final int j = searchIndex(y, yval);
+        if (j == -1) {
+            throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]);
+        }
+
+        final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]);
+        final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]);
+
+        return splines[i][j].value(xN, yN);
+    }
+
+    /**
+     * @param x x-coordinate.
+     * @param y y-coordinate.
+     * @return the value at point (x, y) of the first partial derivative with
+     * respect to x.
+     * @since 2.2
+     */
+    public double partialDerivativeX(double x, double y) {
+        return partialDerivative(0, x, y);
+    }
+    /**
+     * @param x x-coordinate.
+     * @param y y-coordinate.
+     * @return the value at point (x, y) of the first partial derivative with
+     * respect to y.
+     * @since 2.2
+     */
+    public double partialDerivativeY(double x, double y) {
+        return partialDerivative(1, x, y);
+    }
+    /**
+     * @param x x-coordinate.
+     * @param y y-coordinate.
+     * @return the value at point (x, y) of the second partial derivative with
+     * respect to x.
+     * @since 2.2
+     */
+    public double partialDerivativeXX(double x, double y) {
+        return partialDerivative(2, x, y);
+    }
+    /**
+     * @param x x-coordinate.
+     * @param y y-coordinate.
+     * @return the value at point (x, y) of the second partial derivative with
+     * respect to y.
+     * @since 2.2
+     */
+    public double partialDerivativeYY(double x, double y) {
+        return partialDerivative(3, x, y);
+    }
+    /**
+     * @param x x-coordinate.
+     * @param y y-coordinate.
+     * @return the value at point (x, y) of the second partial cross-derivative.
+     * @since 2.2
+     */
+    public double partialDerivativeXY(double x, double y) {
+        return partialDerivative(4, x, y);
+    }
+
+    /**
+     * @param which First index in {@link #partialDerivatives}.
+     * @param x x-coordinate.
+     * @param y y-coordinate.
+     * @return the value at point (x, y) of the selected partial derivative.
+     * @throws FunctionEvaluationException
+     */
+    private double partialDerivative(int which, double x, double y) {
+        if (partialDerivatives == null) {
+            computePartialDerivatives();
+        }
+
+        final int i = searchIndex(x, xval);
+        if (i == -1) {
+            throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]);
+        }
+        final int j = searchIndex(y, yval);
+        if (j == -1) {
+            throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]);
+        }
+
+        final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]);
+        final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]);
+
+        try {
+            return partialDerivatives[which][i][j].value(xN, yN);
+        } catch (FunctionEvaluationException fee) {
+            // this should never happen
+            throw new RuntimeException(fee);
+        }
+
+    }
+
+    /**
+     * Compute all partial derivatives.
+     */
+    private void computePartialDerivatives() {
+        final int lastI = xval.length - 1;
+        final int lastJ = yval.length - 1;
+        partialDerivatives = new BivariateRealFunction[5][lastI][lastJ];
+
+        for (int i = 0; i < lastI; i++) {
+            for (int j = 0; j < lastJ; j++) {
+                final BicubicSplineFunction f = splines[i][j];
+                partialDerivatives[0][i][j] = f.partialDerivativeX();
+                partialDerivatives[1][i][j] = f.partialDerivativeY();
+                partialDerivatives[2][i][j] = f.partialDerivativeXX();
+                partialDerivatives[3][i][j] = f.partialDerivativeYY();
+                partialDerivatives[4][i][j] = f.partialDerivativeXY();
+            }
+        }
+    }
+
+    /**
+     * @param c Coordinate.
+     * @param val Coordinate samples.
+     * @return the index in {@code val} corresponding to the interval
+     * containing {@code c}, or {@code -1} if {@code c} is out of the
+     * range defined by the end values of {@code val}.
+     */
+    private int searchIndex(double c, double[] val) {
+        if (c < val[0]) {
+            return -1;
+        }
+
+        final int max = val.length;
+        for (int i = 1; i < max; i++) {
+            if (c <= val[i]) {
+                return i - 1;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Compute the spline coefficients from the list of function values and
+     * function partial derivatives values at the four corners of a grid
+     * element. They must be specified in the following order:
+     * <ul>
+     *  <li>f(0,0)</li>
+     *  <li>f(1,0)</li>
+     *  <li>f(0,1)</li>
+     *  <li>f(1,1)</li>
+     *  <li>f<sub>x</sub>(0,0)</li>
+     *  <li>f<sub>x</sub>(1,0)</li>
+     *  <li>f<sub>x</sub>(0,1)</li>
+     *  <li>f<sub>x</sub>(1,1)</li>
+     *  <li>f<sub>y</sub>(0,0)</li>
+     *  <li>f<sub>y</sub>(1,0)</li>
+     *  <li>f<sub>y</sub>(0,1)</li>
+     *  <li>f<sub>y</sub>(1,1)</li>
+     *  <li>f<sub>xy</sub>(0,0)</li>
+     *  <li>f<sub>xy</sub>(1,0)</li>
+     *  <li>f<sub>xy</sub>(0,1)</li>
+     *  <li>f<sub>xy</sub>(1,1)</li>
+     * </ul>
+     * where the subscripts indicate the partial derivative with respect to
+     * the corresponding variable(s).
+     *
+     * @param beta List of function values and function partial derivatives
+     * values.
+     * @return the spline coefficients.
+     */
+    private double[] computeSplineCoefficients(double[] beta) {
+        final double[] a = new double[16];
+
+        for (int i = 0; i < 16; i++) {
+            double result = 0;
+            final double[] row = AINV[i];
+            for (int j = 0; j < 16; j++) {
+                result += row[j] * beta[j];
+            }
+            a[i] = result;
+        }
+
+        return a;
+    }
+}
+
+/**
+ * 2D-spline function.
+ *
+ * @version $Revision$ $Date$
+ */
+class BicubicSplineFunction
+    implements BivariateRealFunction {
+
+    /** Number of points. */
+    private static final short N = 4;
+
+    /** Coefficients */
+    private final double[][] a;
+
+    /** First partial derivative along x. */
+    private BivariateRealFunction partialDerivativeX;
+
+    /** First partial derivative along y. */
+    private BivariateRealFunction partialDerivativeY;
+
+    /** Second partial derivative along x. */
+    private BivariateRealFunction partialDerivativeXX;
+
+    /** Second partial derivative along y. */
+    private BivariateRealFunction partialDerivativeYY;
+
+    /** Second crossed partial derivative. */
+    private BivariateRealFunction partialDerivativeXY;
+
+    /**
+     * Simple constructor.
+     * @param a Spline coefficients
+     */
+    public BicubicSplineFunction(double[] a) {
+        this.a = new double[N][N];
+        for (int i = 0; i < N; i++) {
+            for (int j = 0; j < N; j++) {
+                this.a[i][j] = a[i + N * j];
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double value(double x, double y) {
+        if (x < 0 || x > 1) {
+            throw new OutOfRangeException(x, 0, 1);
+        }
+        if (y < 0 || y > 1) {
+            throw new OutOfRangeException(y, 0, 1);
+        }
+
+        final double x2 = x * x;
+        final double x3 = x2 * x;
+        final double[] pX = {1, x, x2, x3};
+
+        final double y2 = y * y;
+        final double y3 = y2 * y;
+        final double[] pY = {1, y, y2, y3};
+
+        return apply(pX, pY, a);
+    }
+
+    /**
+     * Compute the value of the bicubic polynomial.
+     *
+     * @param pX Powers of the x-coordinate.
+     * @param pY Powers of the y-coordinate.
+     * @param coeff Spline coefficients.
+     * @return the interpolated value.
+     */
+    private double apply(double[] pX, double[] pY, double[][] coeff) {
+        double result = 0;
+        for (int i = 0; i < N; i++) {
+            for (int j = 0; j < N; j++) {
+                result += coeff[i][j] * pX[i] * pY[j];
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * @return the partial derivative wrt {@code x}.
+     */
+    public BivariateRealFunction partialDerivativeX() {
+        if (partialDerivativeX == null) {
+            computePartialDerivatives();
+        }
+
+        return partialDerivativeX;
+    }
+    /**
+     * @return the partial derivative wrt {@code y}.
+     */
+    public BivariateRealFunction partialDerivativeY() {
+        if (partialDerivativeY == null) {
+            computePartialDerivatives();
+        }
+
+        return partialDerivativeY;
+    }
+    /**
+     * @return the second partial derivative wrt {@code x}.
+     */
+    public BivariateRealFunction partialDerivativeXX() {
+        if (partialDerivativeXX == null) {
+            computePartialDerivatives();
+        }
+
+        return partialDerivativeXX;
+    }
+    /**
+     * @return the second partial derivative wrt {@code y}.
+     */
+    public BivariateRealFunction partialDerivativeYY() {
+        if (partialDerivativeYY == null) {
+            computePartialDerivatives();
+        }
+
+        return partialDerivativeYY;
+    }
+    /**
+     * @return the second partial cross-derivative.
+     */
+    public BivariateRealFunction partialDerivativeXY() {
+        if (partialDerivativeXY == null) {
+            computePartialDerivatives();
+        }
+
+        return partialDerivativeXY;
+    }
+
+    /**
+     * Compute all partial derivatives functions.
+     */
+    private void computePartialDerivatives() {
+        final double[][] aX = new double[N][N];
+        final double[][] aY = new double[N][N];
+        final double[][] aXX = new double[N][N];
+        final double[][] aYY = new double[N][N];
+        final double[][] aXY = new double[N][N];
+
+        for (int i = 0; i < N; i++) {
+            for (int j = 0; j < N; j++) {
+                final double c = a[i][j];
+                aX[i][j] = i * c;
+                aY[i][j] = j * c;
+                aXX[i][j] = (i - 1) * aX[i][j];
+                aYY[i][j] = (j - 1) * aY[i][j];
+                aXY[i][j] = j * aX[i][j];
+            }
+        }
+
+        partialDerivativeX = new BivariateRealFunction() {
+                public double value(double x, double y)  {
+                    final double x2 = x * x;
+                    final double[] pX = {0, 1, x, x2};
+
+                    final double y2 = y * y;
+                    final double y3 = y2 * y;
+                    final double[] pY = {1, y, y2, y3};
+
+                    return apply(pX, pY, aX);
+                }
+            };
+        partialDerivativeY = new BivariateRealFunction() {
+                public double value(double x, double y)  {
+                    final double x2 = x * x;
+                    final double x3 = x2 * x;
+                    final double[] pX = {1, x, x2, x3};
+
+                    final double y2 = y * y;
+                    final double[] pY = {0, 1, y, y2};
+
+                    return apply(pX, pY, aY);
+                }
+            };
+        partialDerivativeXX = new BivariateRealFunction() {
+                public double value(double x, double y)  {
+                    final double[] pX = {0, 0, 1, x};
+
+                    final double y2 = y * y;
+                    final double y3 = y2 * y;
+                    final double[] pY = {1, y, y2, y3};
+
+                    return apply(pX, pY, aXX);
+                }
+            };
+        partialDerivativeYY = new BivariateRealFunction() {
+                public double value(double x, double y)  {
+                    final double x2 = x * x;
+                    final double x3 = x2 * x;
+                    final double[] pX = {1, x, x2, x3};
+
+                    final double[] pY = {0, 0, 1, y};
+
+                    return apply(pX, pY, aYY);
+                }
+            };
+        partialDerivativeXY = new BivariateRealFunction() {
+                public double value(double x, double y)  {
+                    final double x2 = x * x;
+                    final double[] pX = {0, 1, x, x2};
+
+                    final double y2 = y * y;
+                    final double[] pY = {0, 1, y, y2};
+
+                    return apply(pX, pY, aXY);
+                }
+            };
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java
new file mode 100644
index 0000000..42f73c8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java
@@ -0,0 +1,145 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Generates a bicubic interpolating function.
+ *
+ * @version $Revision: 980944 $ $Date: 2010-07-30 22:31:11 +0200 (ven. 30 juil. 2010) $
+ * @since 2.2
+ */
+public class BicubicSplineInterpolator
+    implements BivariateRealGridInterpolator {
+    /**
+     * {@inheritDoc}
+     */
+    public BicubicSplineInterpolatingFunction interpolate(final double[] xval,
+                                                          final double[] yval,
+                                                          final double[][] fval)
+        throws MathException, IllegalArgumentException {
+        if (xval.length == 0 || yval.length == 0 || fval.length == 0) {
+            throw new NoDataException();
+        }
+        if (xval.length != fval.length) {
+            throw new DimensionMismatchException(xval.length, fval.length);
+        }
+
+        MathUtils.checkOrder(xval);
+        MathUtils.checkOrder(yval);
+
+        final int xLen = xval.length;
+        final int yLen = yval.length;
+
+        // Samples (first index is y-coordinate, i.e. subarray variable is x)
+        // 0 <= i < xval.length
+        // 0 <= j < yval.length
+        // fX[j][i] = f(xval[i], yval[j])
+        final double[][] fX = new double[yLen][xLen];
+        for (int i = 0; i < xLen; i++) {
+            if (fval[i].length != yLen) {
+                throw new DimensionMismatchException(fval[i].length, yLen);
+            }
+
+            for (int j = 0; j < yLen; j++) {
+                fX[j][i] = fval[i][j];
+            }
+        }
+
+        final SplineInterpolator spInterpolator = new SplineInterpolator();
+
+        // For each line y[j] (0 <= j < yLen), construct a 1D spline with
+        // respect to variable x
+        final PolynomialSplineFunction[] ySplineX = new PolynomialSplineFunction[yLen];
+        for (int j = 0; j < yLen; j++) {
+            ySplineX[j] = spInterpolator.interpolate(xval, fX[j]);
+        }
+
+        // For each line x[i] (0 <= i < xLen), construct a 1D spline with
+        // respect to variable y generated by array fY_1[i]
+        final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen];
+        for (int i = 0; i < xLen; i++) {
+            xSplineY[i] = spInterpolator.interpolate(yval, fval[i]);
+        }
+
+        // Partial derivatives with respect to x at the grid knots
+        final double[][] dFdX = new double[xLen][yLen];
+        for (int j = 0; j < yLen; j++) {
+            final UnivariateRealFunction f = ySplineX[j].derivative();
+            for (int i = 0; i < xLen; i++) {
+                dFdX[i][j] = f.value(xval[i]);
+            }
+        }
+
+        // Partial derivatives with respect to y at the grid knots
+        final double[][] dFdY = new double[xLen][yLen];
+        for (int i = 0; i < xLen; i++) {
+            final UnivariateRealFunction f = xSplineY[i].derivative();
+            for (int j = 0; j < yLen; j++) {
+                dFdY[i][j] = f.value(yval[j]);
+            }
+        }
+
+        // Cross partial derivatives
+        final double[][] d2FdXdY = new double[xLen][yLen];
+        for (int i = 0; i < xLen ; i++) {
+            final int nI = nextIndex(i, xLen);
+            final int pI = previousIndex(i);
+            for (int j = 0; j < yLen; j++) {
+                final int nJ = nextIndex(j, yLen);
+                final int pJ = previousIndex(j);
+                d2FdXdY[i][j] = (fval[nI][nJ] - fval[nI][pJ] -
+                                 fval[pI][nJ] + fval[pI][pJ]) /
+                    ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ]));
+            }
+        }
+
+        // Create the interpolating splines
+        return new BicubicSplineInterpolatingFunction(xval, yval, fval,
+                                                      dFdX, dFdY, d2FdXdY);
+    }
+
+    /**
+     * Compute the next index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is larger than or equal to 0}.
+     *
+     * @param i Index
+     * @param max Upper limit of the array
+     * @return the next index
+     */
+    private int nextIndex(int i, int max) {
+        final int index = i + 1;
+        return index < max ? index : index - 1;
+    }
+    /**
+     * Compute the previous index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is smaller than the size of the array.
+     *
+     * @param i Index
+     * @return the previous index
+     */
+    private int previousIndex(int i) {
+        final int index = i - 1;
+        return index >= 0 ? index : 0;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java
new file mode 100644
index 0000000..218d328
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+
+/**
+ * Interface representing a bivariate real interpolating function where the
+ * sample points must be specified on a regular grid.
+ *
+ * @version $Revision: 936391 $ $Date: 2010-04-21 19:00:56 +0200 (mer. 21 avril 2010) $
+ */
+public interface BivariateRealGridInterpolator {
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param xval All the x-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param yval All the y-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param fval The values of the interpolation points on all the grid knots:
+     * {@code fval[i][j] = f(xval[i], yval[j])}.
+     * @return a function which interpolates the data set.
+     * @throws MathException if arguments violate assumptions made by the
+     *         interpolation algorithm.
+     */
+    BivariateRealFunction interpolate(double[] xval, double[] yval, double[][] fval)
+        throws MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolator.java
new file mode 100644
index 0000000..9b80079
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolator.java
@@ -0,0 +1,117 @@
+/*
+ * 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.analysis.interpolation;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.DuplicateSampleAbscissaException;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm;
+
+/**
+ * Implements the <a href="
+ * "http://mathworld.wolfram.com/NewtonsDividedDifferenceInterpolationFormula.html">
+ * Divided Difference Algorithm</a> for interpolation of real univariate
+ * functions. For reference, see <b>Introduction to Numerical Analysis</b>,
+ * ISBN 038795452X, chapter 2.
+ * <p>
+ * The actual code of Neville's evaluation is in PolynomialFunctionLagrangeForm,
+ * this class provides an easy-to-use interface to it.</p>
+ *
+ * @version $Revision: 825919 $ $Date: 2009-10-16 16:51:55 +0200 (ven. 16 oct. 2009) $
+ * @since 1.2
+ */
+public class DividedDifferenceInterpolator implements UnivariateRealInterpolator,
+    Serializable {
+
+    /** serializable version identifier */
+    private static final long serialVersionUID = 107049519551235069L;
+
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param x the interpolating points array
+     * @param y the interpolating values array
+     * @return a function which interpolates the data set
+     * @throws DuplicateSampleAbscissaException if arguments are invalid
+     */
+    public PolynomialFunctionNewtonForm interpolate(double x[], double y[]) throws
+        DuplicateSampleAbscissaException {
+
+        /**
+         * a[] and c[] are defined in the general formula of Newton form:
+         * p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... +
+         *        a[n](x-c[0])(x-c[1])...(x-c[n-1])
+         */
+        PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y);
+
+        /**
+         * When used for interpolation, the Newton form formula becomes
+         * p(x) = f[x0] + f[x0,x1](x-x0) + f[x0,x1,x2](x-x0)(x-x1) + ... +
+         *        f[x0,x1,...,x[n-1]](x-x0)(x-x1)...(x-x[n-2])
+         * Therefore, a[k] = f[x0,x1,...,xk], c[k] = x[k].
+         * <p>
+         * Note x[], y[], a[] have the same length but c[]'s size is one less.</p>
+         */
+        final double[] c = new double[x.length-1];
+        System.arraycopy(x, 0, c, 0, c.length);
+
+        final double[] a = computeDividedDifference(x, y);
+        return new PolynomialFunctionNewtonForm(a, c);
+
+    }
+
+    /**
+     * Returns a copy of the divided difference array.
+     * <p>
+     * The divided difference array is defined recursively by <pre>
+     * f[x0] = f(x0)
+     * f[x0,x1,...,xk] = (f(x1,...,xk) - f(x0,...,x[k-1])) / (xk - x0)
+     * </pre></p>
+     * <p>
+     * The computational complexity is O(N^2).</p>
+     *
+     * @param x the interpolating points array
+     * @param y the interpolating values array
+     * @return a fresh copy of the divided difference array
+     * @throws DuplicateSampleAbscissaException if any abscissas coincide
+     */
+    protected static double[] computeDividedDifference(final double x[], final double y[])
+        throws DuplicateSampleAbscissaException {
+
+        PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y);
+
+        final double[] divdiff = y.clone(); // initialization
+
+        final int n = x.length;
+        final double[] a = new double [n];
+        a[0] = divdiff[0];
+        for (int i = 1; i < n; i++) {
+            for (int j = 0; j < n-i; j++) {
+                final double denominator = x[j+i] - x[j];
+                if (denominator == 0.0) {
+                    // This happens only when two abscissas are identical.
+                    throw new DuplicateSampleAbscissaException(x[j], j, j+i);
+                }
+                divdiff[j] = (divdiff[j+1] - divdiff[j]) / denominator;
+            }
+            a[i] = divdiff[0];
+        }
+
+        return a;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java
new file mode 100644
index 0000000..71ab9a9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java
@@ -0,0 +1,75 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NumberIsTooSmallException;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Implements a linear function for interpolation of real univariate functions.
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class LinearInterpolator implements UnivariateRealInterpolator {
+    /**
+     * Computes a linear interpolating function for the data set.
+     * @param x the arguments for the interpolation points
+     * @param y the values for the interpolation points
+     * @return a function which interpolates the data set
+     * @throws DimensionMismatchException if {@code x} and {@code y}
+     * have different sizes.
+     * @throws org.apache.commons.math.exception.NonMonotonousSequenceException
+     * if {@code x} is not sorted in strict increasing order.
+     * @throws NumberIsTooSmallException if the size of {@code x} is smaller
+     * than 2.
+     */
+    public PolynomialSplineFunction interpolate(double x[], double y[]) {
+        if (x.length != y.length) {
+            throw new DimensionMismatchException(x.length, y.length);
+        }
+
+        if (x.length < 2) {
+            throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS,
+                                                x.length, 2, true);
+        }
+
+        // Number of intervals.  The number of data points is n + 1.
+        int n = x.length - 1;
+
+        MathUtils.checkOrder(x);
+
+        // Slope of the lines between the datapoints.
+        final double m[] = new double[n];
+        for (int i = 0; i < n; i++) {
+            m[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]);
+        }
+
+        PolynomialFunction polynomials[] = new PolynomialFunction[n];
+        final double coefficients[] = new double[2];
+        for (int i = 0; i < n; i++) {
+            coefficients[0] = y[i];
+            coefficients[1] = m[i];
+            polynomials[i] = new PolynomialFunction(coefficients);
+        }
+
+        return new PolynomialSplineFunction(x, polynomials);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/LoessInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/LoessInterpolator.java
new file mode 100644
index 0000000..5f00e14
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/LoessInterpolator.java
@@ -0,0 +1,463 @@
+/*
+ * 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.analysis.interpolation;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://en.wikipedia.org/wiki/Local_regression">
+ * Local Regression Algorithm</a> (also Loess, Lowess) for interpolation of
+ * real univariate functions.
+ * <p/>
+ * For reference, see
+ * <a href="http://www.math.tau.ac.il/~yekutiel/MA seminar/Cleveland 1979.pdf">
+ * William S. Cleveland - Robust Locally Weighted Regression and Smoothing
+ * Scatterplots</a>
+ * <p/>
+ * This class implements both the loess method and serves as an interpolation
+ * adapter to it, allowing to build a spline on the obtained loess fit.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class LoessInterpolator
+        implements UnivariateRealInterpolator, Serializable {
+
+    /** Default value of the bandwidth parameter. */
+    public static final double DEFAULT_BANDWIDTH = 0.3;
+
+    /** Default value of the number of robustness iterations. */
+    public static final int DEFAULT_ROBUSTNESS_ITERS = 2;
+
+    /**
+     * Default value for accuracy.
+     * @since 2.1
+     */
+    public static final double DEFAULT_ACCURACY = 1e-12;
+
+    /** serializable version identifier. */
+    private static final long serialVersionUID = 5204927143605193821L;
+
+    /**
+     * The bandwidth parameter: when computing the loess fit at
+     * a particular point, this fraction of source points closest
+     * to the current point is taken into account for computing
+     * a least-squares regression.
+     * <p/>
+     * A sensible value is usually 0.25 to 0.5.
+     */
+    private final double bandwidth;
+
+    /**
+     * The number of robustness iterations parameter: this many
+     * robustness iterations are done.
+     * <p/>
+     * A sensible value is usually 0 (just the initial fit without any
+     * robustness iterations) to 4.
+     */
+    private final int robustnessIters;
+
+    /**
+     * If the median residual at a certain robustness iteration
+     * is less than this amount, no more iterations are done.
+     */
+    private final double accuracy;
+
+    /**
+     * Constructs a new {@link LoessInterpolator}
+     * with a bandwidth of {@link #DEFAULT_BANDWIDTH},
+     * {@link #DEFAULT_ROBUSTNESS_ITERS} robustness iterations
+     * and an accuracy of {#link #DEFAULT_ACCURACY}.
+     * See {@link #LoessInterpolator(double, int, double)} for an explanation of
+     * the parameters.
+     */
+    public LoessInterpolator() {
+        this.bandwidth = DEFAULT_BANDWIDTH;
+        this.robustnessIters = DEFAULT_ROBUSTNESS_ITERS;
+        this.accuracy = DEFAULT_ACCURACY;
+    }
+
+    /**
+     * Constructs a new {@link LoessInterpolator}
+     * with given bandwidth and number of robustness iterations.
+     * <p>
+     * Calling this constructor is equivalent to calling {link {@link
+     * #LoessInterpolator(double, int, double) LoessInterpolator(bandwidth,
+     * robustnessIters, LoessInterpolator.DEFAULT_ACCURACY)}
+     * </p>
+     *
+     * @param bandwidth  when computing the loess fit at
+     * a particular point, this fraction of source points closest
+     * to the current point is taken into account for computing
+     * a least-squares regression.</br>
+     * A sensible value is usually 0.25 to 0.5, the default value is
+     * {@link #DEFAULT_BANDWIDTH}.
+     * @param robustnessIters This many robustness iterations are done.</br>
+     * A sensible value is usually 0 (just the initial fit without any
+     * robustness iterations) to 4, the default value is
+     * {@link #DEFAULT_ROBUSTNESS_ITERS}.
+     * @throws MathException if bandwidth does not lie in the interval [0,1]
+     * or if robustnessIters is negative.
+     * @see #LoessInterpolator(double, int, double)
+     */
+    public LoessInterpolator(double bandwidth, int robustnessIters) throws MathException {
+        this(bandwidth, robustnessIters, DEFAULT_ACCURACY);
+    }
+
+    /**
+     * Constructs a new {@link LoessInterpolator}
+     * with given bandwidth, number of robustness iterations and accuracy.
+     *
+     * @param bandwidth  when computing the loess fit at
+     * a particular point, this fraction of source points closest
+     * to the current point is taken into account for computing
+     * a least-squares regression.</br>
+     * A sensible value is usually 0.25 to 0.5, the default value is
+     * {@link #DEFAULT_BANDWIDTH}.
+     * @param robustnessIters This many robustness iterations are done.</br>
+     * A sensible value is usually 0 (just the initial fit without any
+     * robustness iterations) to 4, the default value is
+     * {@link #DEFAULT_ROBUSTNESS_ITERS}.
+     * @param accuracy If the median residual at a certain robustness iteration
+     * is less than this amount, no more iterations are done.
+     * @throws MathException if bandwidth does not lie in the interval [0,1]
+     * or if robustnessIters is negative.
+     * @see #LoessInterpolator(double, int)
+     * @since 2.1
+     */
+    public LoessInterpolator(double bandwidth, int robustnessIters, double accuracy) throws MathException {
+        if (bandwidth < 0 || bandwidth > 1) {
+            throw new MathException(LocalizedFormats.BANDWIDTH_OUT_OF_INTERVAL,
+                                    bandwidth);
+        }
+        this.bandwidth = bandwidth;
+        if (robustnessIters < 0) {
+            throw new MathException(LocalizedFormats.NEGATIVE_ROBUSTNESS_ITERATIONS, robustnessIters);
+        }
+        this.robustnessIters = robustnessIters;
+        this.accuracy = accuracy;
+    }
+
+    /**
+     * Compute an interpolating function by performing a loess fit
+     * on the data at the original abscissae and then building a cubic spline
+     * with a
+     * {@link org.apache.commons.math.analysis.interpolation.SplineInterpolator}
+     * on the resulting fit.
+     *
+     * @param xval the arguments for the interpolation points
+     * @param yval the values for the interpolation points
+     * @return A cubic spline built upon a loess fit to the data at the original abscissae
+     * @throws MathException  if some of the following conditions are false:
+     * <ul>
+     * <li> Arguments and values are of the same size that is greater than zero</li>
+     * <li> The arguments are in a strictly increasing order</li>
+     * <li> All arguments and values are finite real numbers</li>
+     * </ul>
+     */
+    public final PolynomialSplineFunction interpolate(
+            final double[] xval, final double[] yval) throws MathException {
+        return new SplineInterpolator().interpolate(xval, smooth(xval, yval));
+    }
+
+    /**
+     * Compute a weighted loess fit on the data at the original abscissae.
+     *
+     * @param xval the arguments for the interpolation points
+     * @param yval the values for the interpolation points
+     * @param weights point weights: coefficients by which the robustness weight of a point is multiplied
+     * @return values of the loess fit at corresponding original abscissae
+     * @throws MathException if some of the following conditions are false:
+     * <ul>
+     * <li> Arguments and values are of the same size that is greater than zero</li>
+     * <li> The arguments are in a strictly increasing order</li>
+     * <li> All arguments and values are finite real numbers</li>
+     * </ul>
+     * @since 2.1
+     */
+    public final double[] smooth(final double[] xval, final double[] yval, final double[] weights)
+            throws MathException {
+        if (xval.length != yval.length) {
+            throw new MathException(LocalizedFormats.MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS,
+                                    xval.length, yval.length);
+        }
+
+        final int n = xval.length;
+
+        if (n == 0) {
+            throw new MathException(LocalizedFormats.LOESS_EXPECTS_AT_LEAST_ONE_POINT);
+        }
+
+        checkAllFiniteReal(xval, LocalizedFormats.NON_REAL_FINITE_ABSCISSA);
+        checkAllFiniteReal(yval, LocalizedFormats.NON_REAL_FINITE_ORDINATE);
+        checkAllFiniteReal(weights, LocalizedFormats.NON_REAL_FINITE_WEIGHT);
+
+        checkStrictlyIncreasing(xval);
+
+        if (n == 1) {
+            return new double[]{yval[0]};
+        }
+
+        if (n == 2) {
+            return new double[]{yval[0], yval[1]};
+        }
+
+        int bandwidthInPoints = (int) (bandwidth * n);
+
+        if (bandwidthInPoints < 2) {
+            throw new MathException(LocalizedFormats.TOO_SMALL_BANDWIDTH,
+                                    n, 2.0 / n, bandwidth);
+        }
+
+        final double[] res = new double[n];
+
+        final double[] residuals = new double[n];
+        final double[] sortedResiduals = new double[n];
+
+        final double[] robustnessWeights = new double[n];
+
+        // Do an initial fit and 'robustnessIters' robustness iterations.
+        // This is equivalent to doing 'robustnessIters+1' robustness iterations
+        // starting with all robustness weights set to 1.
+        Arrays.fill(robustnessWeights, 1);
+
+        for (int iter = 0; iter <= robustnessIters; ++iter) {
+            final int[] bandwidthInterval = {0, bandwidthInPoints - 1};
+            // At each x, compute a local weighted linear regression
+            for (int i = 0; i < n; ++i) {
+                final double x = xval[i];
+
+                // Find out the interval of source points on which
+                // a regression is to be made.
+                if (i > 0) {
+                    updateBandwidthInterval(xval, weights, i, bandwidthInterval);
+                }
+
+                final int ileft = bandwidthInterval[0];
+                final int iright = bandwidthInterval[1];
+
+                // Compute the point of the bandwidth interval that is
+                // farthest from x
+                final int edge;
+                if (xval[i] - xval[ileft] > xval[iright] - xval[i]) {
+                    edge = ileft;
+                } else {
+                    edge = iright;
+                }
+
+                // Compute a least-squares linear fit weighted by
+                // the product of robustness weights and the tricube
+                // weight function.
+                // See http://en.wikipedia.org/wiki/Linear_regression
+                // (section "Univariate linear case")
+                // and http://en.wikipedia.org/wiki/Weighted_least_squares
+                // (section "Weighted least squares")
+                double sumWeights = 0;
+                double sumX = 0;
+                double sumXSquared = 0;
+                double sumY = 0;
+                double sumXY = 0;
+                double denom = FastMath.abs(1.0 / (xval[edge] - x));
+                for (int k = ileft; k <= iright; ++k) {
+                    final double xk   = xval[k];
+                    final double yk   = yval[k];
+                    final double dist = (k < i) ? x - xk : xk - x;
+                    final double w    = tricube(dist * denom) * robustnessWeights[k] * weights[k];
+                    final double xkw  = xk * w;
+                    sumWeights += w;
+                    sumX += xkw;
+                    sumXSquared += xk * xkw;
+                    sumY += yk * w;
+                    sumXY += yk * xkw;
+                }
+
+                final double meanX = sumX / sumWeights;
+                final double meanY = sumY / sumWeights;
+                final double meanXY = sumXY / sumWeights;
+                final double meanXSquared = sumXSquared / sumWeights;
+
+                final double beta;
+                if (FastMath.sqrt(FastMath.abs(meanXSquared - meanX * meanX)) < accuracy) {
+                    beta = 0;
+                } else {
+                    beta = (meanXY - meanX * meanY) / (meanXSquared - meanX * meanX);
+                }
+
+                final double alpha = meanY - beta * meanX;
+
+                res[i] = beta * x + alpha;
+                residuals[i] = FastMath.abs(yval[i] - res[i]);
+            }
+
+            // No need to recompute the robustness weights at the last
+            // iteration, they won't be needed anymore
+            if (iter == robustnessIters) {
+                break;
+            }
+
+            // Recompute the robustness weights.
+
+            // Find the median residual.
+            // An arraycopy and a sort are completely tractable here,
+            // because the preceding loop is a lot more expensive
+            System.arraycopy(residuals, 0, sortedResiduals, 0, n);
+            Arrays.sort(sortedResiduals);
+            final double medianResidual = sortedResiduals[n / 2];
+
+            if (FastMath.abs(medianResidual) < accuracy) {
+                break;
+            }
+
+            for (int i = 0; i < n; ++i) {
+                final double arg = residuals[i] / (6 * medianResidual);
+                if (arg >= 1) {
+                    robustnessWeights[i] = 0;
+                } else {
+                    final double w = 1 - arg * arg;
+                    robustnessWeights[i] = w * w;
+                }
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * Compute a loess fit on the data at the original abscissae.
+     *
+     * @param xval the arguments for the interpolation points
+     * @param yval the values for the interpolation points
+     * @return values of the loess fit at corresponding original abscissae
+     * @throws MathException if some of the following conditions are false:
+     * <ul>
+     * <li> Arguments and values are of the same size that is greater than zero</li>
+     * <li> The arguments are in a strictly increasing order</li>
+     * <li> All arguments and values are finite real numbers</li>
+     * </ul>
+     */
+    public final double[] smooth(final double[] xval, final double[] yval)
+            throws MathException {
+        if (xval.length != yval.length) {
+            throw new MathException(LocalizedFormats.MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS,
+                                    xval.length, yval.length);
+        }
+
+        final double[] unitWeights = new double[xval.length];
+        Arrays.fill(unitWeights, 1.0);
+
+        return smooth(xval, yval, unitWeights);
+    }
+
+    /**
+     * Given an index interval into xval that embraces a certain number of
+     * points closest to xval[i-1], update the interval so that it embraces
+     * the same number of points closest to xval[i], ignoring zero weights.
+     *
+     * @param xval arguments array
+     * @param weights weights array
+     * @param i the index around which the new interval should be computed
+     * @param bandwidthInterval a two-element array {left, right} such that: <p/>
+     * <tt>(left==0 or xval[i] - xval[left-1] > xval[right] - xval[i])</tt>
+     * <p/> and also <p/>
+     * <tt>(right==xval.length-1 or xval[right+1] - xval[i] > xval[i] - xval[left])</tt>.
+     * The array will be updated.
+     */
+    private static void updateBandwidthInterval(final double[] xval, final double[] weights,
+                                                final int i,
+                                                final int[] bandwidthInterval) {
+        final int left = bandwidthInterval[0];
+        final int right = bandwidthInterval[1];
+
+        // The right edge should be adjusted if the next point to the right
+        // is closer to xval[i] than the leftmost point of the current interval
+        int nextRight = nextNonzero(weights, right);
+        if (nextRight < xval.length && xval[nextRight] - xval[i] < xval[i] - xval[left]) {
+            int nextLeft = nextNonzero(weights, bandwidthInterval[0]);
+            bandwidthInterval[0] = nextLeft;
+            bandwidthInterval[1] = nextRight;
+        }
+    }
+
+    /**
+     * Returns the smallest index j such that j > i && (j==weights.length || weights[j] != 0)
+     * @param weights weights array
+     * @param i the index from which to start search; must be < weights.length
+     * @return the smallest index j such that j > i && (j==weights.length || weights[j] != 0)
+     */
+    private static int nextNonzero(final double[] weights, final int i) {
+        int j = i + 1;
+        while(j < weights.length && weights[j] == 0) {
+            j++;
+        }
+        return j;
+    }
+
+    /**
+     * Compute the
+     * <a href="http://en.wikipedia.org/wiki/Local_regression#Weight_function">tricube</a>
+     * weight function
+     *
+     * @param x the argument
+     * @return (1-|x|^3)^3
+     */
+    private static double tricube(final double x) {
+        final double tmp = 1 - x * x * x;
+        return tmp * tmp * tmp;
+    }
+
+    /**
+     * Check that all elements of an array are finite real numbers.
+     *
+     * @param values the values array
+     * @param pattern pattern of the error message
+     * @throws MathException if one of the values is not a finite real number
+     */
+    private static void checkAllFiniteReal(final double[] values, final Localizable pattern)
+        throws MathException {
+        for (int i = 0; i < values.length; i++) {
+            final double x = values[i];
+            if (Double.isInfinite(x) || Double.isNaN(x)) {
+                throw new MathException(pattern, i, x);
+            }
+        }
+    }
+
+    /**
+     * Check that elements of the abscissae array are in a strictly
+     * increasing order.
+     *
+     * @param xval the abscissae array
+     * @throws MathException if the abscissae array
+     * is not in a strictly increasing order
+     */
+    private static void checkStrictlyIncreasing(final double[] xval)
+        throws MathException {
+        for (int i = 0; i < xval.length; ++i) {
+            if (i >= 1 && xval[i - 1] >= xval[i]) {
+                throw new MathException(LocalizedFormats.OUT_OF_ORDER_ABSCISSA_ARRAY,
+                                        i - 1, xval[i - 1], i, xval[i]);
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java b/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
new file mode 100644
index 0000000..a710e82
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
@@ -0,0 +1,244 @@
+/*
+ * 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.analysis.interpolation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.linear.ArrayRealVector;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Interpolating function that implements the
+ * <a href="http://www.dudziak.com/microsphere.php">Microsphere Projection</a>.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public class MicrosphereInterpolatingFunction
+    implements MultivariateRealFunction {
+    /**
+     * Space dimension.
+     */
+    private final int dimension;
+    /**
+     * Internal accounting data for the interpolation algorithm.
+     * Each element of the list corresponds to one surface element of
+     * the microsphere.
+     */
+    private final List<MicrosphereSurfaceElement> microsphere;
+    /**
+     * Exponent used in the power law that computes the weights of the
+     * sample data.
+     */
+    private final double brightnessExponent;
+    /**
+     * Sample data.
+     */
+    private final Map<RealVector, Double> samples;
+
+    /**
+     * Class for storing the accounting data needed to perform the
+     * microsphere projection.
+     */
+    private static class MicrosphereSurfaceElement {
+
+        /** Normal vector characterizing a surface element. */
+        private final RealVector normal;
+
+        /** Illumination received from the brightest sample. */
+        private double brightestIllumination;
+
+        /** Brightest sample. */
+        private Map.Entry<RealVector, Double> brightestSample;
+
+        /**
+         * @param n Normal vector characterizing a surface element
+         * of the microsphere.
+         */
+        MicrosphereSurfaceElement(double[] n) {
+            normal = new ArrayRealVector(n);
+        }
+
+        /**
+         * Return the normal vector.
+         * @return the normal vector
+         */
+        RealVector normal() {
+            return normal;
+        }
+
+        /**
+         * Reset "illumination" and "sampleIndex".
+         */
+        void reset() {
+            brightestIllumination = 0;
+            brightestSample = null;
+        }
+
+        /**
+         * Store the illumination and index of the brightest sample.
+         * @param illuminationFromSample illumination received from sample
+         * @param sample current sample illuminating the element
+         */
+        void store(final double illuminationFromSample,
+                   final Map.Entry<RealVector, Double> sample) {
+            if (illuminationFromSample > this.brightestIllumination) {
+                this.brightestIllumination = illuminationFromSample;
+                this.brightestSample = sample;
+            }
+        }
+
+        /**
+         * Get the illumination of the element.
+         * @return the illumination.
+         */
+        double illumination() {
+            return brightestIllumination;
+        }
+
+        /**
+         * Get the sample illuminating the element the most.
+         * @return the sample.
+         */
+        Map.Entry<RealVector, Double> sample() {
+            return brightestSample;
+        }
+    }
+
+    /**
+     * @param xval the arguments for the interpolation points.
+     * {@code xval[i][0]} is the first component of interpolation point
+     * {@code i}, {@code xval[i][1]} is the second component, and so on
+     * until {@code xval[i][d-1]}, the last component of that interpolation
+     * point (where {@code dimension} is thus the dimension of the sampled
+     * space).
+     * @param yval the values for the interpolation points
+     * @param brightnessExponent Brightness dimming factor.
+     * @param microsphereElements Number of surface elements of the
+     * microsphere.
+     * @param rand Unit vector generator for creating the microsphere.
+     * @throws DimensionMismatchException if the lengths of {@code yval} and
+     * {@code xval} (equal to {@code n}, the number of interpolation points)
+     * do not match, or the the arrays {@code xval[0]} ... {@code xval[n]},
+     * have lengths different from {@code dimension}.
+     * @throws NoDataException if there are no data (xval null or zero length)
+     */
+    public MicrosphereInterpolatingFunction(double[][] xval,
+                                            double[] yval,
+                                            int brightnessExponent,
+                                            int microsphereElements,
+                                            UnitSphereRandomVectorGenerator rand)
+        throws DimensionMismatchException, NoDataException {
+        if (xval.length == 0 || xval[0] == null) {
+            throw new NoDataException();
+        }
+
+        if (xval.length != yval.length) {
+            throw new DimensionMismatchException(xval.length, yval.length);
+        }
+
+        dimension = xval[0].length;
+        this.brightnessExponent = brightnessExponent;
+
+        // Copy data samples.
+        samples = new HashMap<RealVector, Double>(yval.length);
+        for (int i = 0; i < xval.length; ++i) {
+            final double[] xvalI = xval[i];
+            if ( xvalI.length != dimension) {
+                throw new DimensionMismatchException(xvalI.length, dimension);
+            }
+
+            samples.put(new ArrayRealVector(xvalI), yval[i]);
+        }
+
+        microsphere = new ArrayList<MicrosphereSurfaceElement>(microsphereElements);
+        // Generate the microsphere, assuming that a fairly large number of
+        // randomly generated normals will represent a sphere.
+        for (int i = 0; i < microsphereElements; i++) {
+            microsphere.add(new MicrosphereSurfaceElement(rand.nextVector()));
+        }
+
+    }
+
+    /**
+     * @param point Interpolation point.
+     * @return the interpolated value.
+     */
+    public double value(double[] point) {
+
+        final RealVector p = new ArrayRealVector(point);
+
+        // Reset.
+        for (MicrosphereSurfaceElement md : microsphere) {
+            md.reset();
+        }
+
+        // Compute contribution of each sample points to the microsphere elements illumination
+        for (Map.Entry<RealVector, Double> sd : samples.entrySet()) {
+
+            // Vector between interpolation point and current sample point.
+            final RealVector diff = sd.getKey().subtract(p);
+            final double diffNorm = diff.getNorm();
+
+            if (FastMath.abs(diffNorm) < FastMath.ulp(1d)) {
+                // No need to interpolate, as the interpolation point is
+                // actually (very close to) one of the sampled points.
+                return sd.getValue();
+            }
+
+            for (MicrosphereSurfaceElement md : microsphere) {
+                final double w = FastMath.pow(diffNorm, -brightnessExponent);
+                md.store(cosAngle(diff, md.normal()) * w, sd);
+            }
+
+        }
+
+        // Interpolation calculation.
+        double value = 0;
+        double totalWeight = 0;
+        for (MicrosphereSurfaceElement md : microsphere) {
+            final double iV = md.illumination();
+            final Map.Entry<RealVector, Double> sd = md.sample();
+            if (sd != null) {
+                value += iV * sd.getValue();
+                totalWeight += iV;
+            }
+        }
+
+        return value / totalWeight;
+
+    }
+
+    /**
+     * Compute the cosine of the angle between 2 vectors.
+     *
+     * @param v Vector.
+     * @param w Vector.
+     * @return cosine of the angle
+     */
+    private double cosAngle(final RealVector v, final RealVector w) {
+        return v.dotProduct(w) / (v.getNorm() * w.getNorm());
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
new file mode 100644
index 0000000..c2a4009
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
@@ -0,0 +1,118 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.exception.NotPositiveException;
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
+
+/**
+ * Interpolator that implements the algorithm described in
+ * <em>William Dudziak</em>'s
+ * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>.
+ * @since 2.1
+ *
+ * @version $Revision: 980944 $ $Date: 2010-07-30 22:31:11 +0200 (ven. 30 juil. 2010) $
+ */
+public class MicrosphereInterpolator
+    implements MultivariateRealInterpolator {
+
+    /**
+     * Default number of surface elements that composes the microsphere.
+     */
+    public static final int DEFAULT_MICROSPHERE_ELEMENTS = 2000;
+
+    /**
+     * Default exponent used the weights calculation.
+     */
+    public static final int DEFAULT_BRIGHTNESS_EXPONENT = 2;
+
+    /**
+     * Number of surface elements of the microsphere.
+     */
+    private int microsphereElements;
+
+    /**
+     * Exponent used in the power law that computes the weights of the
+     * sample data.
+     */
+    private int brightnessExponent;
+
+    /** Create a microsphere interpolator with default settings.
+     * <p>Calling this constructor is equivalent to call {@link
+     * #MicrosphereInterpolator(int, int)
+     * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS,
+     * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.</p>
+     */
+    public MicrosphereInterpolator() {
+        this(DEFAULT_MICROSPHERE_ELEMENTS, DEFAULT_BRIGHTNESS_EXPONENT);
+    }
+
+    /** Create a microsphere interpolator.
+     * @param microsphereElements number of surface elements of the microsphere.
+     * @param brightnessExponent exponent used in the power law that computes the
+     * weights of the sample data.
+     * @throws NotPositiveException if {@code microsphereElements <= 0}
+     * or {@code brightnessExponent < 0}.
+     */
+    public MicrosphereInterpolator(final int microsphereElements,
+                                   final int brightnessExponent) {
+        setMicropshereElements(microsphereElements);
+        setBrightnessExponent(brightnessExponent);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MultivariateRealFunction interpolate(final double[][] xval,
+                                                final double[] yval)
+        throws MathException, IllegalArgumentException {
+        final UnitSphereRandomVectorGenerator rand
+            = new UnitSphereRandomVectorGenerator(xval[0].length);
+        return new MicrosphereInterpolatingFunction(xval, yval,
+                                                    brightnessExponent,
+                                                    microsphereElements,
+                                                    rand);
+    }
+
+    /**
+     * Set the brightness exponent.
+     * @param exponent Exponent for computing the distance dimming
+     * factor.
+     * @throws NotPositiveException if {@code exponent < 0}.
+     */
+    public void setBrightnessExponent(final int exponent) {
+        if (exponent < 0) {
+            throw new NotPositiveException(exponent);
+        }
+        brightnessExponent = exponent;
+    }
+
+    /**
+     * Set the number of microsphere elements.
+     * @param elements Number of surface elements of the microsphere.
+     * @throws NotStrictlyPositiveException if {@code elements <= 0}.
+     */
+    public void setMicropshereElements(final int elements) {
+        if (elements <= 0) {
+            throw new NotStrictlyPositiveException(elements);
+        }
+        microsphereElements = elements;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java
new file mode 100644
index 0000000..ed7690c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java
@@ -0,0 +1,46 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+
+/**
+ * Interface representing a univariate real interpolating function.
+ *
+ * @since 2.1
+ * @version $Revision: 924794 $ $Date: 2010-03-18 15:15:50 +0100 (jeu. 18 mars 2010) $
+ */
+public interface MultivariateRealInterpolator {
+
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param xval the arguments for the interpolation points.
+     * {@code xval[i][0]} is the first component of interpolation point
+     * {@code i}, {@code xval[i][1]} is the second component, and so on
+     * until {@code xval[i][d-1]}, the last component of that interpolation
+     * point (where {@code d} is thus the dimension of the space).
+     * @param yval the values for the interpolation points
+     * @return a function which interpolates the data set
+     * @throws MathException if arguments violate assumptions made by the
+     *         interpolation algorithm or some dimension mismatch occurs
+     * @throws IllegalArgumentException if there are no data (xval null or zero length)
+     */
+    MultivariateRealFunction interpolate(double[][] xval, double[] yval)
+        throws MathException, IllegalArgumentException;
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolator.java
new file mode 100644
index 0000000..27e89cd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/NevilleInterpolator.java
@@ -0,0 +1,54 @@
+/*
+ * 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.analysis.interpolation;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html">
+ * Neville's Algorithm</a> for interpolation of real univariate functions. For
+ * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
+ * chapter 2.
+ * <p>
+ * The actual code of Neville's evalution is in PolynomialFunctionLagrangeForm,
+ * this class provides an easy-to-use interface to it.</p>
+ *
+ * @version $Revision: 799857 $ $Date: 2009-08-01 15:07:12 +0200 (sam. 01 août 2009) $
+ * @since 1.2
+ */
+public class NevilleInterpolator implements UnivariateRealInterpolator,
+    Serializable {
+
+    /** serializable version identifier */
+    static final long serialVersionUID = 3003707660147873733L;
+
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param x the interpolating points array
+     * @param y the interpolating values array
+     * @return a function which interpolates the data set
+     * @throws MathException if arguments are invalid
+     */
+    public PolynomialFunctionLagrangeForm interpolate(double x[], double y[])
+        throws MathException {
+        return new PolynomialFunctionLagrangeForm(x, y);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java
new file mode 100644
index 0000000..5514433
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.java
@@ -0,0 +1,178 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.MathUtils.OrderDirection;
+import org.apache.commons.math.analysis.BivariateRealFunction;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Generates a bicubic interpolation function.
+ * Before interpolating, smoothing of the input data is performed using
+ * splines.
+ * See <b>Handbook on splines for the user</b>, ISBN 084939404X,
+ * chapter 2.
+ *
+ * @version $Revision: 1059400 $ $Date: 2011-01-15 20:35:27 +0100 (sam. 15 janv. 2011) $
+ * @since 2.1
+ * @deprecated This class does not perform smoothing; the name is thus misleading.
+ * Please use {@link org.apache.commons.math.analysis.interpolation.BicubicSplineInterpolator}
+ * instead. If smoothing is desired, a tentative implementation is provided in class
+ * {@link org.apache.commons.math.analysis.interpolation.SmoothingPolynomialBicubicSplineInterpolator}.
+ * This class will be removed in math 3.0.
+ */
+@Deprecated
+public class SmoothingBicubicSplineInterpolator
+    implements BivariateRealGridInterpolator {
+    /**
+     * {@inheritDoc}
+     */
+    public BivariateRealFunction interpolate(final double[] xval,
+                                                          final double[] yval,
+                                                          final double[][] zval)
+        throws MathException, IllegalArgumentException {
+        if (xval.length == 0 || yval.length == 0 || zval.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NO_DATA);
+        }
+        if (xval.length != zval.length) {
+            throw new DimensionMismatchException(xval.length, zval.length);
+        }
+
+        MathUtils.checkOrder(xval, OrderDirection.INCREASING, true);
+        MathUtils.checkOrder(yval, OrderDirection.INCREASING, true);
+
+        final int xLen = xval.length;
+        final int yLen = yval.length;
+
+        // Samples (first index is y-coordinate, i.e. subarray variable is x)
+        // 0 <= i < xval.length
+        // 0 <= j < yval.length
+        // zX[j][i] = f(xval[i], yval[j])
+        final double[][] zX = new double[yLen][xLen];
+        for (int i = 0; i < xLen; i++) {
+            if (zval[i].length != yLen) {
+                throw new DimensionMismatchException(zval[i].length, yLen);
+            }
+
+            for (int j = 0; j < yLen; j++) {
+                zX[j][i] = zval[i][j];
+            }
+        }
+
+        final SplineInterpolator spInterpolator = new SplineInterpolator();
+
+        // For each line y[j] (0 <= j < yLen), construct a 1D spline with
+        // respect to variable x
+        final PolynomialSplineFunction[] ySplineX = new PolynomialSplineFunction[yLen];
+        for (int j = 0; j < yLen; j++) {
+            ySplineX[j] = spInterpolator.interpolate(xval, zX[j]);
+        }
+
+        // For every knot (xval[i], yval[j]) of the grid, calculate corrected
+        // values zY_1
+        final double[][] zY_1 = new double[xLen][yLen];
+        for (int j = 0; j < yLen; j++) {
+            final PolynomialSplineFunction f = ySplineX[j];
+            for (int i = 0; i < xLen; i++) {
+                zY_1[i][j] = f.value(xval[i]);
+            }
+        }
+
+        // For each line x[i] (0 <= i < xLen), construct a 1D spline with
+        // respect to variable y generated by array zY_1[i]
+        final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen];
+        for (int i = 0; i < xLen; i++) {
+            xSplineY[i] = spInterpolator.interpolate(yval, zY_1[i]);
+        }
+
+        // For every knot (xval[i], yval[j]) of the grid, calculate corrected
+        // values zY_2
+        final double[][] zY_2 = new double[xLen][yLen];
+        for (int i = 0; i < xLen; i++) {
+            final PolynomialSplineFunction f = xSplineY[i];
+            for (int j = 0; j < yLen; j++) {
+                zY_2[i][j] = f.value(yval[j]);
+            }
+        }
+
+        // Partial derivatives with respect to x at the grid knots
+        final double[][] dZdX = new double[xLen][yLen];
+        for (int j = 0; j < yLen; j++) {
+            final UnivariateRealFunction f = ySplineX[j].derivative();
+            for (int i = 0; i < xLen; i++) {
+                dZdX[i][j] = f.value(xval[i]);
+            }
+        }
+
+        // Partial derivatives with respect to y at the grid knots
+        final double[][] dZdY = new double[xLen][yLen];
+        for (int i = 0; i < xLen; i++) {
+            final UnivariateRealFunction f = xSplineY[i].derivative();
+            for (int j = 0; j < yLen; j++) {
+                dZdY[i][j] = f.value(yval[j]);
+            }
+        }
+
+        // Cross partial derivatives
+        final double[][] dZdXdY = new double[xLen][yLen];
+        for (int i = 0; i < xLen ; i++) {
+            final int nI = nextIndex(i, xLen);
+            final int pI = previousIndex(i);
+            for (int j = 0; j < yLen; j++) {
+                final int nJ = nextIndex(j, yLen);
+                final int pJ = previousIndex(j);
+                dZdXdY[i][j] = (zY_2[nI][nJ] - zY_2[nI][pJ] -
+                                zY_2[pI][nJ] + zY_2[pI][pJ]) /
+                    ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ]));
+            }
+        }
+
+        // Create the interpolating splines
+        return new BicubicSplineInterpolatingFunction(xval, yval, zY_2,
+                                                      dZdX, dZdY, dZdXdY);
+    }
+
+    /**
+     * Compute the next index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is larger than or equal to 0}.
+     *
+     * @param i Index
+     * @param max Upper limit of the array
+     * @return the next index
+     */
+    private int nextIndex(int i, int max) {
+        final int index = i + 1;
+        return index < max ? index : index - 1;
+    }
+    /**
+     * Compute the previous index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is smaller than the size of the array.
+     *
+     * @param i Index
+     * @return the previous index
+     */
+    private int previousIndex(int i) {
+        final int index = i - 1;
+        return index >= 0 ? index : 0;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomialBicubicSplineInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomialBicubicSplineInterpolator.java
new file mode 100644
index 0000000..406d603
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/SmoothingPolynomialBicubicSplineInterpolator.java
@@ -0,0 +1,143 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.optimization.general.GaussNewtonOptimizer;
+import org.apache.commons.math.optimization.fitting.PolynomialFitter;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+
+/**
+ * Generates a bicubic interpolation function.
+ * Prior to generating the interpolating function, the input is smoothed using
+ * polynomial fitting.
+ *
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+ */
+public class SmoothingPolynomialBicubicSplineInterpolator
+    extends BicubicSplineInterpolator {
+
+    /** Fitter for x. */
+    private final PolynomialFitter xFitter;
+
+    /** Fitter for y. */
+    private final PolynomialFitter yFitter;
+
+    /**
+     * Default constructor. The degree of the fitting polynomials is set to 3.
+     */
+    public SmoothingPolynomialBicubicSplineInterpolator() {
+        this(3);
+    }
+
+    /**
+     * @param degree Degree of the polynomial fitting functions.
+     */
+    public SmoothingPolynomialBicubicSplineInterpolator(int degree) {
+        this(degree, degree);
+    }
+
+    /**
+     * @param xDegree Degree of the polynomial fitting functions along the
+     * x-dimension.
+     * @param yDegree Degree of the polynomial fitting functions along the
+     * y-dimension.
+     */
+    public SmoothingPolynomialBicubicSplineInterpolator(int xDegree,
+                                                        int yDegree) {
+        xFitter = new PolynomialFitter(xDegree, new GaussNewtonOptimizer(false));
+        yFitter = new PolynomialFitter(yDegree, new GaussNewtonOptimizer(false));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public BicubicSplineInterpolatingFunction interpolate(final double[] xval,
+                                                          final double[] yval,
+                                                          final double[][] fval)
+        throws MathException {
+        if (xval.length == 0 || yval.length == 0 || fval.length == 0) {
+            throw new NoDataException();
+        }
+        if (xval.length != fval.length) {
+            throw new DimensionMismatchException(xval.length, fval.length);
+        }
+
+        final int xLen = xval.length;
+        final int yLen = yval.length;
+
+        for (int i = 0; i < xLen; i++) {
+            if (fval[i].length != yLen) {
+                throw new DimensionMismatchException(fval[i].length, yLen);
+            }
+        }
+
+        MathUtils.checkOrder(xval);
+        MathUtils.checkOrder(yval);
+
+        // For each line y[j] (0 <= j < yLen), construct a polynomial, with
+        // respect to variable x, fitting array fval[][j]
+        final PolynomialFunction[] yPolyX = new PolynomialFunction[yLen];
+        for (int j = 0; j < yLen; j++) {
+            xFitter.clearObservations();
+            for (int i = 0; i < xLen; i++) {
+                xFitter.addObservedPoint(1, xval[i], fval[i][j]);
+            }
+
+            yPolyX[j] = xFitter.fit();
+        }
+
+        // For every knot (xval[i], yval[j]) of the grid, calculate corrected
+        // values fval_1
+        final double[][] fval_1 = new double[xLen][yLen];
+        for (int j = 0; j < yLen; j++) {
+            final PolynomialFunction f = yPolyX[j];
+            for (int i = 0; i < xLen; i++) {
+                fval_1[i][j] = f.value(xval[i]);
+            }
+        }
+
+        // For each line x[i] (0 <= i < xLen), construct a polynomial, with
+        // respect to variable y, fitting array fval_1[i][]
+        final PolynomialFunction[] xPolyY = new PolynomialFunction[xLen];
+        for (int i = 0; i < xLen; i++) {
+            yFitter.clearObservations();
+            for (int j = 0; j < yLen; j++) {
+                yFitter.addObservedPoint(1, yval[j], fval_1[i][j]);
+            }
+
+            xPolyY[i] = yFitter.fit();
+        }
+
+        // For every knot (xval[i], yval[j]) of the grid, calculate corrected
+        // values fval_2
+        final double[][] fval_2 = new double[xLen][yLen];
+        for (int i = 0; i < xLen; i++) {
+            final PolynomialFunction f = xPolyY[i];
+            for (int j = 0; j < yLen; j++) {
+                fval_2[i][j] = f.value(yval[j]);
+            }
+        }
+
+        return super.interpolate(xval, yval, fval_2);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java
new file mode 100644
index 0000000..f25ba83
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java
@@ -0,0 +1,127 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NumberIsTooSmallException;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Computes a natural (also known as "free", "unclamped") cubic spline interpolation for the data set.
+ * <p>
+ * The {@link #interpolate(double[], double[])} method returns a {@link PolynomialSplineFunction}
+ * consisting of n cubic polynomials, defined over the subintervals determined by the x values,
+ * x[0] < x[i] ... < x[n].  The x values are referred to as "knot points."</p>
+ * <p>
+ * The value of the PolynomialSplineFunction at a point x that is greater than or equal to the smallest
+ * knot point and strictly less than the largest knot point is computed by finding the subinterval to which
+ * x belongs and computing the value of the corresponding polynomial at <code>x - x[i] </code> where
+ * <code>i</code> is the index of the subinterval.  See {@link PolynomialSplineFunction} for more details.
+ * </p>
+ * <p>
+ * The interpolating polynomials satisfy: <ol>
+ * <li>The value of the PolynomialSplineFunction at each of the input x values equals the
+ *  corresponding y value.</li>
+ * <li>Adjacent polynomials are equal through two derivatives at the knot points (i.e., adjacent polynomials
+ *  "match up" at the knot points, as do their first and second derivatives).</li>
+ * </ol></p>
+ * <p>
+ * The cubic spline interpolation algorithm implemented is as described in R.L. Burden, J.D. Faires,
+ * <u>Numerical Analysis</u>, 4th Ed., 1989, PWS-Kent, ISBN 0-53491-585-X, pp 126-131.
+ * </p>
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ *
+ */
+public class SplineInterpolator implements UnivariateRealInterpolator {
+
+    /**
+     * Computes an interpolating function for the data set.
+     * @param x the arguments for the interpolation points
+     * @param y the values for the interpolation points
+     * @return a function which interpolates the data set
+     * @throws DimensionMismatchException if {@code x} and {@code y}
+     * have different sizes.
+     * @throws org.apache.commons.math.exception.NonMonotonousSequenceException
+     * if {@code x} is not sorted in strict increasing order.
+     * @throws NumberIsTooSmallException if the size of {@code x} is smaller
+     * than 3.
+     */
+    public PolynomialSplineFunction interpolate(double x[], double y[]) {
+        if (x.length != y.length) {
+            throw new DimensionMismatchException(x.length, y.length);
+        }
+
+        if (x.length < 3) {
+            throw new NumberIsTooSmallException(LocalizedFormats.NUMBER_OF_POINTS,
+                                                x.length, 3, true);
+        }
+
+        // Number of intervals.  The number of data points is n + 1.
+        int n = x.length - 1;
+
+        MathUtils.checkOrder(x);
+
+        // Differences between knot points
+        double h[] = new double[n];
+        for (int i = 0; i < n; i++) {
+            h[i] = x[i + 1] - x[i];
+        }
+
+        double mu[] = new double[n];
+        double z[] = new double[n + 1];
+        mu[0] = 0d;
+        z[0] = 0d;
+        double g = 0;
+        for (int i = 1; i < n; i++) {
+            g = 2d * (x[i+1]  - x[i - 1]) - h[i - 1] * mu[i -1];
+            mu[i] = h[i] / g;
+            z[i] = (3d * (y[i + 1] * h[i - 1] - y[i] * (x[i + 1] - x[i - 1])+ y[i - 1] * h[i]) /
+                    (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g;
+        }
+
+        // cubic spline coefficients --  b is linear, c quadratic, d is cubic (original y's are constants)
+        double b[] = new double[n];
+        double c[] = new double[n + 1];
+        double d[] = new double[n];
+
+        z[n] = 0d;
+        c[n] = 0d;
+
+        for (int j = n -1; j >=0; j--) {
+            c[j] = z[j] - mu[j] * c[j + 1];
+            b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2d * c[j]) / 3d;
+            d[j] = (c[j + 1] - c[j]) / (3d * h[j]);
+        }
+
+        PolynomialFunction polynomials[] = new PolynomialFunction[n];
+        double coefficients[] = new double[4];
+        for (int i = 0; i < n; i++) {
+            coefficients[0] = y[i];
+            coefficients[1] = b[i];
+            coefficients[2] = c[i];
+            coefficients[3] = d[i];
+            polynomials[i] = new PolynomialFunction(coefficients);
+        }
+
+        return new PolynomialSplineFunction(x, polynomials);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolatingFunction.java b/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolatingFunction.java
new file mode 100644
index 0000000..ea435a3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolatingFunction.java
@@ -0,0 +1,483 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.analysis.TrivariateRealFunction;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.exception.OutOfRangeException;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Function that implements the
+ * <a href="http://en.wikipedia.org/wiki/Tricubic_interpolation">
+ * tricubic spline interpolation</a>, as proposed in
+ * <quote>
+ *  Tricubic interpolation in three dimensions<br/>
+ *  F. Lekien and J. Marsden<br/>
+ *  <em>Int. J. Numer. Meth. Engng</em> 2005; <b>63</b>:455-471
+ * </quote>
+ *
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class TricubicSplineInterpolatingFunction
+    implements TrivariateRealFunction {
+    /**
+     * Matrix to compute the spline coefficients from the function values
+     * and function derivatives values
+     */
+    private static final double[][] AINV = {
+        { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { -3,3,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 2,-2,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { -3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 9,-9,-9,9,0,0,0,0,6,3,-6,-3,0,0,0,0,6,-6,3,-3,0,0,0,0,0,0,0,0,0,0,0,0,4,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { -6,6,6,-6,0,0,0,0,-3,-3,3,3,0,0,0,0,-4,4,-2,2,0,0,0,0,0,0,0,0,0,0,0,0,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { -6,6,6,-6,0,0,0,0,-4,-2,4,2,0,0,0,0,-3,3,-3,3,0,0,0,0,0,0,0,0,0,0,0,0,-2,-1,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 4,-4,-4,4,0,0,0,0,2,2,-2,-2,0,0,0,0,2,-2,2,-2,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,0,0,0,0,-2,-1,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,0,0,0,0,1,1,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-9,-9,9,0,0,0,0,0,0,0,0,0,0,0,0,6,3,-6,-3,0,0,0,0,6,-6,3,-3,0,0,0,0,4,2,2,1,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,6,-6,0,0,0,0,0,0,0,0,0,0,0,0,-3,-3,3,3,0,0,0,0,-4,4,-2,2,0,0,0,0,-2,-2,-1,-1,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,6,-6,0,0,0,0,0,0,0,0,0,0,0,0,-4,-2,4,2,0,0,0,0,-3,3,-3,3,0,0,0,0,-2,-1,-2,-1,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,-4,-4,4,0,0,0,0,0,0,0,0,0,0,0,0,2,2,-2,-2,0,0,0,0,2,-2,2,-2,0,0,0,0,1,1,1,1,0,0,0,0 },
+        {-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 9,-9,0,0,-9,9,0,0,6,3,0,0,-6,-3,0,0,0,0,0,0,0,0,0,0,6,-6,0,0,3,-3,0,0,0,0,0,0,0,0,0,0,4,2,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { -6,6,0,0,6,-6,0,0,-3,-3,0,0,3,3,0,0,0,0,0,0,0,0,0,0,-4,4,0,0,-2,2,0,0,0,0,0,0,0,0,0,0,-2,-2,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,0,0,-1,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,-9,0,0,-9,9,0,0,0,0,0,0,0,0,0,0,6,3,0,0,-6,-3,0,0,0,0,0,0,0,0,0,0,6,-6,0,0,3,-3,0,0,4,2,0,0,2,1,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,0,0,6,-6,0,0,0,0,0,0,0,0,0,0,-3,-3,0,0,3,3,0,0,0,0,0,0,0,0,0,0,-4,4,0,0,-2,2,0,0,-2,-2,0,0,-1,-1,0,0 },
+        { 9,0,-9,0,-9,0,9,0,0,0,0,0,0,0,0,0,6,0,3,0,-6,0,-3,0,6,0,-6,0,3,0,-3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,2,0,2,0,1,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,9,0,-9,0,-9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,3,0,-6,0,-3,0,6,0,-6,0,3,0,-3,0,0,0,0,0,0,0,0,0,4,0,2,0,2,0,1,0 },
+        { -27,27,27,-27,27,-27,-27,27,-18,-9,18,9,18,9,-18,-9,-18,18,-9,9,18,-18,9,-9,-18,18,18,-18,-9,9,9,-9,-12,-6,-6,-3,12,6,6,3,-12,-6,12,6,-6,-3,6,3,-12,12,-6,6,-6,6,-3,3,-8,-4,-4,-2,-4,-2,-2,-1 },
+        { 18,-18,-18,18,-18,18,18,-18,9,9,-9,-9,-9,-9,9,9,12,-12,6,-6,-12,12,-6,6,12,-12,-12,12,6,-6,-6,6,6,6,3,3,-6,-6,-3,-3,6,6,-6,-6,3,3,-3,-3,8,-8,4,-4,4,-4,2,-2,4,4,2,2,2,2,1,1 },
+        { -6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,-3,0,-3,0,3,0,3,0,-4,0,4,0,-2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-2,0,-1,0,-1,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,-6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-3,0,-3,0,3,0,3,0,-4,0,4,0,-2,0,2,0,0,0,0,0,0,0,0,0,-2,0,-2,0,-1,0,-1,0 },
+        { 18,-18,-18,18,-18,18,18,-18,12,6,-12,-6,-12,-6,12,6,9,-9,9,-9,-9,9,-9,9,12,-12,-12,12,6,-6,-6,6,6,3,6,3,-6,-3,-6,-3,8,4,-8,-4,4,2,-4,-2,6,-6,6,-6,3,-3,3,-3,4,2,4,2,2,1,2,1 },
+        { -12,12,12,-12,12,-12,-12,12,-6,-6,6,6,6,6,-6,-6,-6,6,-6,6,6,-6,6,-6,-8,8,8,-8,-4,4,4,-4,-3,-3,-3,-3,3,3,3,3,-4,-4,4,4,-2,-2,2,2,-4,4,-4,4,-2,2,-2,2,-2,-2,-2,-2,-1,-1,-1,-1 },
+        { 2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { -6,6,0,0,6,-6,0,0,-4,-2,0,0,4,2,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,-3,3,0,0,0,0,0,0,0,0,0,0,-2,-1,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 4,-4,0,0,-4,4,0,0,2,2,0,0,-2,-2,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,2,-2,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-6,6,0,0,6,-6,0,0,0,0,0,0,0,0,0,0,-4,-2,0,0,4,2,0,0,0,0,0,0,0,0,0,0,-3,3,0,0,-3,3,0,0,-2,-1,0,0,-2,-1,0,0 },
+        { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,-4,0,0,-4,4,0,0,0,0,0,0,0,0,0,0,2,2,0,0,-2,-2,0,0,0,0,0,0,0,0,0,0,2,-2,0,0,2,-2,0,0,1,1,0,0,1,1,0,0 },
+        { -6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,-4,0,-2,0,4,0,2,0,-3,0,3,0,-3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,0,-1,0,-2,0,-1,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,-6,0,6,0,6,0,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,0,-2,0,4,0,2,0,-3,0,3,0,-3,0,3,0,0,0,0,0,0,0,0,0,-2,0,-1,0,-2,0,-1,0 },
+        { 18,-18,-18,18,-18,18,18,-18,12,6,-12,-6,-12,-6,12,6,12,-12,6,-6,-12,12,-6,6,9,-9,-9,9,9,-9,-9,9,8,4,4,2,-8,-4,-4,-2,6,3,-6,-3,6,3,-6,-3,6,-6,3,-3,6,-6,3,-3,4,2,2,1,4,2,2,1 },
+        { -12,12,12,-12,12,-12,-12,12,-6,-6,6,6,6,6,-6,-6,-8,8,-4,4,8,-8,4,-4,-6,6,6,-6,-6,6,6,-6,-4,-4,-2,-2,4,4,2,2,-3,-3,3,3,-3,-3,3,3,-4,4,-2,2,-4,4,-2,2,-2,-2,-1,-1,-2,-2,-1,-1 },
+        { 4,0,-4,0,-4,0,4,0,0,0,0,0,0,0,0,0,2,0,2,0,-2,0,-2,0,2,0,-2,0,2,0,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0 },
+        { 0,0,0,0,0,0,0,0,4,0,-4,0,-4,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,-2,0,-2,0,2,0,-2,0,2,0,-2,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0 },
+        { -12,12,12,-12,12,-12,-12,12,-8,-4,8,4,8,4,-8,-4,-6,6,-6,6,6,-6,6,-6,-6,6,6,-6,-6,6,6,-6,-4,-2,-4,-2,4,2,4,2,-4,-2,4,2,-4,-2,4,2,-3,3,-3,3,-3,3,-3,3,-2,-1,-2,-1,-2,-1,-2,-1 },
+        { 8,-8,-8,8,-8,8,8,-8,4,4,-4,-4,-4,-4,4,4,4,-4,4,-4,-4,4,-4,4,4,-4,-4,4,4,-4,-4,4,2,2,2,2,-2,-2,-2,-2,2,2,-2,-2,2,2,-2,-2,2,-2,2,-2,2,-2,2,-2,1,1,1,1,1,1,1,1 }
+    };
+
+    /** Samples x-coordinates */
+    private final double[] xval;
+    /** Samples y-coordinates */
+    private final double[] yval;
+    /** Samples z-coordinates */
+    private final double[] zval;
+    /** Set of cubic splines pacthing the whole data grid */
+    private final TricubicSplineFunction[][][] splines;
+
+    /**
+     * @param x Sample values of the x-coordinate, in increasing order.
+     * @param y Sample values of the y-coordinate, in increasing order.
+     * @param z Sample values of the y-coordinate, in increasing order.
+     * @param f Values of the function on every grid point.
+     * @param dFdX Values of the partial derivative of function with respect
+     * to x on every grid point.
+     * @param dFdY Values of the partial derivative of function with respect
+     * to y on every grid point.
+     * @param dFdZ Values of the partial derivative of function with respect
+     * to z on every grid point.
+     * @param d2FdXdY Values of the cross partial derivative of function on
+     * every grid point.
+     * @param d2FdXdZ Values of the cross partial derivative of function on
+     * every grid point.
+     * @param d2FdYdZ Values of the cross partial derivative of function on
+     * every grid point.
+     * @param d3FdXdYdZ Values of the cross partial derivative of function on
+     * every grid point.
+     * @throws NoDataException if any of the arrays has zero length.
+     * @throws DimensionMismatchException if the various arrays do not contain
+     * the expected number of elements.
+     * @throws IllegalArgumentException if {@code x}, {@code y} or {@code z}
+     * are not strictly increasing.
+     */
+    public TricubicSplineInterpolatingFunction(double[] x,
+                                               double[] y,
+                                               double[] z,
+                                               double[][][] f,
+                                               double[][][] dFdX,
+                                               double[][][] dFdY,
+                                               double[][][] dFdZ,
+                                               double[][][] d2FdXdY,
+                                               double[][][] d2FdXdZ,
+                                               double[][][] d2FdYdZ,
+                                               double[][][] d3FdXdYdZ) {
+        final int xLen = x.length;
+        final int yLen = y.length;
+        final int zLen = z.length;
+
+        if (xLen == 0 || yLen == 0 || z.length == 0 || f.length == 0 || f[0].length == 0) {
+            throw new NoDataException();
+        }
+        if (xLen != f.length) {
+            throw new DimensionMismatchException(xLen, f.length);
+        }
+        if (xLen != dFdX.length) {
+            throw new DimensionMismatchException(xLen, dFdX.length);
+        }
+        if (xLen != dFdY.length) {
+            throw new DimensionMismatchException(xLen, dFdY.length);
+        }
+        if (xLen != dFdZ.length) {
+            throw new DimensionMismatchException(xLen, dFdZ.length);
+        }
+        if (xLen != d2FdXdY.length) {
+            throw new DimensionMismatchException(xLen, d2FdXdY.length);
+        }
+        if (xLen != d2FdXdZ.length) {
+            throw new DimensionMismatchException(xLen, d2FdXdZ.length);
+        }
+        if (xLen != d2FdYdZ.length) {
+            throw new DimensionMismatchException(xLen, d2FdYdZ.length);
+        }
+        if (xLen != d3FdXdYdZ.length) {
+            throw new DimensionMismatchException(xLen, d3FdXdYdZ.length);
+        }
+
+        MathUtils.checkOrder(x);
+        MathUtils.checkOrder(y);
+        MathUtils.checkOrder(z);
+
+        xval = x.clone();
+        yval = y.clone();
+        zval = z.clone();
+
+        final int lastI = xLen - 1;
+        final int lastJ = yLen - 1;
+        final int lastK = zLen - 1;
+        splines = new TricubicSplineFunction[lastI][lastJ][lastK];
+
+        for (int i = 0; i < lastI; i++) {
+            if (f[i].length != yLen) {
+                throw new DimensionMismatchException(f[i].length, yLen);
+            }
+            if (dFdX[i].length != yLen) {
+                throw new DimensionMismatchException(dFdX[i].length, yLen);
+            }
+            if (dFdY[i].length != yLen) {
+                throw new DimensionMismatchException(dFdY[i].length, yLen);
+            }
+            if (dFdZ[i].length != yLen) {
+                throw new DimensionMismatchException(dFdZ[i].length, yLen);
+            }
+            if (d2FdXdY[i].length != yLen) {
+                throw new DimensionMismatchException(d2FdXdY[i].length, yLen);
+            }
+            if (d2FdXdZ[i].length != yLen) {
+                throw new DimensionMismatchException(d2FdXdZ[i].length, yLen);
+            }
+            if (d2FdYdZ[i].length != yLen) {
+                throw new DimensionMismatchException(d2FdYdZ[i].length, yLen);
+            }
+            if (d3FdXdYdZ[i].length != yLen) {
+                throw new DimensionMismatchException(d3FdXdYdZ[i].length, yLen);
+            }
+
+            final int ip1 = i + 1;
+            for (int j = 0; j < lastJ; j++) {
+                if (f[i][j].length != zLen) {
+                    throw new DimensionMismatchException(f[i][j].length, zLen);
+                }
+                if (dFdX[i][j].length != zLen) {
+                    throw new DimensionMismatchException(dFdX[i][j].length, zLen);
+                }
+                if (dFdY[i][j].length != zLen) {
+                    throw new DimensionMismatchException(dFdY[i][j].length, zLen);
+                }
+                if (dFdZ[i][j].length != zLen) {
+                    throw new DimensionMismatchException(dFdZ[i][j].length, zLen);
+                }
+                if (d2FdXdY[i][j].length != zLen) {
+                    throw new DimensionMismatchException(d2FdXdY[i][j].length, zLen);
+                }
+                if (d2FdXdZ[i][j].length != zLen) {
+                    throw new DimensionMismatchException(d2FdXdZ[i][j].length, zLen);
+                }
+                if (d2FdYdZ[i][j].length != zLen) {
+                    throw new DimensionMismatchException(d2FdYdZ[i][j].length, zLen);
+                }
+                if (d3FdXdYdZ[i][j].length != zLen) {
+                    throw new DimensionMismatchException(d3FdXdYdZ[i][j].length, zLen);
+                }
+
+                final int jp1 = j + 1;
+                for (int k = 0; k < lastK; k++) {
+                    final int kp1 = k + 1;
+
+                    final double[] beta = new double[] {
+                        f[i][j][k], f[ip1][j][k],
+                        f[i][jp1][k], f[ip1][jp1][k],
+                        f[i][j][kp1], f[ip1][j][kp1],
+                        f[i][jp1][kp1], f[ip1][jp1][kp1],
+
+                        dFdX[i][j][k], dFdX[ip1][j][k],
+                        dFdX[i][jp1][k], dFdX[ip1][jp1][k],
+                        dFdX[i][j][kp1], dFdX[ip1][j][kp1],
+                        dFdX[i][jp1][kp1], dFdX[ip1][jp1][kp1],
+
+                        dFdY[i][j][k], dFdY[ip1][j][k],
+                        dFdY[i][jp1][k], dFdY[ip1][jp1][k],
+                        dFdY[i][j][kp1], dFdY[ip1][j][kp1],
+                        dFdY[i][jp1][kp1], dFdY[ip1][jp1][kp1],
+
+                        dFdZ[i][j][k], dFdZ[ip1][j][k],
+                        dFdZ[i][jp1][k], dFdZ[ip1][jp1][k],
+                        dFdZ[i][j][kp1], dFdZ[ip1][j][kp1],
+                        dFdZ[i][jp1][kp1], dFdZ[ip1][jp1][kp1],
+
+                        d2FdXdY[i][j][k], d2FdXdY[ip1][j][k],
+                        d2FdXdY[i][jp1][k], d2FdXdY[ip1][jp1][k],
+                        d2FdXdY[i][j][kp1], d2FdXdY[ip1][j][kp1],
+                        d2FdXdY[i][jp1][kp1], d2FdXdY[ip1][jp1][kp1],
+
+                        d2FdXdZ[i][j][k], d2FdXdZ[ip1][j][k],
+                        d2FdXdZ[i][jp1][k], d2FdXdZ[ip1][jp1][k],
+                        d2FdXdZ[i][j][kp1], d2FdXdZ[ip1][j][kp1],
+                        d2FdXdZ[i][jp1][kp1], d2FdXdZ[ip1][jp1][kp1],
+
+                        d2FdYdZ[i][j][k], d2FdYdZ[ip1][j][k],
+                        d2FdYdZ[i][jp1][k], d2FdYdZ[ip1][jp1][k],
+                        d2FdYdZ[i][j][kp1], d2FdYdZ[ip1][j][kp1],
+                        d2FdYdZ[i][jp1][kp1], d2FdYdZ[ip1][jp1][kp1],
+
+                        d3FdXdYdZ[i][j][k], d3FdXdYdZ[ip1][j][k],
+                        d3FdXdYdZ[i][jp1][k], d3FdXdYdZ[ip1][jp1][k],
+                        d3FdXdYdZ[i][j][kp1], d3FdXdYdZ[ip1][j][kp1],
+                        d3FdXdYdZ[i][jp1][kp1], d3FdXdYdZ[ip1][jp1][kp1],
+                    };
+
+                    splines[i][j][k] = new TricubicSplineFunction(computeSplineCoefficients(beta));
+                }
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double value(double x, double y, double z) {
+        final int i = searchIndex(x, xval);
+        if (i == -1) {
+            throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]);
+        }
+        final int j = searchIndex(y, yval);
+        if (j == -1) {
+            throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]);
+        }
+        final int k = searchIndex(z, zval);
+        if (k == -1) {
+            throw new OutOfRangeException(z, zval[0], zval[zval.length - 1]);
+        }
+
+        final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]);
+        final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]);
+        final double zN = (z - zval[k]) / (zval[k + 1] - zval[k]);
+
+        return splines[i][j][k].value(xN, yN, zN);
+    }
+
+    /**
+     * @param c Coordinate.
+     * @param val Coordinate samples.
+     * @return the index in {@code val} corresponding to the interval
+     * containing {@code c}, or {@code -1} if {@code c} is out of the
+     * range defined by the end values of {@code val}.
+     */
+    private int searchIndex(double c, double[] val) {
+        if (c < val[0]) {
+            return -1;
+        }
+
+        final int max = val.length;
+        for (int i = 1; i < max; i++) {
+            if (c <= val[i]) {
+                return i - 1;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Compute the spline coefficients from the list of function values and
+     * function partial derivatives values at the four corners of a grid
+     * element. They must be specified in the following order:
+     * <ul>
+     *  <li>f(0,0,0)</li>
+     *  <li>f(1,0,0)</li>
+     *  <li>f(0,1,0)</li>
+     *  <li>f(1,1,0)</li>
+     *  <li>f(0,0,1)</li>
+     *  <li>f(1,0,1)</li>
+     *  <li>f(0,1,1)</li>
+     *  <li>f(1,1,1)</li>
+     *
+     *  <li>f<sub>x</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>x</sub>(1,1,1)</li>
+     *
+     *  <li>f<sub>y</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>y</sub>(1,1,1)</li>
+     *
+     *  <li>f<sub>z</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>z</sub>(1,1,1)</li>
+     *
+     *  <li>f<sub>xy</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>xy</sub>(1,1,1)</li>
+     *
+     *  <li>f<sub>xz</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>xz</sub>(1,1,1)</li>
+     *
+     *  <li>f<sub>yz</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>yz</sub>(1,1,1)</li>
+     *
+     *  <li>f<sub>xyz</sub>(0,0,0)</li>
+     *  <li>... <em>(same order as above)</em></li>
+     *  <li>f<sub>xyz</sub>(1,1,1)</li>
+     * </ul>
+     * where the subscripts indicate the partial derivative with respect to
+     * the corresponding variable(s).
+     *
+     * @param beta List of function values and function partial derivatives
+     * values.
+     * @return the spline coefficients.
+     */
+    private double[] computeSplineCoefficients(double[] beta) {
+        final int sz = 64;
+        final double[] a = new double[sz];
+
+        for (int i = 0; i < sz; i++) {
+            double result = 0;
+            final double[] row = AINV[i];
+            for (int j = 0; j < sz; j++) {
+                result += row[j] * beta[j];
+            }
+            a[i] = result;
+        }
+
+        return a;
+    }
+}
+
+/**
+ * 3D-spline function.
+ *
+ * @version $Revision$ $Date$
+ */
+class TricubicSplineFunction
+    implements TrivariateRealFunction {
+    /** Number of points. */
+    private static final short N = 4;
+    /** Coefficients */
+    private final double[][][] a = new double[N][N][N];
+
+    /**
+     * @param aV List of spline coefficients.
+     */
+    public TricubicSplineFunction(double[] aV) {
+        for (int i = 0; i < N; i++) {
+            for (int j = 0; j < N; j++) {
+                for (int k = 0; k < N; k++) {
+                    a[i][j][k] = aV[i + N * (j + N * k)];
+                }
+            }
+        }
+    }
+
+    /**
+     * @param x x-coordinate of the interpolation point.
+     * @param y y-coordinate of the interpolation point.
+     * @param z z-coordinate of the interpolation point.
+     * @return the interpolated value.
+     */
+    public double value(double x, double y, double z) {
+        if (x < 0 || x > 1) {
+            throw new OutOfRangeException(x, 0, 1);
+        }
+        if (y < 0 || y > 1) {
+            throw new OutOfRangeException(y, 0, 1);
+        }
+        if (z < 0 || z > 1) {
+            throw new OutOfRangeException(z, 0, 1);
+        }
+
+        final double x2 = x * x;
+        final double x3 = x2 * x;
+        final double[] pX = { 1, x, x2, x3 };
+
+        final double y2 = y * y;
+        final double y3 = y2 * y;
+        final double[] pY = { 1, y, y2, y3 };
+
+        final double z2 = z * z;
+        final double z3 = z2 * z;
+        final double[] pZ = { 1, z, z2, z3 };
+
+        double result = 0;
+        for (int i = 0; i < N; i++) {
+            for (int j = 0; j < N; j++) {
+                for (int k = 0; k < N; k++) {
+                    result += a[i][j][k] * pX[i] * pY[j] * pZ[k];
+                }
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolator.java
new file mode 100644
index 0000000..dac7f26
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/TricubicSplineInterpolator.java
@@ -0,0 +1,198 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Generates a tricubic interpolating function.
+ *
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class TricubicSplineInterpolator
+    implements TrivariateRealGridInterpolator {
+    /**
+     * {@inheritDoc}
+     */
+    public TricubicSplineInterpolatingFunction interpolate(final double[] xval,
+                                                           final double[] yval,
+                                                           final double[] zval,
+                                                           final double[][][] fval)
+        throws MathException {
+        if (xval.length == 0 || yval.length == 0 || zval.length == 0 || fval.length == 0) {
+            throw new NoDataException();
+        }
+        if (xval.length != fval.length) {
+            throw new DimensionMismatchException(xval.length, fval.length);
+        }
+
+        MathUtils.checkOrder(xval);
+        MathUtils.checkOrder(yval);
+        MathUtils.checkOrder(zval);
+
+        final int xLen = xval.length;
+        final int yLen = yval.length;
+        final int zLen = zval.length;
+
+        // Samples, re-ordered as (z, x, y) and (y, z, x) tuplets
+        // fvalXY[k][i][j] = f(xval[i], yval[j], zval[k])
+        // fvalZX[j][k][i] = f(xval[i], yval[j], zval[k])
+        final double[][][] fvalXY = new double[zLen][xLen][yLen];
+        final double[][][] fvalZX = new double[yLen][zLen][xLen];
+        for (int i = 0; i < xLen; i++) {
+            if (fval[i].length != yLen) {
+                throw new DimensionMismatchException(fval[i].length, yLen);
+            }
+
+            for (int j = 0; j < yLen; j++) {
+                if (fval[i][j].length != zLen) {
+                    throw new DimensionMismatchException(fval[i][j].length, zLen);
+                }
+
+                for (int k = 0; k < zLen; k++) {
+                    final double v = fval[i][j][k];
+                    fvalXY[k][i][j] = v;
+                    fvalZX[j][k][i] = v;
+                }
+            }
+        }
+
+        final BicubicSplineInterpolator bsi = new BicubicSplineInterpolator();
+
+        // For each line x[i] (0 <= i < xLen), construct a 2D spline in y and z
+        final BicubicSplineInterpolatingFunction[] xSplineYZ
+            = new BicubicSplineInterpolatingFunction[xLen];
+        for (int i = 0; i < xLen; i++) {
+            xSplineYZ[i] = bsi.interpolate(yval, zval, fval[i]);
+        }
+
+        // For each line y[j] (0 <= j < yLen), construct a 2D spline in z and x
+        final BicubicSplineInterpolatingFunction[] ySplineZX
+            = new BicubicSplineInterpolatingFunction[yLen];
+        for (int j = 0; j < yLen; j++) {
+            ySplineZX[j] = bsi.interpolate(zval, xval, fvalZX[j]);
+        }
+
+        // For each line z[k] (0 <= k < zLen), construct a 2D spline in x and y
+        final BicubicSplineInterpolatingFunction[] zSplineXY
+            = new BicubicSplineInterpolatingFunction[zLen];
+        for (int k = 0; k < zLen; k++) {
+            zSplineXY[k] = bsi.interpolate(xval, yval, fvalXY[k]);
+        }
+
+        // Partial derivatives wrt x and wrt y
+        final double[][][] dFdX = new double[xLen][yLen][zLen];
+        final double[][][] dFdY = new double[xLen][yLen][zLen];
+        final double[][][] d2FdXdY = new double[xLen][yLen][zLen];
+        for (int k = 0; k < zLen; k++) {
+            final BicubicSplineInterpolatingFunction f = zSplineXY[k];
+            for (int i = 0; i < xLen; i++) {
+                final double x = xval[i];
+                for (int j = 0; j < yLen; j++) {
+                    final double y = yval[j];
+                    dFdX[i][j][k] = f.partialDerivativeX(x, y);
+                    dFdY[i][j][k] = f.partialDerivativeY(x, y);
+                    d2FdXdY[i][j][k] = f.partialDerivativeXY(x, y);
+                }
+            }
+        }
+
+        // Partial derivatives wrt y and wrt z
+        final double[][][] dFdZ = new double[xLen][yLen][zLen];
+        final double[][][] d2FdYdZ = new double[xLen][yLen][zLen];
+        for (int i = 0; i < xLen; i++) {
+            final BicubicSplineInterpolatingFunction f = xSplineYZ[i];
+            for (int j = 0; j < yLen; j++) {
+                final double y = yval[j];
+                for (int k = 0; k < zLen; k++) {
+                    final double z = zval[k];
+                    dFdZ[i][j][k] = f.partialDerivativeY(y, z);
+                    d2FdYdZ[i][j][k] = f.partialDerivativeXY(y, z);
+                }
+            }
+        }
+
+        // Partial derivatives wrt x and wrt z
+        final double[][][] d2FdZdX = new double[xLen][yLen][zLen];
+        for (int j = 0; j < yLen; j++) {
+            final BicubicSplineInterpolatingFunction f = ySplineZX[j];
+            for (int k = 0; k < zLen; k++) {
+                final double z = zval[k];
+                for (int i = 0; i < xLen; i++) {
+                    final double x = xval[i];
+                    d2FdZdX[i][j][k] = f.partialDerivativeXY(z, x);
+                }
+            }
+        }
+
+        // Third partial cross-derivatives
+        final double[][][] d3FdXdYdZ = new double[xLen][yLen][zLen];
+        for (int i = 0; i < xLen ; i++) {
+            final int nI = nextIndex(i, xLen);
+            final int pI = previousIndex(i);
+            for (int j = 0; j < yLen; j++) {
+                final int nJ = nextIndex(j, yLen);
+                final int pJ = previousIndex(j);
+                for (int k = 0; k < zLen; k++) {
+                    final int nK = nextIndex(k, zLen);
+                    final int pK = previousIndex(k);
+
+                    // XXX Not sure about this formula
+                    d3FdXdYdZ[i][j][k] = (fval[nI][nJ][nK] - fval[nI][pJ][nK] -
+                                          fval[pI][nJ][nK] + fval[pI][pJ][nK] -
+                                          fval[nI][nJ][pK] + fval[nI][pJ][pK] +
+                                          fval[pI][nJ][pK] - fval[pI][pJ][pK]) /
+                        ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ]) * (zval[nK] - zval[pK])) ;
+                }
+            }
+        }
+
+        // Create the interpolating splines
+        return new TricubicSplineInterpolatingFunction(xval, yval, zval, fval,
+                                                       dFdX, dFdY, dFdZ,
+                                                       d2FdXdY, d2FdZdX, d2FdYdZ,
+                                                       d3FdXdYdZ);
+    }
+
+    /**
+     * Compute the next index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is larger than or equal to 0}.
+     *
+     * @param i Index
+     * @param max Upper limit of the array
+     * @return the next index
+     */
+    private int nextIndex(int i, int max) {
+        final int index = i + 1;
+        return index < max ? index : index - 1;
+    }
+    /**
+     * Compute the previous index of an array, clipping if necessary.
+     * It is assumed (but not checked) that {@code i} is smaller than the size of the array.
+     *
+     * @param i Index
+     * @return the previous index
+     */
+    private int previousIndex(int i) {
+        final int index = i - 1;
+        return index >= 0 ? index : 0;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/TrivariateRealGridInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/TrivariateRealGridInterpolator.java
new file mode 100644
index 0000000..c42d7aa
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/TrivariateRealGridInterpolator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.TrivariateRealFunction;
+
+/**
+ * Interface representing a trivariate real interpolating function where the
+ * sample points must be specified on a regular grid.
+ *
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public interface TrivariateRealGridInterpolator {
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param xval All the x-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param yval All the y-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param zval All the z-coordinates of the interpolation points, sorted
+     * in increasing order.
+     * @param fval the values of the interpolation points on all the grid knots:
+     * {@code fval[i][j][k] = f(xval[i], yval[j], zval[k])}.
+     * @return a function that interpolates the data set.
+     * @throws org.apache.commons.math.exception.NoDataException if any of the arrays has zero length.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException if the array lengths are inconsistent.
+     * @throws MathException if arguments violate assumptions made by the
+     *         interpolation algorithm.
+     */
+    TrivariateRealFunction interpolate(double[] xval, double[] yval, double[] zval, double[][][] fval)
+        throws MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java b/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java
new file mode 100644
index 0000000..09f5487
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.analysis.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+/**
+ * Interface representing a univariate real interpolating function.
+ *
+ * @version $Revision: 821626 $ $Date: 2009-10-04 23:57:30 +0200 (dim. 04 oct. 2009) $
+ */
+public interface UnivariateRealInterpolator {
+
+    /**
+     * Computes an interpolating function for the data set.
+     * @param xval the arguments for the interpolation points
+     * @param yval the values for the interpolation points
+     * @return a function which interpolates the data set
+     * @throws MathException if arguments violate assumptions made by the
+     *         interpolation algorithm
+     */
+    UnivariateRealFunction interpolate(double xval[], double yval[])
+        throws MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/interpolation/package.html b/src/main/java/org/apache/commons/math/analysis/interpolation/package.html
new file mode 100644
index 0000000..136c576
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/interpolation/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+     Univariate real functions interpolation algorithms.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/analysis/package.html b/src/main/java/org/apache/commons/math/analysis/package.html
new file mode 100644
index 0000000..63b64a8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/package.html
@@ -0,0 +1,33 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+  <body>
+    <p>
+      Parent package for common numerical analysis procedures, including root finding,
+      function interpolation and integration. Note that the optimization (i.e. minimization
+      and maximization) is a huge separate top package, despite it also operate on functions
+      as defined by this top-level package.
+    </p>
+    <p>
+      Functions interfaces are intended to be implemented by user code to represent their
+      domain problems. The algorithms provided by the library will then operate on these
+      function to find their roots, or integrate them, or ... Functions can be multivariate
+      or univariate, real vectorial or matrix valued, and they can be differentiable or not.
+    </p>
+  </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java
new file mode 100644
index 0000000..ec528b4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunction.java
@@ -0,0 +1,350 @@
+/*
+ * 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.analysis.polynomials;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Immutable representation of a real polynomial function with real coefficients.
+ * <p>
+ * <a href="http://mathworld.wolfram.com/HornersMethod.html">Horner's Method</a>
+ *  is used to evaluate the function.</p>
+ *
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ */
+public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable {
+
+    /**
+     * Serialization identifier
+     */
+    private static final long serialVersionUID = -7726511984200295583L;
+
+    /**
+     * The coefficients of the polynomial, ordered by degree -- i.e.,
+     * coefficients[0] is the constant term and coefficients[n] is the
+     * coefficient of x^n where n is the degree of the polynomial.
+     */
+    private final double coefficients[];
+
+    /**
+     * Construct a polynomial with the given coefficients.  The first element
+     * of the coefficients array is the constant term.  Higher degree
+     * coefficients follow in sequence.  The degree of the resulting polynomial
+     * is the index of the last non-null element of the array, or 0 if all elements
+     * are null.
+     * <p>
+     * The constructor makes a copy of the input array and assigns the copy to
+     * the coefficients property.</p>
+     *
+     * @param c polynomial coefficients
+     * @throws NullPointerException if c is null
+     * @throws NoDataException if c is empty
+     */
+    public PolynomialFunction(double c[]) {
+        super();
+        int n = c.length;
+        if (n == 0) {
+            throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
+        }
+        while ((n > 1) && (c[n - 1] == 0)) {
+            --n;
+        }
+        this.coefficients = new double[n];
+        System.arraycopy(c, 0, this.coefficients, 0, n);
+    }
+
+    /**
+     * Compute the value of the function for the given argument.
+     * <p>
+     *  The value returned is <br>
+     *   <code>coefficients[n] * x^n + ... + coefficients[1] * x  + coefficients[0]</code>
+     * </p>
+     *
+     * @param x the argument for which the function value should be computed
+     * @return the value of the polynomial at the given point
+     * @see UnivariateRealFunction#value(double)
+     */
+    public double value(double x) {
+       return evaluate(coefficients, x);
+    }
+
+
+    /**
+     *  Returns the degree of the polynomial
+     *
+     * @return the degree of the polynomial
+     */
+    public int degree() {
+        return coefficients.length - 1;
+    }
+
+    /**
+     * Returns a copy of the coefficients array.
+     * <p>
+     * Changes made to the returned copy will not affect the coefficients of
+     * the polynomial.</p>
+     *
+     * @return  a fresh copy of the coefficients array
+     */
+    public double[] getCoefficients() {
+        return coefficients.clone();
+    }
+
+    /**
+     * Uses Horner's Method to evaluate the polynomial with the given coefficients at
+     * the argument.
+     *
+     * @param coefficients  the coefficients of the polynomial to evaluate
+     * @param argument  the input value
+     * @return  the value of the polynomial
+     * @throws NoDataException if coefficients is empty
+     * @throws NullPointerException if coefficients is null
+     */
+    protected static double evaluate(double[] coefficients, double argument) {
+        int n = coefficients.length;
+        if (n == 0) {
+            throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
+        }
+        double result = coefficients[n - 1];
+        for (int j = n -2; j >=0; j--) {
+            result = argument * result + coefficients[j];
+        }
+        return result;
+    }
+
+    /**
+     * Add a polynomial to the instance.
+     * @param p polynomial to add
+     * @return a new polynomial which is the sum of the instance and p
+     */
+    public PolynomialFunction add(final PolynomialFunction p) {
+
+        // identify the lowest degree polynomial
+        final int lowLength  = FastMath.min(coefficients.length, p.coefficients.length);
+        final int highLength = FastMath.max(coefficients.length, p.coefficients.length);
+
+        // build the coefficients array
+        double[] newCoefficients = new double[highLength];
+        for (int i = 0; i < lowLength; ++i) {
+            newCoefficients[i] = coefficients[i] + p.coefficients[i];
+        }
+        System.arraycopy((coefficients.length < p.coefficients.length) ?
+                         p.coefficients : coefficients,
+                         lowLength,
+                         newCoefficients, lowLength,
+                         highLength - lowLength);
+
+        return new PolynomialFunction(newCoefficients);
+
+    }
+
+    /**
+     * Subtract a polynomial from the instance.
+     * @param p polynomial to subtract
+     * @return a new polynomial which is the difference the instance minus p
+     */
+    public PolynomialFunction subtract(final PolynomialFunction p) {
+
+        // identify the lowest degree polynomial
+        int lowLength  = FastMath.min(coefficients.length, p.coefficients.length);
+        int highLength = FastMath.max(coefficients.length, p.coefficients.length);
+
+        // build the coefficients array
+        double[] newCoefficients = new double[highLength];
+        for (int i = 0; i < lowLength; ++i) {
+            newCoefficients[i] = coefficients[i] - p.coefficients[i];
+        }
+        if (coefficients.length < p.coefficients.length) {
+            for (int i = lowLength; i < highLength; ++i) {
+                newCoefficients[i] = -p.coefficients[i];
+            }
+        } else {
+            System.arraycopy(coefficients, lowLength, newCoefficients, lowLength,
+                             highLength - lowLength);
+        }
+
+        return new PolynomialFunction(newCoefficients);
+
+    }
+
+    /**
+     * Negate the instance.
+     * @return a new polynomial
+     */
+    public PolynomialFunction negate() {
+        double[] newCoefficients = new double[coefficients.length];
+        for (int i = 0; i < coefficients.length; ++i) {
+            newCoefficients[i] = -coefficients[i];
+        }
+        return new PolynomialFunction(newCoefficients);
+    }
+
+    /**
+     * Multiply the instance by a polynomial.
+     * @param p polynomial to multiply by
+     * @return a new polynomial
+     */
+    public PolynomialFunction multiply(final PolynomialFunction p) {
+
+        double[] newCoefficients = new double[coefficients.length + p.coefficients.length - 1];
+
+        for (int i = 0; i < newCoefficients.length; ++i) {
+            newCoefficients[i] = 0.0;
+            for (int j = FastMath.max(0, i + 1 - p.coefficients.length);
+                 j < FastMath.min(coefficients.length, i + 1);
+                 ++j) {
+                newCoefficients[i] += coefficients[j] * p.coefficients[i-j];
+            }
+        }
+
+        return new PolynomialFunction(newCoefficients);
+
+    }
+
+    /**
+     * Returns the coefficients of the derivative of the polynomial with the given coefficients.
+     *
+     * @param coefficients  the coefficients of the polynomial to differentiate
+     * @return the coefficients of the derivative or null if coefficients has length 1.
+     * @throws NoDataException if coefficients is empty
+     * @throws NullPointerException if coefficients is null
+     */
+    protected static double[] differentiate(double[] coefficients) {
+        int n = coefficients.length;
+        if (n == 0) {
+            throw new NoDataException(LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
+        }
+        if (n == 1) {
+            return new double[]{0};
+        }
+        double[] result = new double[n - 1];
+        for (int i = n - 1; i  > 0; i--) {
+            result[i - 1] = i * coefficients[i];
+        }
+        return result;
+    }
+
+    /**
+     * Returns the derivative as a PolynomialRealFunction
+     *
+     * @return  the derivative polynomial
+     */
+    public PolynomialFunction polynomialDerivative() {
+        return new PolynomialFunction(differentiate(coefficients));
+    }
+
+    /**
+     * Returns the derivative as a UnivariateRealFunction
+     *
+     * @return  the derivative function
+     */
+    public UnivariateRealFunction derivative() {
+        return polynomialDerivative();
+    }
+
+    /** Returns a string representation of the polynomial.
+
+     * <p>The representation is user oriented. Terms are displayed lowest
+     * degrees first. The multiplications signs, coefficients equals to
+     * one and null terms are not displayed (except if the polynomial is 0,
+     * in which case the 0 constant term is displayed). Addition of terms
+     * with negative coefficients are replaced by subtraction of terms
+     * with positive coefficients except for the first displayed term
+     * (i.e. we display <code>-3</code> for a constant negative polynomial,
+     * but <code>1 - 3 x + x^2</code> if the negative coefficient is not
+     * the first one displayed).</p>
+
+     * @return a string representation of the polynomial
+
+     */
+    @Override
+     public String toString() {
+
+       StringBuilder s = new StringBuilder();
+       if (coefficients[0] == 0.0) {
+         if (coefficients.length == 1) {
+           return "0";
+         }
+       } else {
+         s.append(Double.toString(coefficients[0]));
+       }
+
+       for (int i = 1; i < coefficients.length; ++i) {
+
+         if (coefficients[i] != 0) {
+
+           if (s.length() > 0) {
+             if (coefficients[i] < 0) {
+               s.append(" - ");
+             } else {
+               s.append(" + ");
+             }
+           } else {
+             if (coefficients[i] < 0) {
+               s.append("-");
+             }
+           }
+
+           double absAi = FastMath.abs(coefficients[i]);
+           if ((absAi - 1) != 0) {
+             s.append(Double.toString(absAi));
+             s.append(' ');
+           }
+
+           s.append("x");
+           if (i > 1) {
+             s.append('^');
+             s.append(Integer.toString(i));
+           }
+         }
+
+       }
+
+       return s.toString();
+
+     }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode(coefficients);
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof PolynomialFunction))
+            return false;
+        PolynomialFunction other = (PolynomialFunction) obj;
+        if (!Arrays.equals(coefficients, other.coefficients))
+            return false;
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeForm.java b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeForm.java
new file mode 100644
index 0000000..b40bf60
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeForm.java
@@ -0,0 +1,305 @@
+/*
+ * 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.analysis.polynomials;
+
+import org.apache.commons.math.DuplicateSampleAbscissaException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the representation of a real polynomial function in
+ * <a href="http://mathworld.wolfram.com/LagrangeInterpolatingPolynomial.html">
+ * Lagrange Form</a>. For reference, see <b>Introduction to Numerical
+ * Analysis</b>, ISBN 038795452X, chapter 2.
+ * <p>
+ * The approximated function should be smooth enough for Lagrange polynomial
+ * to work well. Otherwise, consider using splines instead.</p>
+ *
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ * @since 1.2
+ */
+public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
+
+    /**
+     * The coefficients of the polynomial, ordered by degree -- i.e.
+     * coefficients[0] is the constant term and coefficients[n] is the
+     * coefficient of x^n where n is the degree of the polynomial.
+     */
+    private double coefficients[];
+
+    /**
+     * Interpolating points (abscissas).
+     */
+    private final double x[];
+
+    /**
+     * Function values at interpolating points.
+     */
+    private final double y[];
+
+    /**
+     * Whether the polynomial coefficients are available.
+     */
+    private boolean coefficientsComputed;
+
+    /**
+     * Construct a Lagrange polynomial with the given abscissas and function
+     * values. The order of interpolating points are not important.
+     * <p>
+     * The constructor makes copy of the input arrays and assigns them.</p>
+     *
+     * @param x interpolating points
+     * @param y function values at interpolating points
+     * @throws IllegalArgumentException if input arrays are not valid
+     */
+    public PolynomialFunctionLagrangeForm(double x[], double y[])
+        throws IllegalArgumentException {
+
+        verifyInterpolationArray(x, y);
+        this.x = new double[x.length];
+        this.y = new double[y.length];
+        System.arraycopy(x, 0, this.x, 0, x.length);
+        System.arraycopy(y, 0, this.y, 0, y.length);
+        coefficientsComputed = false;
+    }
+
+    /** {@inheritDoc} */
+    public double value(double z) throws FunctionEvaluationException {
+        try {
+            return evaluate(x, y, z);
+        } catch (DuplicateSampleAbscissaException e) {
+            throw new FunctionEvaluationException(z, e.getSpecificPattern(), e.getGeneralPattern(), e.getArguments());
+        }
+    }
+
+    /**
+     * Returns the degree of the polynomial.
+     *
+     * @return the degree of the polynomial
+     */
+    public int degree() {
+        return x.length - 1;
+    }
+
+    /**
+     * Returns a copy of the interpolating points array.
+     * <p>
+     * Changes made to the returned copy will not affect the polynomial.</p>
+     *
+     * @return a fresh copy of the interpolating points array
+     */
+    public double[] getInterpolatingPoints() {
+        double[] out = new double[x.length];
+        System.arraycopy(x, 0, out, 0, x.length);
+        return out;
+    }
+
+    /**
+     * Returns a copy of the interpolating values array.
+     * <p>
+     * Changes made to the returned copy will not affect the polynomial.</p>
+     *
+     * @return a fresh copy of the interpolating values array
+     */
+    public double[] getInterpolatingValues() {
+        double[] out = new double[y.length];
+        System.arraycopy(y, 0, out, 0, y.length);
+        return out;
+    }
+
+    /**
+     * Returns a copy of the coefficients array.
+     * <p>
+     * Changes made to the returned copy will not affect the polynomial.</p>
+     * <p>
+     * Note that coefficients computation can be ill-conditioned. Use with caution
+     * and only when it is necessary.</p>
+     *
+     * @return a fresh copy of the coefficients array
+     */
+    public double[] getCoefficients() {
+        if (!coefficientsComputed) {
+            computeCoefficients();
+        }
+        double[] out = new double[coefficients.length];
+        System.arraycopy(coefficients, 0, out, 0, coefficients.length);
+        return out;
+    }
+
+    /**
+     * Evaluate the Lagrange polynomial using
+     * <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html">
+     * Neville's Algorithm</a>. It takes O(N^2) time.
+     * <p>
+     * This function is made public static so that users can call it directly
+     * without instantiating PolynomialFunctionLagrangeForm object.</p>
+     *
+     * @param x the interpolating points array
+     * @param y the interpolating values array
+     * @param z the point at which the function value is to be computed
+     * @return the function value
+     * @throws DuplicateSampleAbscissaException if the sample has duplicate abscissas
+     * @throws IllegalArgumentException if inputs are not valid
+     */
+    public static double evaluate(double x[], double y[], double z) throws
+        DuplicateSampleAbscissaException, IllegalArgumentException {
+
+        verifyInterpolationArray(x, y);
+
+        int nearest = 0;
+        final int n = x.length;
+        final double[] c = new double[n];
+        final double[] d = new double[n];
+        double min_dist = Double.POSITIVE_INFINITY;
+        for (int i = 0; i < n; i++) {
+            // initialize the difference arrays
+            c[i] = y[i];
+            d[i] = y[i];
+            // find out the abscissa closest to z
+            final double dist = FastMath.abs(z - x[i]);
+            if (dist < min_dist) {
+                nearest = i;
+                min_dist = dist;
+            }
+        }
+
+        // initial approximation to the function value at z
+        double value = y[nearest];
+
+        for (int i = 1; i < n; i++) {
+            for (int j = 0; j < n-i; j++) {
+                final double tc = x[j] - z;
+                final double td = x[i+j] - z;
+                final double divider = x[j] - x[i+j];
+                if (divider == 0.0) {
+                    // This happens only when two abscissas are identical.
+                    throw new DuplicateSampleAbscissaException(x[i], i, i+j);
+                }
+                // update the difference arrays
+                final double w = (c[j+1] - d[j]) / divider;
+                c[j] = tc * w;
+                d[j] = td * w;
+            }
+            // sum up the difference terms to get the final value
+            if (nearest < 0.5*(n-i+1)) {
+                value += c[nearest];    // fork down
+            } else {
+                nearest--;
+                value += d[nearest];    // fork up
+            }
+        }
+
+        return value;
+    }
+
+    /**
+     * Calculate the coefficients of Lagrange polynomial from the
+     * interpolation data. It takes O(N^2) time.
+     * <p>
+     * Note this computation can be ill-conditioned. Use with caution
+     * and only when it is necessary.</p>
+     *
+     * @throws ArithmeticException if any abscissas coincide
+     */
+    protected void computeCoefficients() throws ArithmeticException {
+
+        final int n = degree() + 1;
+        coefficients = new double[n];
+        for (int i = 0; i < n; i++) {
+            coefficients[i] = 0.0;
+        }
+
+        // c[] are the coefficients of P(x) = (x-x[0])(x-x[1])...(x-x[n-1])
+        final double[] c = new double[n+1];
+        c[0] = 1.0;
+        for (int i = 0; i < n; i++) {
+            for (int j = i; j > 0; j--) {
+                c[j] = c[j-1] - c[j] * x[i];
+            }
+            c[0] *= -x[i];
+            c[i+1] = 1;
+        }
+
+        final double[] tc = new double[n];
+        for (int i = 0; i < n; i++) {
+            // d = (x[i]-x[0])...(x[i]-x[i-1])(x[i]-x[i+1])...(x[i]-x[n-1])
+            double d = 1;
+            for (int j = 0; j < n; j++) {
+                if (i != j) {
+                    d *= x[i] - x[j];
+                }
+            }
+            if (d == 0.0) {
+                // This happens only when two abscissas are identical.
+                for (int k = 0; k < n; ++k) {
+                    if ((i != k) && (x[i] == x[k])) {
+                        throw MathRuntimeException.createArithmeticException(
+                              LocalizedFormats.IDENTICAL_ABSCISSAS_DIVISION_BY_ZERO,
+                              i, k, x[i]);
+                    }
+                }
+            }
+            final double t = y[i] / d;
+            // Lagrange polynomial is the sum of n terms, each of which is a
+            // polynomial of degree n-1. tc[] are the coefficients of the i-th
+            // numerator Pi(x) = (x-x[0])...(x-x[i-1])(x-x[i+1])...(x-x[n-1]).
+            tc[n-1] = c[n];     // actually c[n] = 1
+            coefficients[n-1] += t * tc[n-1];
+            for (int j = n-2; j >= 0; j--) {
+                tc[j] = c[j+1] + tc[j+1] * x[i];
+                coefficients[j] += t * tc[j];
+            }
+        }
+
+        coefficientsComputed = true;
+    }
+
+    /**
+     * Verifies that the interpolation arrays are valid.
+     * <p>
+     * The arrays features checked by this method are that both arrays have the
+     * same length and this length is at least 2.
+     * </p>
+     * <p>
+     * The interpolating points must be distinct. However it is not
+     * verified here, it is checked in evaluate() and computeCoefficients().
+     * </p>
+     *
+     * @param x the interpolating points array
+     * @param y the interpolating values array
+     * @throws IllegalArgumentException if not valid
+     * @see #evaluate(double[], double[], double)
+     * @see #computeCoefficients()
+     */
+    public static void verifyInterpolationArray(double x[], double y[])
+        throws IllegalArgumentException {
+
+        if (x.length != y.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, y.length);
+        }
+
+        if (x.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2, x.length);
+        }
+
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonForm.java b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonForm.java
new file mode 100644
index 0000000..5ee3224
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonForm.java
@@ -0,0 +1,221 @@
+/*
+ * 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.analysis.polynomials;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Implements the representation of a real polynomial function in
+ * Newton Form. For reference, see <b>Elementary Numerical Analysis</b>,
+ * ISBN 0070124477, chapter 2.
+ * <p>
+ * The formula of polynomial in Newton form is
+ *     p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... +
+ *            a[n](x-c[0])(x-c[1])...(x-c[n-1])
+ * Note that the length of a[] is one more than the length of c[]</p>
+ *
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ * @since 1.2
+ */
+public class PolynomialFunctionNewtonForm implements UnivariateRealFunction {
+
+    /**
+     * The coefficients of the polynomial, ordered by degree -- i.e.
+     * coefficients[0] is the constant term and coefficients[n] is the
+     * coefficient of x^n where n is the degree of the polynomial.
+     */
+    private double coefficients[];
+
+    /**
+     * Centers of the Newton polynomial.
+     */
+    private final double c[];
+
+    /**
+     * When all c[i] = 0, a[] becomes normal polynomial coefficients,
+     * i.e. a[i] = coefficients[i].
+     */
+    private final double a[];
+
+    /**
+     * Whether the polynomial coefficients are available.
+     */
+    private boolean coefficientsComputed;
+
+    /**
+     * Construct a Newton polynomial with the given a[] and c[]. The order of
+     * centers are important in that if c[] shuffle, then values of a[] would
+     * completely change, not just a permutation of old a[].
+     * <p>
+     * The constructor makes copy of the input arrays and assigns them.</p>
+     *
+     * @param a the coefficients in Newton form formula
+     * @param c the centers
+     * @throws IllegalArgumentException if input arrays are not valid
+     */
+    public PolynomialFunctionNewtonForm(double a[], double c[])
+        throws IllegalArgumentException {
+
+        verifyInputArray(a, c);
+        this.a = new double[a.length];
+        this.c = new double[c.length];
+        System.arraycopy(a, 0, this.a, 0, a.length);
+        System.arraycopy(c, 0, this.c, 0, c.length);
+        coefficientsComputed = false;
+    }
+
+    /**
+     * Calculate the function value at the given point.
+     *
+     * @param z the point at which the function value is to be computed
+     * @return the function value
+     * @throws FunctionEvaluationException if a runtime error occurs
+     * @see UnivariateRealFunction#value(double)
+     */
+    public double value(double z) throws FunctionEvaluationException {
+       return evaluate(a, c, z);
+    }
+
+    /**
+     * Returns the degree of the polynomial.
+     *
+     * @return the degree of the polynomial
+     */
+    public int degree() {
+        return c.length;
+    }
+
+    /**
+     * Returns a copy of coefficients in Newton form formula.
+     * <p>
+     * Changes made to the returned copy will not affect the polynomial.</p>
+     *
+     * @return a fresh copy of coefficients in Newton form formula
+     */
+    public double[] getNewtonCoefficients() {
+        double[] out = new double[a.length];
+        System.arraycopy(a, 0, out, 0, a.length);
+        return out;
+    }
+
+    /**
+     * Returns a copy of the centers array.
+     * <p>
+     * Changes made to the returned copy will not affect the polynomial.</p>
+     *
+     * @return a fresh copy of the centers array
+     */
+    public double[] getCenters() {
+        double[] out = new double[c.length];
+        System.arraycopy(c, 0, out, 0, c.length);
+        return out;
+    }
+
+    /**
+     * Returns a copy of the coefficients array.
+     * <p>
+     * Changes made to the returned copy will not affect the polynomial.</p>
+     *
+     * @return a fresh copy of the coefficients array
+     */
+    public double[] getCoefficients() {
+        if (!coefficientsComputed) {
+            computeCoefficients();
+        }
+        double[] out = new double[coefficients.length];
+        System.arraycopy(coefficients, 0, out, 0, coefficients.length);
+        return out;
+    }
+
+    /**
+     * Evaluate the Newton polynomial using nested multiplication. It is
+     * also called <a href="http://mathworld.wolfram.com/HornersRule.html">
+     * Horner's Rule</a> and takes O(N) time.
+     *
+     * @param a the coefficients in Newton form formula
+     * @param c the centers
+     * @param z the point at which the function value is to be computed
+     * @return the function value
+     * @throws FunctionEvaluationException if a runtime error occurs
+     * @throws IllegalArgumentException if inputs are not valid
+     */
+    public static double evaluate(double a[], double c[], double z)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        verifyInputArray(a, c);
+
+        int n = c.length;
+        double value = a[n];
+        for (int i = n-1; i >= 0; i--) {
+            value = a[i] + (z - c[i]) * value;
+        }
+
+        return value;
+    }
+
+    /**
+     * Calculate the normal polynomial coefficients given the Newton form.
+     * It also uses nested multiplication but takes O(N^2) time.
+     */
+    protected void computeCoefficients() {
+        final int n = degree();
+
+        coefficients = new double[n+1];
+        for (int i = 0; i <= n; i++) {
+            coefficients[i] = 0.0;
+        }
+
+        coefficients[0] = a[n];
+        for (int i = n-1; i >= 0; i--) {
+            for (int j = n-i; j > 0; j--) {
+                coefficients[j] = coefficients[j-1] - c[i] * coefficients[j];
+            }
+            coefficients[0] = a[i] - c[i] * coefficients[0];
+        }
+
+        coefficientsComputed = true;
+    }
+
+    /**
+     * Verifies that the input arrays are valid.
+     * <p>
+     * The centers must be distinct for interpolation purposes, but not
+     * for general use. Thus it is not verified here.</p>
+     *
+     * @param a the coefficients in Newton form formula
+     * @param c the centers
+     * @throws IllegalArgumentException if not valid
+     * @see org.apache.commons.math.analysis.interpolation.DividedDifferenceInterpolator#computeDividedDifference(double[],
+     * double[])
+     */
+    protected static void verifyInputArray(double a[], double c[]) throws
+        IllegalArgumentException {
+
+        if (a.length < 1 || c.length < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
+        }
+        if (a.length != c.length + 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.ARRAY_SIZES_SHOULD_HAVE_DIFFERENCE_1,
+                  a.length, c.length);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunction.java b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunction.java
new file mode 100644
index 0000000..a0e1e01
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunction.java
@@ -0,0 +1,224 @@
+/*
+ * 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.analysis.polynomials;
+
+import java.util.Arrays;
+
+import org.apache.commons.math.ArgumentOutsideDomainException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Represents a polynomial spline function.
+ * <p>
+ * A <strong>polynomial spline function</strong> consists of a set of
+ * <i>interpolating polynomials</i> and an ascending array of domain
+ * <i>knot points</i>, determining the intervals over which the spline function
+ * is defined by the constituent polynomials.  The polynomials are assumed to
+ * have been computed to match the values of another function at the knot
+ * points.  The value consistency constraints are not currently enforced by
+ * <code>PolynomialSplineFunction</code> itself, but are assumed to hold among
+ * the polynomials and knot points passed to the constructor.</p>
+ * <p>
+ * N.B.:  The polynomials in the <code>polynomials</code> property must be
+ * centered on the knot points to compute the spline function values.
+ * See below.</p>
+ * <p>
+ * The domain of the polynomial spline function is
+ * <code>[smallest knot, largest knot]</code>.  Attempts to evaluate the
+ * function at values outside of this range generate IllegalArgumentExceptions.
+ * </p>
+ * <p>
+ * The value of the polynomial spline function for an argument <code>x</code>
+ * is computed as follows:
+ * <ol>
+ * <li>The knot array is searched to find the segment to which <code>x</code>
+ * belongs.  If <code>x</code> is less than the smallest knot point or greater
+ * than the largest one, an <code>IllegalArgumentException</code>
+ * is thrown.</li>
+ * <li> Let <code>j</code> be the index of the largest knot point that is less
+ * than or equal to <code>x</code>.  The value returned is <br>
+ * <code>polynomials[j](x - knot[j])</code></li></ol></p>
+ *
+ * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
+ */
+public class PolynomialSplineFunction
+    implements DifferentiableUnivariateRealFunction {
+
+    /** Spline segment interval delimiters (knots).   Size is n+1 for n segments. */
+    private final double knots[];
+
+    /**
+     * The polynomial functions that make up the spline.  The first element
+     * determines the value of the spline over the first subinterval, the
+     * second over the second, etc.   Spline function values are determined by
+     * evaluating these functions at <code>(x - knot[i])</code> where i is the
+     * knot segment to which x belongs.
+     */
+    private final PolynomialFunction polynomials[];
+
+    /**
+     * Number of spline segments = number of polynomials
+     *  = number of partition points - 1
+     */
+    private final int n;
+
+
+    /**
+     * Construct a polynomial spline function with the given segment delimiters
+     * and interpolating polynomials.
+     * <p>
+     * The constructor copies both arrays and assigns the copies to the knots
+     * and polynomials properties, respectively.</p>
+     *
+     * @param knots spline segment interval delimiters
+     * @param polynomials polynomial functions that make up the spline
+     * @throws NullPointerException if either of the input arrays is null
+     * @throws IllegalArgumentException if knots has length less than 2,
+     * <code>polynomials.length != knots.length - 1 </code>, or the knots array
+     * is not strictly increasing.
+     *
+     */
+    public PolynomialSplineFunction(double knots[], PolynomialFunction polynomials[]) {
+        if (knots.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION,
+                  2, knots.length);
+        }
+        if (knots.length - 1 != polynomials.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS,
+                  polynomials.length, knots.length);
+        }
+        if (!isStrictlyIncreasing(knots)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_STRICTLY_INCREASING_KNOT_VALUES);
+        }
+
+        this.n = knots.length -1;
+        this.knots = new double[n + 1];
+        System.arraycopy(knots, 0, this.knots, 0, n + 1);
+        this.polynomials = new PolynomialFunction[n];
+        System.arraycopy(polynomials, 0, this.polynomials, 0, n);
+    }
+
+    /**
+     * Compute the value for the function.
+     * See {@link PolynomialSplineFunction} for details on the algorithm for
+     * computing the value of the function.</p>
+     *
+     * @param v the point for which the function value should be computed
+     * @return the value
+     * @throws ArgumentOutsideDomainException if v is outside of the domain of
+     * of the spline function (less than the smallest knot point or greater
+     * than the largest knot point)
+     */
+    public double value(double v) throws ArgumentOutsideDomainException {
+        if (v < knots[0] || v > knots[n]) {
+            throw new ArgumentOutsideDomainException(v, knots[0], knots[n]);
+        }
+        int i = Arrays.binarySearch(knots, v);
+        if (i < 0) {
+            i = -i - 2;
+        }
+        //This will handle the case where v is the last knot value
+        //There are only n-1 polynomials, so if v is the last knot
+        //then we will use the last polynomial to calculate the value.
+        if ( i >= polynomials.length ) {
+            i--;
+        }
+        return polynomials[i].value(v - knots[i]);
+    }
+
+    /**
+     * Returns the derivative of the polynomial spline function as a UnivariateRealFunction
+     * @return  the derivative function
+     */
+    public UnivariateRealFunction derivative() {
+        return polynomialSplineDerivative();
+    }
+
+    /**
+     * Returns the derivative of the polynomial spline function as a PolynomialSplineFunction
+     *
+     * @return  the derivative function
+     */
+    public PolynomialSplineFunction polynomialSplineDerivative() {
+        PolynomialFunction derivativePolynomials[] = new PolynomialFunction[n];
+        for (int i = 0; i < n; i++) {
+            derivativePolynomials[i] = polynomials[i].polynomialDerivative();
+        }
+        return new PolynomialSplineFunction(knots, derivativePolynomials);
+    }
+
+    /**
+     * Returns the number of spline segments = the number of polynomials
+     * = the number of knot points - 1.
+     *
+     * @return the number of spline segments
+     */
+    public int getN() {
+        return n;
+    }
+
+    /**
+     * Returns a copy of the interpolating polynomials array.
+     * <p>
+     * Returns a fresh copy of the array. Changes made to the copy will
+     * not affect the polynomials property.</p>
+     *
+     * @return the interpolating polynomials
+     */
+    public PolynomialFunction[] getPolynomials() {
+        PolynomialFunction p[] = new PolynomialFunction[n];
+        System.arraycopy(polynomials, 0, p, 0, n);
+        return p;
+    }
+
+    /**
+     * Returns an array copy of the knot points.
+     * <p>
+     * Returns a fresh copy of the array. Changes made to the copy
+     * will not affect the knots property.</p>
+     *
+     * @return the knot points
+     */
+    public double[] getKnots() {
+        double out[] = new double[n + 1];
+        System.arraycopy(knots, 0, out, 0, n + 1);
+        return out;
+    }
+
+    /**
+     * Determines if the given array is ordered in a strictly increasing
+     * fashion.
+     *
+     * @param x the array to examine.
+     * @return <code>true</code> if the elements in <code>x</code> are ordered
+     * in a stricly increasing manner.  <code>false</code>, otherwise.
+     */
+    private static boolean isStrictlyIncreasing(double[] x) {
+        for (int i = 1; i < x.length; ++i) {
+            if (x[i - 1] >= x[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java
new file mode 100644
index 0000000..5e939c7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.java
@@ -0,0 +1,281 @@
+/*
+ * 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.analysis.polynomials;
+
+import java.util.ArrayList;
+
+import org.apache.commons.math.fraction.BigFraction;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * A collection of static methods that operate on or return polynomials.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class PolynomialsUtils {
+
+    /** Coefficients for Chebyshev polynomials. */
+    private static final ArrayList<BigFraction> CHEBYSHEV_COEFFICIENTS;
+
+    /** Coefficients for Hermite polynomials. */
+    private static final ArrayList<BigFraction> HERMITE_COEFFICIENTS;
+
+    /** Coefficients for Laguerre polynomials. */
+    private static final ArrayList<BigFraction> LAGUERRE_COEFFICIENTS;
+
+    /** Coefficients for Legendre polynomials. */
+    private static final ArrayList<BigFraction> LEGENDRE_COEFFICIENTS;
+
+    static {
+
+        // initialize recurrence for Chebyshev polynomials
+        // T0(X) = 1, T1(X) = 0 + 1 * X
+        CHEBYSHEV_COEFFICIENTS = new ArrayList<BigFraction>();
+        CHEBYSHEV_COEFFICIENTS.add(BigFraction.ONE);
+        CHEBYSHEV_COEFFICIENTS.add(BigFraction.ZERO);
+        CHEBYSHEV_COEFFICIENTS.add(BigFraction.ONE);
+
+        // initialize recurrence for Hermite polynomials
+        // H0(X) = 1, H1(X) = 0 + 2 * X
+        HERMITE_COEFFICIENTS = new ArrayList<BigFraction>();
+        HERMITE_COEFFICIENTS.add(BigFraction.ONE);
+        HERMITE_COEFFICIENTS.add(BigFraction.ZERO);
+        HERMITE_COEFFICIENTS.add(BigFraction.TWO);
+
+        // initialize recurrence for Laguerre polynomials
+        // L0(X) = 1, L1(X) = 1 - 1 * X
+        LAGUERRE_COEFFICIENTS = new ArrayList<BigFraction>();
+        LAGUERRE_COEFFICIENTS.add(BigFraction.ONE);
+        LAGUERRE_COEFFICIENTS.add(BigFraction.ONE);
+        LAGUERRE_COEFFICIENTS.add(BigFraction.MINUS_ONE);
+
+        // initialize recurrence for Legendre polynomials
+        // P0(X) = 1, P1(X) = 0 + 1 * X
+        LEGENDRE_COEFFICIENTS = new ArrayList<BigFraction>();
+        LEGENDRE_COEFFICIENTS.add(BigFraction.ONE);
+        LEGENDRE_COEFFICIENTS.add(BigFraction.ZERO);
+        LEGENDRE_COEFFICIENTS.add(BigFraction.ONE);
+
+    }
+
+    /**
+     * Private constructor, to prevent instantiation.
+     */
+    private PolynomialsUtils() {
+    }
+
+    /**
+     * Create a Chebyshev polynomial of the first kind.
+     * <p><a href="http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html">Chebyshev
+     * polynomials of the first kind</a> are orthogonal polynomials.
+     * They can be defined by the following recurrence relations:
+     * <pre>
+     *  T<sub>0</sub>(X)   = 1
+     *  T<sub>1</sub>(X)   = X
+     *  T<sub>k+1</sub>(X) = 2X T<sub>k</sub>(X) - T<sub>k-1</sub>(X)
+     * </pre></p>
+     * @param degree degree of the polynomial
+     * @return Chebyshev polynomial of specified degree
+     */
+    public static PolynomialFunction createChebyshevPolynomial(final int degree) {
+        return buildPolynomial(degree, CHEBYSHEV_COEFFICIENTS,
+                new RecurrenceCoefficientsGenerator() {
+            private final BigFraction[] coeffs = { BigFraction.ZERO, BigFraction.TWO, BigFraction.ONE };
+            /** {@inheritDoc} */
+            public BigFraction[] generate(int k) {
+                return coeffs;
+            }
+        });
+    }
+
+    /**
+     * Create a Hermite polynomial.
+     * <p><a href="http://mathworld.wolfram.com/HermitePolynomial.html">Hermite
+     * polynomials</a> are orthogonal polynomials.
+     * They can be defined by the following recurrence relations:
+     * <pre>
+     *  H<sub>0</sub>(X)   = 1
+     *  H<sub>1</sub>(X)   = 2X
+     *  H<sub>k+1</sub>(X) = 2X H<sub>k</sub>(X) - 2k H<sub>k-1</sub>(X)
+     * </pre></p>
+
+     * @param degree degree of the polynomial
+     * @return Hermite polynomial of specified degree
+     */
+    public static PolynomialFunction createHermitePolynomial(final int degree) {
+        return buildPolynomial(degree, HERMITE_COEFFICIENTS,
+                new RecurrenceCoefficientsGenerator() {
+            /** {@inheritDoc} */
+            public BigFraction[] generate(int k) {
+                return new BigFraction[] {
+                        BigFraction.ZERO,
+                        BigFraction.TWO,
+                        new BigFraction(2 * k)};
+            }
+        });
+    }
+
+    /**
+     * Create a Laguerre polynomial.
+     * <p><a href="http://mathworld.wolfram.com/LaguerrePolynomial.html">Laguerre
+     * polynomials</a> are orthogonal polynomials.
+     * They can be defined by the following recurrence relations:
+     * <pre>
+     *        L<sub>0</sub>(X)   = 1
+     *        L<sub>1</sub>(X)   = 1 - X
+     *  (k+1) L<sub>k+1</sub>(X) = (2k + 1 - X) L<sub>k</sub>(X) - k L<sub>k-1</sub>(X)
+     * </pre></p>
+     * @param degree degree of the polynomial
+     * @return Laguerre polynomial of specified degree
+     */
+    public static PolynomialFunction createLaguerrePolynomial(final int degree) {
+        return buildPolynomial(degree, LAGUERRE_COEFFICIENTS,
+                new RecurrenceCoefficientsGenerator() {
+            /** {@inheritDoc} */
+            public BigFraction[] generate(int k) {
+                final int kP1 = k + 1;
+                return new BigFraction[] {
+                        new BigFraction(2 * k + 1, kP1),
+                        new BigFraction(-1, kP1),
+                        new BigFraction(k, kP1)};
+            }
+        });
+    }
+
+    /**
+     * Create a Legendre polynomial.
+     * <p><a href="http://mathworld.wolfram.com/LegendrePolynomial.html">Legendre
+     * polynomials</a> are orthogonal polynomials.
+     * They can be defined by the following recurrence relations:
+     * <pre>
+     *        P<sub>0</sub>(X)   = 1
+     *        P<sub>1</sub>(X)   = X
+     *  (k+1) P<sub>k+1</sub>(X) = (2k+1) X P<sub>k</sub>(X) - k P<sub>k-1</sub>(X)
+     * </pre></p>
+     * @param degree degree of the polynomial
+     * @return Legendre polynomial of specified degree
+     */
+    public static PolynomialFunction createLegendrePolynomial(final int degree) {
+        return buildPolynomial(degree, LEGENDRE_COEFFICIENTS,
+                               new RecurrenceCoefficientsGenerator() {
+            /** {@inheritDoc} */
+            public BigFraction[] generate(int k) {
+                final int kP1 = k + 1;
+                return new BigFraction[] {
+                        BigFraction.ZERO,
+                        new BigFraction(k + kP1, kP1),
+                        new BigFraction(k, kP1)};
+            }
+        });
+    }
+
+    /** Get the coefficients array for a given degree.
+     * @param degree degree of the polynomial
+     * @param coefficients list where the computed coefficients are stored
+     * @param generator recurrence coefficients generator
+     * @return coefficients array
+     */
+    private static PolynomialFunction buildPolynomial(final int degree,
+                                                      final ArrayList<BigFraction> coefficients,
+                                                      final RecurrenceCoefficientsGenerator generator) {
+
+        final int maxDegree = (int) FastMath.floor(FastMath.sqrt(2 * coefficients.size())) - 1;
+        synchronized (PolynomialsUtils.class) {
+            if (degree > maxDegree) {
+                computeUpToDegree(degree, maxDegree, generator, coefficients);
+            }
+        }
+
+        // coefficient  for polynomial 0 is  l [0]
+        // coefficients for polynomial 1 are l [1] ... l [2] (degrees 0 ... 1)
+        // coefficients for polynomial 2 are l [3] ... l [5] (degrees 0 ... 2)
+        // coefficients for polynomial 3 are l [6] ... l [9] (degrees 0 ... 3)
+        // coefficients for polynomial 4 are l[10] ... l[14] (degrees 0 ... 4)
+        // coefficients for polynomial 5 are l[15] ... l[20] (degrees 0 ... 5)
+        // coefficients for polynomial 6 are l[21] ... l[27] (degrees 0 ... 6)
+        // ...
+        final int start = degree * (degree + 1) / 2;
+
+        final double[] a = new double[degree + 1];
+        for (int i = 0; i <= degree; ++i) {
+            a[i] = coefficients.get(start + i).doubleValue();
+        }
+
+        // build the polynomial
+        return new PolynomialFunction(a);
+
+    }
+
+    /** Compute polynomial coefficients up to a given degree.
+     * @param degree maximal degree
+     * @param maxDegree current maximal degree
+     * @param generator recurrence coefficients generator
+     * @param coefficients list where the computed coefficients should be appended
+     */
+    private static void computeUpToDegree(final int degree, final int maxDegree,
+                                          final RecurrenceCoefficientsGenerator generator,
+                                          final ArrayList<BigFraction> coefficients) {
+
+        int startK = (maxDegree - 1) * maxDegree / 2;
+        for (int k = maxDegree; k < degree; ++k) {
+
+            // start indices of two previous polynomials Pk(X) and Pk-1(X)
+            int startKm1 = startK;
+            startK += k;
+
+            // Pk+1(X) = (a[0] + a[1] X) Pk(X) - a[2] Pk-1(X)
+            BigFraction[] ai = generator.generate(k);
+
+            BigFraction ck     = coefficients.get(startK);
+            BigFraction ckm1   = coefficients.get(startKm1);
+
+            // degree 0 coefficient
+            coefficients.add(ck.multiply(ai[0]).subtract(ckm1.multiply(ai[2])));
+
+            // degree 1 to degree k-1 coefficients
+            for (int i = 1; i < k; ++i) {
+                final BigFraction ckPrev = ck;
+                ck     = coefficients.get(startK + i);
+                ckm1   = coefficients.get(startKm1 + i);
+                coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1])).subtract(ckm1.multiply(ai[2])));
+            }
+
+            // degree k coefficient
+            final BigFraction ckPrev = ck;
+            ck = coefficients.get(startK + k);
+            coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1])));
+
+            // degree k+1 coefficient
+            coefficients.add(ck.multiply(ai[1]));
+
+        }
+
+    }
+
+    /** Interface for recurrence coefficients generation. */
+    private static interface RecurrenceCoefficientsGenerator {
+        /**
+         * Generate recurrence coefficients.
+         * @param k highest degree of the polynomials used in the recurrence
+         * @return an array of three coefficients such that
+         * P<sub>k+1</sub>(X) = (a[0] + a[1] X) P<sub>k</sub>(X) - a[2] P<sub>k-1</sub>(X)
+         */
+        BigFraction[] generate(int k);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/polynomials/package.html b/src/main/java/org/apache/commons/math/analysis/polynomials/package.html
new file mode 100644
index 0000000..63ca96a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/polynomials/package.html
@@ -0,0 +1,23 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+     Univariate real polynomials implementations, seen as differentiable
+     univariate real functions.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/BisectionSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/BisectionSolver.java
new file mode 100644
index 0000000..c9d3a63
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/BisectionSolver.java
@@ -0,0 +1,133 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/Bisection.html">
+ * bisection algorithm</a> for finding zeros of univariate real functions.
+ * <p>
+ * The function should be continuous but not necessarily smooth.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class BisectionSolver extends UnivariateRealSolverImpl {
+
+    /**
+     * Construct a solver for the given function.
+     *
+     * @param f function to solve.
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public BisectionSolver(UnivariateRealFunction f) {
+        super(f, 100, 1E-6);
+    }
+
+    /**
+     * Construct a solver.
+     *
+     */
+    public BisectionSolver() {
+        super(100, 1E-6);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(double min, double max, double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(double min, double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f, double min, double max, double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f, double min, double max, double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(maxEval, f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f, double min, double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f, double min, double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        clearResult();
+        verifyInterval(min,max);
+        double m;
+        double fm;
+        double fmin;
+
+        int i = 0;
+        while (i < maximalIterationCount) {
+            m = UnivariateRealSolverUtils.midpoint(min, max);
+           fmin = f.value(min);
+           fm = f.value(m);
+
+            if (fm * fmin > 0.0) {
+                // max and m bracket the root.
+                min = m;
+            } else {
+                // min and m bracket the root.
+                max = m;
+            }
+
+            if (FastMath.abs(max - min) <= absoluteAccuracy) {
+                m = UnivariateRealSolverUtils.midpoint(min, max);
+                setResult(m, i);
+                return m;
+            }
+            ++i;
+        }
+
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/BrentSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/BrentSolver.java
new file mode 100644
index 0000000..5aa2447
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/BrentSolver.java
@@ -0,0 +1,399 @@
+/*
+ * 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.analysis.solvers;
+
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/BrentsMethod.html">
+ * Brent algorithm</a> for  finding zeros of real univariate functions.
+ * <p>
+ * The function should be continuous but not necessarily smooth.</p>
+ *
+ * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $
+ */
+public class BrentSolver extends UnivariateRealSolverImpl {
+
+    /**
+     * Default absolute accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_ABSOLUTE_ACCURACY = 1E-6;
+
+    /** Default maximum number of iterations
+     * @since 2.1
+     */
+    public static final int DEFAULT_MAXIMUM_ITERATIONS = 100;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 7694577816772532779L;
+
+    /**
+     * Construct a solver for the given function.
+     *
+     * @param f function to solve.
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public BrentSolver(UnivariateRealFunction f) {
+        super(f, DEFAULT_MAXIMUM_ITERATIONS, DEFAULT_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Construct a solver with default properties.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public BrentSolver() {
+        super(DEFAULT_MAXIMUM_ITERATIONS, DEFAULT_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Construct a solver with the given absolute accuracy.
+     *
+     * @param absoluteAccuracy lower bound for absolute accuracy of solutions returned by the solver
+     * @since 2.1
+     */
+    public BrentSolver(double absoluteAccuracy) {
+        super(DEFAULT_MAXIMUM_ITERATIONS, absoluteAccuracy);
+    }
+
+    /**
+     * Contstruct a solver with the given maximum iterations and absolute accuracy.
+     *
+     * @param maximumIterations maximum number of iterations
+     * @param absoluteAccuracy lower bound for absolute accuracy of solutions returned by the solver
+     * @since 2.1
+     */
+    public BrentSolver(int maximumIterations, double absoluteAccuracy) {
+        super(maximumIterations, absoluteAccuracy);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(double min, double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(double min, double max, double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a zero in the given interval with an initial guess.
+     * <p>Throws <code>IllegalArgumentException</code> if the values of the
+     * function at the three points have the same sign (note that it is
+     * allowed to have endpoints with the same sign if the initial point has
+     * opposite sign function-wise).</p>
+     *
+     * @param f function to solve.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param initial the start value to use (must be set to min if no
+     * initial point is known).
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating  the function
+     * @throws IllegalArgumentException if initial is not between min and max
+     * (even if it <em>is</em> a root)
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        clearResult();
+        if ((initial < min) || (initial > max)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS,
+                  min, initial, max);
+        }
+
+        // return the initial guess if it is good enough
+        double yInitial = f.value(initial);
+        if (FastMath.abs(yInitial) <= functionValueAccuracy) {
+            setResult(initial, 0);
+            return result;
+        }
+
+        // return the first endpoint if it is good enough
+        double yMin = f.value(min);
+        if (FastMath.abs(yMin) <= functionValueAccuracy) {
+            setResult(min, 0);
+            return result;
+        }
+
+        // reduce interval if min and initial bracket the root
+        if (yInitial * yMin < 0) {
+            return solve(f, min, yMin, initial, yInitial, min, yMin);
+        }
+
+        // return the second endpoint if it is good enough
+        double yMax = f.value(max);
+        if (FastMath.abs(yMax) <= functionValueAccuracy) {
+            setResult(max, 0);
+            return result;
+        }
+
+        // reduce interval if initial and max bracket the root
+        if (yInitial * yMax < 0) {
+            return solve(f, initial, yInitial, max, yMax, initial, yInitial);
+        }
+
+        throw MathRuntimeException.createIllegalArgumentException(
+              LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, yMin, yMax);
+
+    }
+
+    /**
+     * Find a zero in the given interval with an initial guess.
+     * <p>Throws <code>IllegalArgumentException</code> if the values of the
+     * function at the three points have the same sign (note that it is
+     * allowed to have endpoints with the same sign if the initial point has
+     * opposite sign function-wise).</p>
+     *
+     * @param f function to solve.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param initial the start value to use (must be set to min if no
+     * initial point is known).
+     * @param maxEval Maximum number of evaluations.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating  the function
+     * @throws IllegalArgumentException if initial is not between min and max
+     * (even if it <em>is</em> a root)
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a zero in the given interval.
+     * <p>
+     * Requires that the values of the function at the endpoints have opposite
+     * signs. An <code>IllegalArgumentException</code> is thrown if this is not
+     * the case.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min is not less than max or the
+     * signs of the values of the function at the endpoints are not opposites
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        clearResult();
+        verifyInterval(min, max);
+
+        double ret = Double.NaN;
+
+        double yMin = f.value(min);
+        double yMax = f.value(max);
+
+        // Verify bracketing
+        double sign = yMin * yMax;
+        if (sign > 0) {
+            // check if either value is close to a zero
+            if (FastMath.abs(yMin) <= functionValueAccuracy) {
+                setResult(min, 0);
+                ret = min;
+            } else if (FastMath.abs(yMax) <= functionValueAccuracy) {
+                setResult(max, 0);
+                ret = max;
+            } else {
+                // neither value is close to zero and min and max do not bracket root.
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, yMin, yMax);
+            }
+        } else if (sign < 0){
+            // solve using only the first endpoint as initial guess
+            ret = solve(f, min, yMin, max, yMax, min, yMin);
+        } else {
+            // either min or max is a root
+            if (yMin == 0.0) {
+                ret = min;
+            } else {
+                ret = max;
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * Find a zero in the given interval.
+     * <p>
+     * Requires that the values of the function at the endpoints have opposite
+     * signs. An <code>IllegalArgumentException</code> is thrown if this is not
+     * the case.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param maxEval Maximum number of evaluations.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min is not less than max or the
+     * signs of the values of the function at the endpoints are not opposites
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a zero starting search according to the three provided points.
+     * @param f the function to solve
+     * @param x0 old approximation for the root
+     * @param y0 function value at the approximation for the root
+     * @param x1 last calculated approximation for the root
+     * @param y1 function value at the last calculated approximation
+     * for the root
+     * @param x2 bracket point (must be set to x0 if no bracket point is
+     * known, this will force starting with linear interpolation)
+     * @param y2 function value at the bracket point.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     */
+    private double solve(final UnivariateRealFunction f,
+                         double x0, double y0,
+                         double x1, double y1,
+                         double x2, double y2)
+    throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        double delta = x1 - x0;
+        double oldDelta = delta;
+
+        int i = 0;
+        while (i < maximalIterationCount) {
+            if (FastMath.abs(y2) < FastMath.abs(y1)) {
+                // use the bracket point if is better than last approximation
+                x0 = x1;
+                x1 = x2;
+                x2 = x0;
+                y0 = y1;
+                y1 = y2;
+                y2 = y0;
+            }
+            if (FastMath.abs(y1) <= functionValueAccuracy) {
+                // Avoid division by very small values. Assume
+                // the iteration has converged (the problem may
+                // still be ill conditioned)
+                setResult(x1, i);
+                return result;
+            }
+            double dx = x2 - x1;
+            double tolerance =
+                FastMath.max(relativeAccuracy * FastMath.abs(x1), absoluteAccuracy);
+            if (FastMath.abs(dx) <= tolerance) {
+                setResult(x1, i);
+                return result;
+            }
+            if ((FastMath.abs(oldDelta) < tolerance) ||
+                    (FastMath.abs(y0) <= FastMath.abs(y1))) {
+                // Force bisection.
+                delta = 0.5 * dx;
+                oldDelta = delta;
+            } else {
+                double r3 = y1 / y0;
+                double p;
+                double p1;
+                // the equality test (x0 == x2) is intentional,
+                // it is part of the original Brent's method,
+                // it should NOT be replaced by proximity test
+                if (x0 == x2) {
+                    // Linear interpolation.
+                    p = dx * r3;
+                    p1 = 1.0 - r3;
+                } else {
+                    // Inverse quadratic interpolation.
+                    double r1 = y0 / y2;
+                    double r2 = y1 / y2;
+                    p = r3 * (dx * r1 * (r1 - r2) - (x1 - x0) * (r2 - 1.0));
+                    p1 = (r1 - 1.0) * (r2 - 1.0) * (r3 - 1.0);
+                }
+                if (p > 0.0) {
+                    p1 = -p1;
+                } else {
+                    p = -p;
+                }
+                if (2.0 * p >= 1.5 * dx * p1 - FastMath.abs(tolerance * p1) ||
+                        p >= FastMath.abs(0.5 * oldDelta * p1)) {
+                    // Inverse quadratic interpolation gives a value
+                    // in the wrong direction, or progress is slow.
+                    // Fall back to bisection.
+                    delta = 0.5 * dx;
+                    oldDelta = delta;
+                } else {
+                    oldDelta = delta;
+                    delta = p / p1;
+                }
+            }
+            // Save old X1, Y1
+            x0 = x1;
+            y0 = y1;
+            // Compute new X1, Y1
+            if (FastMath.abs(delta) > tolerance) {
+                x1 = x1 + delta;
+            } else if (dx > 0.0) {
+                x1 = x1 + 0.5 * tolerance;
+            } else if (dx <= 0.0) {
+                x1 = x1 - 0.5 * tolerance;
+            }
+            y1 = f.value(x1);
+            if ((y1 > 0) == (y2 > 0)) {
+                x2 = x0;
+                y2 = y0;
+                delta = x1 - x0;
+                oldDelta = delta;
+            }
+            i++;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/LaguerreSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/LaguerreSolver.java
new file mode 100644
index 0000000..e6d8bd8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/LaguerreSolver.java
@@ -0,0 +1,434 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/LaguerresMethod.html">
+ * Laguerre's Method</a> for root finding of real coefficient polynomials.
+ * For reference, see <b>A First Course in Numerical Analysis</b>,
+ * ISBN 048641454X, chapter 8.
+ * <p>
+ * Laguerre's method is global in the sense that it can start with any initial
+ * approximation and be able to solve all roots from that point.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class LaguerreSolver extends UnivariateRealSolverImpl {
+
+    /** polynomial function to solve.
+     * @deprecated as of 2.0 the function is not stored anymore in the instance
+     */
+    @Deprecated
+    private final PolynomialFunction p;
+
+    /**
+     * Construct a solver for the given function.
+     *
+     * @param f function to solve
+     * @throws IllegalArgumentException if function is not polynomial
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public LaguerreSolver(UnivariateRealFunction f) throws IllegalArgumentException {
+        super(f, 100, 1E-6);
+        if (f instanceof PolynomialFunction) {
+            p = (PolynomialFunction) f;
+        } else {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_POLYNOMIAL);
+        }
+    }
+
+    /**
+     * Construct a solver.
+     * @deprecated in 2.2 (to be removed in 3.0)
+     */
+    @Deprecated
+    public LaguerreSolver() {
+        super(100, 1E-6);
+        p = null;
+    }
+
+    /**
+     * Returns a copy of the polynomial function.
+     *
+     * @return a fresh copy of the polynomial function
+     * @deprecated as of 2.0 the function is not stored anymore within the instance.
+     */
+    @Deprecated
+    public PolynomialFunction getPolynomialFunction() {
+        return new PolynomialFunction(p.getCoefficients());
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(p, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max, final double initial)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(p, min, max, initial);
+    }
+
+    /**
+     * Find a real root in the given interval with initial value.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f function to solve (must be polynomial)
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use
+     * @param maxEval Maximum number of evaluations.
+     * @return the point at which the function value is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws ConvergenceException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a real root in the given interval with initial value.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f function to solve (must be polynomial)
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use
+     * @return the point at which the function value is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws ConvergenceException, FunctionEvaluationException {
+
+        // check for zeros before verifying bracketing
+        if (f.value(min) == 0.0) {
+            return min;
+        }
+        if (f.value(max) == 0.0) {
+            return max;
+        }
+        if (f.value(initial) == 0.0) {
+            return initial;
+        }
+
+        verifyBracketing(min, max, f);
+        verifySequence(min, initial, max);
+        if (isBracketing(min, initial, f)) {
+            return solve(f, min, initial);
+        } else {
+            return solve(f, initial, max);
+        }
+
+    }
+
+    /**
+     * Find a real root in the given interval.
+     * <p>
+     * Despite the bracketing condition, the root returned by solve(Complex[],
+     * Complex) may not be a real zero inside [min, max]. For example,
+     * p(x) = x^3 + 1, min = -2, max = 2, initial = 0. We can either try
+     * another initial value, or, as we did here, call solveAll() to obtain
+     * all roots and pick up the one that we're looking for.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param maxEval Maximum number of evaluations.
+     * @return the point at which the function value is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a real root in the given interval.
+     * <p>
+     * Despite the bracketing condition, the root returned by solve(Complex[],
+     * Complex) may not be a real zero inside [min, max]. For example,
+     * p(x) = x^3 + 1, min = -2, max = 2, initial = 0. We can either try
+     * another initial value, or, as we did here, call solveAll() to obtain
+     * all roots and pick up the one that we're looking for.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the point at which the function value is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+
+        // check function type
+        if (!(f instanceof PolynomialFunction)) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_POLYNOMIAL);
+        }
+
+        // check for zeros before verifying bracketing
+        if (f.value(min) == 0.0) { return min; }
+        if (f.value(max) == 0.0) { return max; }
+        verifyBracketing(min, max, f);
+
+        double coefficients[] = ((PolynomialFunction) f).getCoefficients();
+        Complex c[] = new Complex[coefficients.length];
+        for (int i = 0; i < coefficients.length; i++) {
+            c[i] = new Complex(coefficients[i], 0.0);
+        }
+        Complex initial = new Complex(0.5 * (min + max), 0.0);
+        Complex z = solve(c, initial);
+        if (isRootOK(min, max, z)) {
+            setResult(z.getReal(), iterationCount);
+            return result;
+        }
+
+        // solve all roots and select the one we're seeking
+        Complex[] root = solveAll(c, initial);
+        for (int i = 0; i < root.length; i++) {
+            if (isRootOK(min, max, root[i])) {
+                setResult(root[i].getReal(), iterationCount);
+                return result;
+            }
+        }
+
+        // should never happen
+        throw new ConvergenceException();
+    }
+
+    /**
+     * Returns true iff the given complex root is actually a real zero
+     * in the given interval, within the solver tolerance level.
+     *
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param z the complex root
+     * @return true iff z is the sought-after real zero
+     */
+    protected boolean isRootOK(double min, double max, Complex z) {
+        double tolerance = FastMath.max(relativeAccuracy * z.abs(), absoluteAccuracy);
+        return (isSequence(min, z.getReal(), max)) &&
+               (FastMath.abs(z.getImaginary()) <= tolerance ||
+                z.abs() <= functionValueAccuracy);
+    }
+
+    /**
+     * Find all complex roots for the polynomial with the given coefficients,
+     * starting from the given initial value.
+     *
+     * @param coefficients the polynomial coefficients array
+     * @param initial the start value to use
+     * @return the point at which the function value is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2.
+     */
+    @Deprecated
+    public Complex[] solveAll(double coefficients[], double initial) throws
+        ConvergenceException, FunctionEvaluationException {
+
+        Complex c[] = new Complex[coefficients.length];
+        Complex z = new Complex(initial, 0.0);
+        for (int i = 0; i < c.length; i++) {
+            c[i] = new Complex(coefficients[i], 0.0);
+        }
+        return solveAll(c, z);
+    }
+
+    /**
+     * Find all complex roots for the polynomial with the given coefficients,
+     * starting from the given initial value.
+     *
+     * @param coefficients the polynomial coefficients array
+     * @param initial the start value to use
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2.
+     */
+    @Deprecated
+    public Complex[] solveAll(Complex coefficients[], Complex initial) throws
+        MaxIterationsExceededException, FunctionEvaluationException {
+
+        int n = coefficients.length - 1;
+        int iterationCount = 0;
+        if (n < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NON_POSITIVE_POLYNOMIAL_DEGREE, n);
+        }
+        Complex c[] = new Complex[n+1];    // coefficients for deflated polynomial
+        for (int i = 0; i <= n; i++) {
+            c[i] = coefficients[i];
+        }
+
+        // solve individual root successively
+        Complex root[] = new Complex[n];
+        for (int i = 0; i < n; i++) {
+            Complex subarray[] = new Complex[n-i+1];
+            System.arraycopy(c, 0, subarray, 0, subarray.length);
+            root[i] = solve(subarray, initial);
+            // polynomial deflation using synthetic division
+            Complex newc = c[n-i];
+            Complex oldc = null;
+            for (int j = n-i-1; j >= 0; j--) {
+                oldc = c[j];
+                c[j] = newc;
+                newc = oldc.add(newc.multiply(root[i]));
+            }
+            iterationCount += this.iterationCount;
+        }
+
+        resultComputed = true;
+        this.iterationCount = iterationCount;
+        return root;
+    }
+
+    /**
+     * Find a complex root for the polynomial with the given coefficients,
+     * starting from the given initial value.
+     *
+     * @param coefficients the polynomial coefficients array
+     * @param initial the start value to use
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2.
+     */
+    @Deprecated
+    public Complex solve(Complex coefficients[], Complex initial) throws
+        MaxIterationsExceededException, FunctionEvaluationException {
+
+        int n = coefficients.length - 1;
+        if (n < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NON_POSITIVE_POLYNOMIAL_DEGREE, n);
+        }
+        Complex N  = new Complex(n,     0.0);
+        Complex N1 = new Complex(n - 1, 0.0);
+
+        int i = 1;
+        Complex pv = null;
+        Complex dv = null;
+        Complex d2v = null;
+        Complex G = null;
+        Complex G2 = null;
+        Complex H = null;
+        Complex delta = null;
+        Complex denominator = null;
+        Complex z = initial;
+        Complex oldz = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
+        while (i <= maximalIterationCount) {
+            // Compute pv (polynomial value), dv (derivative value), and
+            // d2v (second derivative value) simultaneously.
+            pv = coefficients[n];
+            dv = Complex.ZERO;
+            d2v = Complex.ZERO;
+            for (int j = n-1; j >= 0; j--) {
+                d2v = dv.add(z.multiply(d2v));
+                dv = pv.add(z.multiply(dv));
+                pv = coefficients[j].add(z.multiply(pv));
+            }
+            d2v = d2v.multiply(new Complex(2.0, 0.0));
+
+            // check for convergence
+            double tolerance = FastMath.max(relativeAccuracy * z.abs(),
+                                        absoluteAccuracy);
+            if ((z.subtract(oldz)).abs() <= tolerance) {
+                resultComputed = true;
+                iterationCount = i;
+                return z;
+            }
+            if (pv.abs() <= functionValueAccuracy) {
+                resultComputed = true;
+                iterationCount = i;
+                return z;
+            }
+
+            // now pv != 0, calculate the new approximation
+            G = dv.divide(pv);
+            G2 = G.multiply(G);
+            H = G2.subtract(d2v.divide(pv));
+            delta = N1.multiply((N.multiply(H)).subtract(G2));
+            // choose a denominator larger in magnitude
+            Complex deltaSqrt = delta.sqrt();
+            Complex dplus = G.add(deltaSqrt);
+            Complex dminus = G.subtract(deltaSqrt);
+            denominator = dplus.abs() > dminus.abs() ? dplus : dminus;
+            // Perturb z if denominator is zero, for instance,
+            // p(x) = x^3 + 1, z = 0.
+            if (denominator.equals(new Complex(0.0, 0.0))) {
+                z = z.add(new Complex(absoluteAccuracy, absoluteAccuracy));
+                oldz = new Complex(Double.POSITIVE_INFINITY,
+                                   Double.POSITIVE_INFINITY);
+            } else {
+                oldz = z;
+                z = z.subtract(N.divide(denominator));
+            }
+            i++;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java
new file mode 100644
index 0000000..a6d03bc
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/MullerSolver.java
@@ -0,0 +1,415 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/MullersMethod.html">
+ * Muller's Method</a> for root finding of real univariate functions. For
+ * reference, see <b>Elementary Numerical Analysis</b>, ISBN 0070124477,
+ * chapter 3.
+ * <p>
+ * Muller's method applies to both real and complex functions, but here we
+ * restrict ourselves to real functions. Methods solve() and solve2() find
+ * real zeros, using different ways to bypass complex arithmetics.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class MullerSolver extends UnivariateRealSolverImpl {
+
+    /**
+     * Construct a solver for the given function.
+     *
+     * @param f function to solve
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public MullerSolver(UnivariateRealFunction f) {
+        super(f, 100, 1E-6);
+    }
+
+    /**
+     * Construct a solver.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public MullerSolver() {
+        super(100, 1E-6);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max, final double initial)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a real root in the given interval with initial value.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use
+     * @param maxEval Maximum number of evaluations.
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a real root in the given interval with initial value.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        // check for zeros before verifying bracketing
+        if (f.value(min) == 0.0) { return min; }
+        if (f.value(max) == 0.0) { return max; }
+        if (f.value(initial) == 0.0) { return initial; }
+
+        verifyBracketing(min, max, f);
+        verifySequence(min, initial, max);
+        if (isBracketing(min, initial, f)) {
+            return solve(f, min, initial);
+        } else {
+            return solve(f, initial, max);
+        }
+    }
+
+    /**
+     * Find a real root in the given interval.
+     * <p>
+     * Original Muller's method would have function evaluation at complex point.
+     * Since our f(x) is real, we have to find ways to avoid that. Bracketing
+     * condition is one way to go: by requiring bracketing in every iteration,
+     * the newly computed approximation is guaranteed to be real.</p>
+     * <p>
+     * Normally Muller's method converges quadratically in the vicinity of a
+     * zero, however it may be very slow in regions far away from zeros. For
+     * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use
+     * bisection as a safety backup if it performs very poorly.</p>
+     * <p>
+     * The formulas here use divided differences directly.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param maxEval Maximum number of evaluations.
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a real root in the given interval.
+     * <p>
+     * Original Muller's method would have function evaluation at complex point.
+     * Since our f(x) is real, we have to find ways to avoid that. Bracketing
+     * condition is one way to go: by requiring bracketing in every iteration,
+     * the newly computed approximation is guaranteed to be real.</p>
+     * <p>
+     * Normally Muller's method converges quadratically in the vicinity of a
+     * zero, however it may be very slow in regions far away from zeros. For
+     * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use
+     * bisection as a safety backup if it performs very poorly.</p>
+     * <p>
+     * The formulas here use divided differences directly.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        // [x0, x2] is the bracketing interval in each iteration
+        // x1 is the last approximation and an interpolation point in (x0, x2)
+        // x is the new root approximation and new x1 for next round
+        // d01, d12, d012 are divided differences
+
+        double x0 = min;
+        double y0 = f.value(x0);
+        double x2 = max;
+        double y2 = f.value(x2);
+        double x1 = 0.5 * (x0 + x2);
+        double y1 = f.value(x1);
+
+        // check for zeros before verifying bracketing
+        if (y0 == 0.0) {
+            return min;
+        }
+        if (y2 == 0.0) {
+            return max;
+        }
+        verifyBracketing(min, max, f);
+
+        double oldx = Double.POSITIVE_INFINITY;
+        for (int i = 1; i <= maximalIterationCount; ++i) {
+            // Muller's method employs quadratic interpolation through
+            // x0, x1, x2 and x is the zero of the interpolating parabola.
+            // Due to bracketing condition, this parabola must have two
+            // real roots and we choose one in [x0, x2] to be x.
+            final double d01 = (y1 - y0) / (x1 - x0);
+            final double d12 = (y2 - y1) / (x2 - x1);
+            final double d012 = (d12 - d01) / (x2 - x0);
+            final double c1 = d01 + (x1 - x0) * d012;
+            final double delta = c1 * c1 - 4 * y1 * d012;
+            final double xplus = x1 + (-2.0 * y1) / (c1 + FastMath.sqrt(delta));
+            final double xminus = x1 + (-2.0 * y1) / (c1 - FastMath.sqrt(delta));
+            // xplus and xminus are two roots of parabola and at least
+            // one of them should lie in (x0, x2)
+            final double x = isSequence(x0, xplus, x2) ? xplus : xminus;
+            final double y = f.value(x);
+
+            // check for convergence
+            final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
+            if (FastMath.abs(x - oldx) <= tolerance) {
+                setResult(x, i);
+                return result;
+            }
+            if (FastMath.abs(y) <= functionValueAccuracy) {
+                setResult(x, i);
+                return result;
+            }
+
+            // Bisect if convergence is too slow. Bisection would waste
+            // our calculation of x, hopefully it won't happen often.
+            // the real number equality test x == x1 is intentional and
+            // completes the proximity tests above it
+            boolean bisect = (x < x1 && (x1 - x0) > 0.95 * (x2 - x0)) ||
+                             (x > x1 && (x2 - x1) > 0.95 * (x2 - x0)) ||
+                             (x == x1);
+            // prepare the new bracketing interval for next iteration
+            if (!bisect) {
+                x0 = x < x1 ? x0 : x1;
+                y0 = x < x1 ? y0 : y1;
+                x2 = x > x1 ? x2 : x1;
+                y2 = x > x1 ? y2 : y1;
+                x1 = x; y1 = y;
+                oldx = x;
+            } else {
+                double xm = 0.5 * (x0 + x2);
+                double ym = f.value(xm);
+                if (MathUtils.sign(y0) + MathUtils.sign(ym) == 0.0) {
+                    x2 = xm; y2 = ym;
+                } else {
+                    x0 = xm; y0 = ym;
+                }
+                x1 = 0.5 * (x0 + x2);
+                y1 = f.value(x1);
+                oldx = Double.POSITIVE_INFINITY;
+            }
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+
+    /**
+     * Find a real root in the given interval.
+     * <p>
+     * solve2() differs from solve() in the way it avoids complex operations.
+     * Except for the initial [min, max], solve2() does not require bracketing
+     * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex
+     * number arises in the computation, we simply use its modulus as real
+     * approximation.</p>
+     * <p>
+     * Because the interval may not be bracketing, bisection alternative is
+     * not applicable here. However in practice our treatment usually works
+     * well, especially near real zeros where the imaginary part of complex
+     * approximation is often negligible.</p>
+     * <p>
+     * The formulas here do not use divided differences directly.</p>
+     *
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated replaced by {@link #solve2(UnivariateRealFunction, double, double)}
+     * since 2.0
+     */
+    @Deprecated
+    public double solve2(final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve2(f, min, max);
+    }
+
+    /**
+     * Find a real root in the given interval.
+     * <p>
+     * solve2() differs from solve() in the way it avoids complex operations.
+     * Except for the initial [min, max], solve2() does not require bracketing
+     * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex
+     * number arises in the computation, we simply use its modulus as real
+     * approximation.</p>
+     * <p>
+     * Because the interval may not be bracketing, bisection alternative is
+     * not applicable here. However in practice our treatment usually works
+     * well, especially near real zeros where the imaginary part of complex
+     * approximation is often negligible.</p>
+     * <p>
+     * The formulas here do not use divided differences directly.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve2(final UnivariateRealFunction f,
+                         final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        // x2 is the last root approximation
+        // x is the new approximation and new x2 for next round
+        // x0 < x1 < x2 does not hold here
+
+        double x0 = min;
+        double y0 = f.value(x0);
+        double x1 = max;
+        double y1 = f.value(x1);
+        double x2 = 0.5 * (x0 + x1);
+        double y2 = f.value(x2);
+
+        // check for zeros before verifying bracketing
+        if (y0 == 0.0) { return min; }
+        if (y1 == 0.0) { return max; }
+        verifyBracketing(min, max, f);
+
+        double oldx = Double.POSITIVE_INFINITY;
+        for (int i = 1; i <= maximalIterationCount; ++i) {
+            // quadratic interpolation through x0, x1, x2
+            final double q = (x2 - x1) / (x1 - x0);
+            final double a = q * (y2 - (1 + q) * y1 + q * y0);
+            final double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0;
+            final double c = (1 + q) * y2;
+            final double delta = b * b - 4 * a * c;
+            double x;
+            final double denominator;
+            if (delta >= 0.0) {
+                // choose a denominator larger in magnitude
+                double dplus = b + FastMath.sqrt(delta);
+                double dminus = b - FastMath.sqrt(delta);
+                denominator = FastMath.abs(dplus) > FastMath.abs(dminus) ? dplus : dminus;
+            } else {
+                // take the modulus of (B +/- FastMath.sqrt(delta))
+                denominator = FastMath.sqrt(b * b - delta);
+            }
+            if (denominator != 0) {
+                x = x2 - 2.0 * c * (x2 - x1) / denominator;
+                // perturb x if it exactly coincides with x1 or x2
+                // the equality tests here are intentional
+                while (x == x1 || x == x2) {
+                    x += absoluteAccuracy;
+                }
+            } else {
+                // extremely rare case, get a random number to skip it
+                x = min + FastMath.random() * (max - min);
+                oldx = Double.POSITIVE_INFINITY;
+            }
+            final double y = f.value(x);
+
+            // check for convergence
+            final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
+            if (FastMath.abs(x - oldx) <= tolerance) {
+                setResult(x, i);
+                return result;
+            }
+            if (FastMath.abs(y) <= functionValueAccuracy) {
+                setResult(x, i);
+                return result;
+            }
+
+            // prepare the next iteration
+            x0 = x1;
+            y0 = y1;
+            x1 = x2;
+            y1 = y2;
+            x2 = x;
+            y2 = y;
+            oldx = x;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java
new file mode 100644
index 0000000..a2cffff
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/NewtonSolver.java
@@ -0,0 +1,183 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements <a href="http://mathworld.wolfram.com/NewtonsMethod.html">
+ * Newton's Method</a> for finding zeros of real univariate functions.
+ * <p>
+ * The function should be continuous but not necessarily smooth.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class NewtonSolver extends UnivariateRealSolverImpl {
+
+    /**
+     * Construct a solver for the given function.
+     * @param f function to solve.
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public NewtonSolver(DifferentiableUnivariateRealFunction f) {
+        super(f, 100, 1E-6);
+    }
+
+    /**
+     * Construct a solver.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public NewtonSolver() {
+        super(100, 1E-6);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException  {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max, final double startValue)
+        throws MaxIterationsExceededException, FunctionEvaluationException  {
+        return solve(f, min, max, startValue);
+    }
+
+    /**
+     * Find a zero near the midpoint of <code>min</code> and <code>max</code>.
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param maxEval Maximum number of evaluations.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative
+     * @throws IllegalArgumentException if min is not less than max
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException  {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a zero near the midpoint of <code>min</code> and <code>max</code>.
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative
+     * @throws IllegalArgumentException if min is not less than max
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException  {
+        return solve(f, min, max, UnivariateRealSolverUtils.midpoint(min, max));
+    }
+
+    /**
+     * Find a zero near the value <code>startValue</code>.
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval (ignored).
+     * @param max the upper bound for the interval (ignored).
+     * @param startValue the start value to use.
+     * @param maxEval Maximum number of evaluations.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative
+     * @throws IllegalArgumentException if startValue is not between min and max or
+     * if function is not a {@link DifferentiableUnivariateRealFunction} instance
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max, final double startValue)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max, startValue);
+    }
+
+    /**
+     * Find a zero near the value <code>startValue</code>.
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval (ignored).
+     * @param max the upper bound for the interval (ignored).
+     * @param startValue the start value to use.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function or derivative
+     * @throws IllegalArgumentException if startValue is not between min and max or
+     * if function is not a {@link DifferentiableUnivariateRealFunction} instance
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max, final double startValue)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        try {
+
+            final UnivariateRealFunction derivative =
+                ((DifferentiableUnivariateRealFunction) f).derivative();
+            clearResult();
+            verifySequence(min, startValue, max);
+
+            double x0 = startValue;
+            double x1;
+
+            int i = 0;
+            while (i < maximalIterationCount) {
+
+                x1 = x0 - (f.value(x0) / derivative.value(x0));
+                if (FastMath.abs(x1 - x0) <= absoluteAccuracy) {
+                    setResult(x1, i);
+                    return x1;
+                }
+
+                x0 = x1;
+                ++i;
+            }
+
+            throw new MaxIterationsExceededException(maximalIterationCount);
+        } catch (ClassCastException cce) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.FUNCTION_NOT_DIFFERENTIABLE);
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java
new file mode 100644
index 0000000..4f316c7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/RiddersSolver.java
@@ -0,0 +1,247 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/RiddersMethod.html">
+ * Ridders' Method</a> for root finding of real univariate functions. For
+ * reference, see C. Ridders, <i>A new algorithm for computing a single root
+ * of a real continuous function </i>, IEEE Transactions on Circuits and
+ * Systems, 26 (1979), 979 - 980.
+ * <p>
+ * The function should be continuous but not necessarily smooth.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class RiddersSolver extends UnivariateRealSolverImpl {
+
+    /**
+     * Construct a solver for the given function.
+     *
+     * @param f function to solve
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public RiddersSolver(UnivariateRealFunction f) {
+        super(f, 100, 1E-6);
+    }
+
+    /**
+     * Construct a solver.
+     * @deprecated in 2.2
+     */
+    @Deprecated
+    public RiddersSolver() {
+        super(100, 1E-6);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max, final double initial)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a root in the given interval with initial value.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use
+     * @param maxEval Maximum number of evaluations.
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a root in the given interval with initial value.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        // check for zeros before verifying bracketing
+        if (f.value(min) == 0.0) { return min; }
+        if (f.value(max) == 0.0) { return max; }
+        if (f.value(initial) == 0.0) { return initial; }
+
+        verifyBracketing(min, max, f);
+        verifySequence(min, initial, max);
+        if (isBracketing(min, initial, f)) {
+            return solve(f, min, initial);
+        } else {
+            return solve(f, initial, max);
+        }
+    }
+
+    /**
+     * Find a root in the given interval.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param maxEval Maximum number of evaluations.
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a root in the given interval.
+     * <p>
+     * Requires bracketing condition.</p>
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @return the point at which the function value is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if any parameters are invalid
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        // [x1, x2] is the bracketing interval in each iteration
+        // x3 is the midpoint of [x1, x2]
+        // x is the new root approximation and an endpoint of the new interval
+        double x1 = min;
+        double y1 = f.value(x1);
+        double x2 = max;
+        double y2 = f.value(x2);
+
+        // check for zeros before verifying bracketing
+        if (y1 == 0.0) {
+            return min;
+        }
+        if (y2 == 0.0) {
+            return max;
+        }
+        verifyBracketing(min, max, f);
+
+        int i = 1;
+        double oldx = Double.POSITIVE_INFINITY;
+        while (i <= maximalIterationCount) {
+            // calculate the new root approximation
+            final double x3 = 0.5 * (x1 + x2);
+            final double y3 = f.value(x3);
+            if (FastMath.abs(y3) <= functionValueAccuracy) {
+                setResult(x3, i);
+                return result;
+            }
+            final double delta = 1 - (y1 * y2) / (y3 * y3);  // delta > 1 due to bracketing
+            final double correction = (MathUtils.sign(y2) * MathUtils.sign(y3)) *
+                                      (x3 - x1) / FastMath.sqrt(delta);
+            final double x = x3 - correction;                // correction != 0
+            final double y = f.value(x);
+
+            // check for convergence
+            final double tolerance = FastMath.max(relativeAccuracy * FastMath.abs(x), absoluteAccuracy);
+            if (FastMath.abs(x - oldx) <= tolerance) {
+                setResult(x, i);
+                return result;
+            }
+            if (FastMath.abs(y) <= functionValueAccuracy) {
+                setResult(x, i);
+                return result;
+            }
+
+            // prepare the new interval for next iteration
+            // Ridders' method guarantees x1 < x < x2
+            if (correction > 0.0) {             // x1 < x < x3
+                if (MathUtils.sign(y1) + MathUtils.sign(y) == 0.0) {
+                    x2 = x;
+                    y2 = y;
+                } else {
+                    x1 = x;
+                    x2 = x3;
+                    y1 = y;
+                    y2 = y3;
+                }
+            } else {                            // x3 < x < x2
+                if (MathUtils.sign(y2) + MathUtils.sign(y) == 0.0) {
+                    x1 = x;
+                    y1 = y;
+                } else {
+                    x1 = x3;
+                    x2 = x;
+                    y1 = y3;
+                    y2 = y;
+                }
+            }
+            oldx = x;
+            i++;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java
new file mode 100644
index 0000000..325b662
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/SecantSolver.java
@@ -0,0 +1,230 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Implements a modified version of the
+ * <a href="http://mathworld.wolfram.com/SecantMethod.html">secant method</a>
+ * for approximating a zero of a real univariate function.
+ * <p>
+ * The algorithm is modified to maintain bracketing of a root by successive
+ * approximations. Because of forced bracketing, convergence may be slower than
+ * the unrestricted secant algorithm. However, this implementation should in
+ * general outperform the
+ * <a href="http://mathworld.wolfram.com/MethodofFalsePosition.html">
+ * regula falsi method.</a></p>
+ * <p>
+ * The function is assumed to be continuous but not necessarily smooth.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class SecantSolver extends UnivariateRealSolverImpl {
+
+    /**
+     * Construct a solver for the given function.
+     * @param f function to solve.
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    public SecantSolver(UnivariateRealFunction f) {
+        super(f, 100, 1E-6);
+    }
+
+    /**
+     * Construct a solver.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public SecantSolver() {
+        super(100, 1E-6);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double solve(final double min, final double max, final double initial)
+        throws ConvergenceException, FunctionEvaluationException {
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a zero in the given interval.
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use (ignored)
+     * @param maxEval Maximum number of evaluations.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min is not less than max or the
+     * signs of the values of the function at the endpoints are not opposites
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max, initial);
+    }
+
+    /**
+     * Find a zero in the given interval.
+     *
+     * @param f the function to solve
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param initial the start value to use (ignored)
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min is not less than max or the
+     * signs of the values of the function at the endpoints are not opposites
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max, final double initial)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a zero in the given interval.
+     * @param f the function to solve
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param maxEval Maximum number of evaluations.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException  if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min is not less than max or the
+     * signs of the values of the function at the endpoints are not opposites
+     */
+    @Override
+    public double solve(int maxEval, final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        setMaximalIterationCount(maxEval);
+        return solve(f, min, max);
+    }
+
+    /**
+     * Find a zero in the given interval.
+     * @param f the function to solve
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @return the value where the function is zero
+     * @throws MaxIterationsExceededException  if the maximum iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min is not less than max or the
+     * signs of the values of the function at the endpoints are not opposites
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public double solve(final UnivariateRealFunction f,
+                        final double min, final double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+
+        clearResult();
+        verifyInterval(min, max);
+
+        // Index 0 is the old approximation for the root.
+        // Index 1 is the last calculated approximation  for the root.
+        // Index 2 is a bracket for the root with respect to x0.
+        // OldDelta is the length of the bracketing interval of the last
+        // iteration.
+        double x0 = min;
+        double x1 = max;
+        double y0 = f.value(x0);
+        double y1 = f.value(x1);
+
+        // Verify bracketing
+        if (y0 * y1 >= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.SAME_SIGN_AT_ENDPOINTS, min, max, y0, y1);
+        }
+
+        double x2 = x0;
+        double y2 = y0;
+        double oldDelta = x2 - x1;
+        int i = 0;
+        while (i < maximalIterationCount) {
+            if (FastMath.abs(y2) < FastMath.abs(y1)) {
+                x0 = x1;
+                x1 = x2;
+                x2 = x0;
+                y0 = y1;
+                y1 = y2;
+                y2 = y0;
+            }
+            if (FastMath.abs(y1) <= functionValueAccuracy) {
+                setResult(x1, i);
+                return result;
+            }
+            if (FastMath.abs(oldDelta) <
+                FastMath.max(relativeAccuracy * FastMath.abs(x1), absoluteAccuracy)) {
+                setResult(x1, i);
+                return result;
+            }
+            double delta;
+            if (FastMath.abs(y1) > FastMath.abs(y0)) {
+                // Function value increased in last iteration. Force bisection.
+                delta = 0.5 * oldDelta;
+            } else {
+                delta = (x0 - x1) / (1 - y0 / y1);
+                if (delta / oldDelta > 1) {
+                    // New approximation falls outside bracket.
+                    // Fall back to bisection.
+                    delta = 0.5 * oldDelta;
+                }
+            }
+            x0 = x1;
+            y0 = y1;
+            x1 = x1 + delta;
+            y1 = f.value(x1);
+            if ((y1 > 0) == (y2 > 0)) {
+                // New bracket is (x0,x1).
+                x2 = x0;
+                y2 = y0;
+            }
+            oldDelta = x2 - x1;
+            i++;
+        }
+        throw new MaxIterationsExceededException(maximalIterationCount);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java
new file mode 100644
index 0000000..6540f67
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.java
@@ -0,0 +1,165 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.ConvergingAlgorithm;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+
+/**
+ * Interface for (univariate real) rootfinding algorithms.
+ * <p>
+ * Implementations will search for only one zero in the given interval.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public interface UnivariateRealSolver extends ConvergingAlgorithm {
+
+    /**
+     * Set the function value accuracy.
+     * <p>
+     * This is used to determine when an evaluated function value or some other
+     * value which is used as divisor is zero.</p>
+     * <p>
+     * This is a safety guard and it shouldn't be necessary to change this in
+     * general.</p>
+     *
+     * @param accuracy the accuracy.
+     * @throws IllegalArgumentException if the accuracy can't be achieved by
+     * the solver or is otherwise deemed unreasonable.
+     */
+    void setFunctionValueAccuracy(double accuracy);
+
+    /**
+     * Get the actual function value accuracy.
+     * @return the accuracy
+     */
+    double getFunctionValueAccuracy();
+
+    /**
+     * Reset the actual function accuracy to the default.
+     * The default value is provided by the solver implementation.
+     */
+    void resetFunctionValueAccuracy();
+
+    /**
+     * Solve for a zero root in the given interval.
+     * <p>A solver may require that the interval brackets a single zero root.
+     * Solvers that do require bracketing should be able to handle the case
+     * where one of the endpoints is itself a root.</p>
+     *
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the endpoints do not
+     * satisfy the requirements specified by the solver
+     * @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double)}
+     * since 2.0
+     */
+    @Deprecated
+    double solve(double min, double max) throws ConvergenceException, FunctionEvaluationException;
+
+    /**
+     * Solve for a zero root in the given interval.
+     * <p>A solver may require that the interval brackets a single zero root.
+     * Solvers that do require bracketing should be able to handle the case
+     * where one of the endpoints is itself a root.</p>
+     *
+     * @param f the function to solve.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the endpoints do not
+     * satisfy the requirements specified by the solver
+     * @since 2.0
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    double solve(UnivariateRealFunction f, double min, double max)
+        throws ConvergenceException, FunctionEvaluationException;
+
+    /**
+     * Solve for a zero in the given interval, start at startValue.
+     * <p>A solver may require that the interval brackets a single zero root.
+     * Solvers that do require bracketing should be able to handle the case
+     * where one of the endpoints is itself a root.</p>
+     *
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param startValue the start value to use
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the arguments do not
+     * satisfy the requirements specified by the solver
+     * @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double, double)}
+     * since 2.0
+     */
+    @Deprecated
+    double solve(double min, double max, double startValue)
+        throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException;
+
+    /**
+     * Solve for a zero in the given interval, start at startValue.
+     * <p>A solver may require that the interval brackets a single zero root.
+     * Solvers that do require bracketing should be able to handle the case
+     * where one of the endpoints is itself a root.</p>
+     *
+     * @param f the function to solve.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param startValue the start value to use
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the arguments do not
+     * satisfy the requirements specified by the solver
+     * @since 2.0
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    double solve(UnivariateRealFunction f, double min, double max, double startValue)
+        throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException;
+
+    /**
+     * Get the result of the last run of the solver.
+     *
+     * @return the last result.
+     * @throws IllegalStateException if there is no result available, either
+     * because no result was yet computed or the last attempt failed.
+     */
+    double getResult();
+
+    /**
+     * Get the result of the last run of the solver.
+     *
+     * @return the value of the function at the last result.
+     * @throws IllegalStateException if there is no result available, either
+     * because no result was yet computed or the last attempt failed.
+     */
+    double getFunctionValue();
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactory.java b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactory.java
new file mode 100644
index 0000000..46b7234
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactory.java
@@ -0,0 +1,90 @@
+/*
+ * 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.analysis.solvers;
+
+/**
+ * Abstract factory class used to create {@link UnivariateRealSolver} instances.
+ * <p>
+ * Solvers implementing the following algorithms are supported:
+ * <ul>
+ * <li>Bisection</li>
+ * <li>Brent's method</li>
+ * <li>Secant method</li>
+ * </ul>
+ * Concrete factories extending this class also specify a default solver, instances of which
+ * are returned by <code>newDefaultSolver()</code>.</p>
+ * <p>
+ * Common usage:<pre>
+ * SolverFactory factory = UnivariateRealSolverFactory.newInstance();</p>
+ *
+ * // create a Brent solver to use
+ * BrentSolver solver = factory.newBrentSolver();
+ * </pre>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public abstract class UnivariateRealSolverFactory {
+    /**
+     * Default constructor.
+     */
+    protected UnivariateRealSolverFactory() {
+    }
+
+    /**
+     * Create a new factory.
+     * @return a new factory.
+     */
+    public static UnivariateRealSolverFactory newInstance() {
+        return new UnivariateRealSolverFactoryImpl();
+    }
+
+    /**
+     * Create a new {@link UnivariateRealSolver}.  The
+     * actual solver returned is determined by the underlying factory.
+     * @return the new solver.
+     */
+    public abstract UnivariateRealSolver newDefaultSolver();
+
+    /**
+     * Create a new {@link UnivariateRealSolver}.  The
+     * solver is an implementation of the bisection method.
+     * @return the new solver.
+     */
+    public abstract UnivariateRealSolver newBisectionSolver();
+
+    /**
+     * Create a new {@link UnivariateRealSolver}.  The
+     * solver is an implementation of the Brent method.
+     * @return the new solver.
+     */
+    public abstract UnivariateRealSolver newBrentSolver();
+
+    /**
+     * Create a new {@link UnivariateRealSolver}.  The
+     * solver is an implementation of Newton's Method.
+     * @return the new solver.
+     */
+    public abstract UnivariateRealSolver newNewtonSolver();
+
+    /**
+     * Create a new {@link UnivariateRealSolver}.  The
+     * solver is an implementation of the secant method.
+     * @return the new solver.
+     */
+    public abstract UnivariateRealSolver newSecantSolver();
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImpl.java b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImpl.java
new file mode 100644
index 0000000..cb4c6b2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImpl.java
@@ -0,0 +1,64 @@
+/*
+ * 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.analysis.solvers;
+
+/**
+ * A concrete {@link  UnivariateRealSolverFactory}.  This is the default solver factory
+ * used by commons-math.
+ * <p>
+ * The default solver returned by this factory is a {@link BrentSolver}.</p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class UnivariateRealSolverFactoryImpl extends UnivariateRealSolverFactory {
+
+    /**
+     * Default constructor.
+     */
+    public UnivariateRealSolverFactoryImpl() {
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public UnivariateRealSolver newDefaultSolver() {
+        return newBrentSolver();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public UnivariateRealSolver newBisectionSolver() {
+        return new BisectionSolver();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public UnivariateRealSolver newBrentSolver() {
+        return new BrentSolver();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public UnivariateRealSolver newNewtonSolver() {
+        return new NewtonSolver();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public UnivariateRealSolver newSecantSolver() {
+        return new SecantSolver();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java
new file mode 100644
index 0000000..557c767
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java
@@ -0,0 +1,304 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergingAlgorithmImpl;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * Provide a default implementation for several functions useful to generic
+ * solvers.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @deprecated in 2.2 (to be removed in 3.0).
+ */
+@Deprecated
+public abstract class UnivariateRealSolverImpl
+    extends ConvergingAlgorithmImpl implements UnivariateRealSolver {
+
+    /** Maximum error of function. */
+    protected double functionValueAccuracy;
+
+    /** Default maximum error of function. */
+    protected double defaultFunctionValueAccuracy;
+
+    /** Indicates where a root has been computed. */
+    protected boolean resultComputed = false;
+
+    /** The last computed root. */
+    protected double result;
+
+    /** Value of the function at the last computed result. */
+    protected double functionValue;
+
+    /** The function to solve.
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method. */
+    @Deprecated
+    protected UnivariateRealFunction f;
+
+    /**
+     * Construct a solver with given iteration count and accuracy.
+     *
+     * @param f the function to solve.
+     * @param defaultAbsoluteAccuracy maximum absolute error
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @throws IllegalArgumentException if f is null or the
+     * defaultAbsoluteAccuracy is not valid
+     * @deprecated as of 2.0 the function to solve is passed as an argument
+     * to the {@link #solve(UnivariateRealFunction, double, double)} or
+     * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
+     * method.
+     */
+    @Deprecated
+    protected UnivariateRealSolverImpl(final UnivariateRealFunction f,
+                                       final int defaultMaximalIterationCount,
+                                       final double defaultAbsoluteAccuracy) {
+        super(defaultMaximalIterationCount, defaultAbsoluteAccuracy);
+        if (f == null) {
+            throw new NullArgumentException(LocalizedFormats.FUNCTION);
+        }
+        this.f = f;
+        this.defaultFunctionValueAccuracy = 1.0e-15;
+        this.functionValueAccuracy = defaultFunctionValueAccuracy;
+    }
+
+    /**
+     * Construct a solver with given iteration count and accuracy.
+     *
+     * @param defaultAbsoluteAccuracy maximum absolute error
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @throws IllegalArgumentException if f is null or the
+     * defaultAbsoluteAccuracy is not valid
+     */
+    protected UnivariateRealSolverImpl(final int defaultMaximalIterationCount,
+                                       final double defaultAbsoluteAccuracy) {
+        super(defaultMaximalIterationCount, defaultAbsoluteAccuracy);
+        this.defaultFunctionValueAccuracy = 1.0e-15;
+        this.functionValueAccuracy = defaultFunctionValueAccuracy;
+    }
+
+    /** Check if a result has been computed.
+     * @exception IllegalStateException if no result has been computed
+     */
+    protected void checkResultComputed() throws IllegalStateException {
+        if (!resultComputed) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public double getResult() {
+        checkResultComputed();
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    public double getFunctionValue() {
+        checkResultComputed();
+        return functionValue;
+    }
+
+    /** {@inheritDoc} */
+    public void setFunctionValueAccuracy(final double accuracy) {
+        functionValueAccuracy = accuracy;
+    }
+
+    /** {@inheritDoc} */
+    public double getFunctionValueAccuracy() {
+        return functionValueAccuracy;
+    }
+
+    /** {@inheritDoc} */
+    public void resetFunctionValueAccuracy() {
+        functionValueAccuracy = defaultFunctionValueAccuracy;
+    }
+
+    /**
+     * Solve for a zero root in the given interval.
+     * <p>A solver may require that the interval brackets a single zero root.
+     * Solvers that do require bracketing should be able to handle the case
+     * where one of the endpoints is itself a root.</p>
+     *
+     * @param function the function to solve.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param maxEval Maximum number of evaluations.
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the endpoints do not
+     * satisfy the requirements specified by the solver
+     * @since 2.2
+     */
+    public double solve(int maxEval, UnivariateRealFunction function, double min, double max)
+        throws ConvergenceException, FunctionEvaluationException {
+        throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN);
+    }
+
+    /**
+     * Solve for a zero in the given interval, start at startValue.
+     * <p>A solver may require that the interval brackets a single zero root.
+     * Solvers that do require bracketing should be able to handle the case
+     * where one of the endpoints is itself a root.</p>
+     *
+     * @param function the function to solve.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param startValue the start value to use
+     * @param maxEval Maximum number of evaluations.
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the solver detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if min > max or the arguments do not
+     * satisfy the requirements specified by the solver
+     * @since 2.2
+     */
+    public double solve(int maxEval, UnivariateRealFunction function, double min, double max, double startValue)
+        throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException {
+        throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN);
+    }
+
+    /**
+     * Convenience function for implementations.
+     *
+     * @param newResult the result to set
+     * @param iterationCount the iteration count to set
+     */
+    protected final void setResult(final double newResult, final int iterationCount) {
+        this.result         = newResult;
+        this.iterationCount = iterationCount;
+        this.resultComputed = true;
+    }
+
+    /**
+     * Convenience function for implementations.
+     *
+     * @param x the result to set
+     * @param fx the result to set
+     * @param iterationCount the iteration count to set
+     */
+    protected final void setResult(final double x, final double fx,
+                                   final int iterationCount) {
+        this.result         = x;
+        this.functionValue  = fx;
+        this.iterationCount = iterationCount;
+        this.resultComputed = true;
+    }
+
+    /**
+     * Convenience function for implementations.
+     */
+    protected final void clearResult() {
+        this.iterationCount = 0;
+        this.resultComputed = false;
+    }
+
+    /**
+     * Returns true iff the function takes opposite signs at the endpoints.
+     *
+     * @param lower  the lower endpoint
+     * @param upper  the upper endpoint
+     * @param function the function
+     * @return true if f(lower) * f(upper) < 0
+     * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints
+     */
+    protected boolean isBracketing(final double lower, final double upper,
+                                   final UnivariateRealFunction function)
+        throws FunctionEvaluationException {
+        final double f1 = function.value(lower);
+        final double f2 = function.value(upper);
+        return (f1 > 0 && f2 < 0) || (f1 < 0 && f2 > 0);
+    }
+
+    /**
+     * Returns true if the arguments form a (strictly) increasing sequence
+     *
+     * @param start  first number
+     * @param mid   second number
+     * @param end  third number
+     * @return true if the arguments form an increasing sequence
+     */
+    protected boolean isSequence(final double start, final double mid, final double end) {
+        return (start < mid) && (mid < end);
+    }
+
+    /**
+     * Verifies that the endpoints specify an interval,
+     * throws IllegalArgumentException if not
+     *
+     * @param lower  lower endpoint
+     * @param upper upper endpoint
+     * @throws IllegalArgumentException
+     */
+    protected void verifyInterval(final double lower, final double upper) {
+        if (lower >= upper) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
+                    lower, upper);
+        }
+    }
+
+    /**
+     * Verifies that <code>lower < initial < upper</code>
+     * throws IllegalArgumentException if not
+     *
+     * @param lower  lower endpoint
+     * @param initial initial value
+     * @param upper upper endpoint
+     * @throws IllegalArgumentException
+     */
+    protected void verifySequence(final double lower, final double initial, final double upper) {
+        if (!isSequence(lower, initial, upper)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS,
+                    lower, initial, upper);
+        }
+    }
+
+    /**
+     * Verifies that the endpoints specify an interval and the function takes
+     * opposite signs at the endpoints, throws IllegalArgumentException if not
+     *
+     * @param lower  lower endpoint
+     * @param upper upper endpoint
+     * @param function function
+     * @throws IllegalArgumentException
+     * @throws FunctionEvaluationException if an error occurs evaluating the function at the endpoints
+     */
+    protected void verifyBracketing(final double lower, final double upper,
+                                    final UnivariateRealFunction function)
+        throws FunctionEvaluationException {
+
+        verifyInterval(lower, upper);
+        if (!isBracketing(lower, upper, function)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.SAME_SIGN_AT_ENDPOINTS,
+                    lower, upper, function.value(lower), function.value(upper));
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
new file mode 100644
index 0000000..3186d6a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
@@ -0,0 +1,240 @@
+/*
+ * 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.analysis.solvers;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Utility routines for {@link UnivariateRealSolver} objects.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class UnivariateRealSolverUtils {
+
+    /**
+     * Default constructor.
+     */
+    private UnivariateRealSolverUtils() {
+        super();
+    }
+
+    /**
+     * Convenience method to find a zero of a univariate real function.  A default
+     * solver is used.
+     *
+     * @param f the function.
+     * @param x0 the lower bound for the interval.
+     * @param x1 the upper bound for the interval.
+     * @return a value where the function is zero.
+     * @throws ConvergenceException if the iteration count was exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if f is null or the endpoints do not
+     * specify a valid interval
+     */
+    public static double solve(UnivariateRealFunction f, double x0, double x1)
+    throws ConvergenceException, FunctionEvaluationException {
+        setup(f);
+        return LazyHolder.FACTORY.newDefaultSolver().solve(f, x0, x1);
+    }
+
+    /**
+     * Convenience method to find a zero of a univariate real function.  A default
+     * solver is used.
+     *
+     * @param f the function
+     * @param x0 the lower bound for the interval
+     * @param x1 the upper bound for the interval
+     * @param absoluteAccuracy the accuracy to be used by the solver
+     * @return a value where the function is zero
+     * @throws ConvergenceException if the iteration count is exceeded
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if f is null, the endpoints do not
+     * specify a valid interval, or the absoluteAccuracy is not valid for the
+     * default solver
+     */
+    public static double solve(UnivariateRealFunction f, double x0, double x1,
+            double absoluteAccuracy) throws ConvergenceException,
+            FunctionEvaluationException {
+
+        setup(f);
+        UnivariateRealSolver solver = LazyHolder.FACTORY.newDefaultSolver();
+        solver.setAbsoluteAccuracy(absoluteAccuracy);
+        return solver.solve(f, x0, x1);
+    }
+
+    /**
+     * This method attempts to find two values a and b satisfying <ul>
+    * <li> <code> lowerBound <= a < initial < b <= upperBound</code> </li>
+     * <li> <code> f(a) * f(b) < 0 </code></li>
+     * </ul>
+     * If f is continuous on <code>[a,b],</code> this means that <code>a</code>
+     * and <code>b</code> bracket a root of f.
+     * <p>
+     * The algorithm starts by setting
+     * <code>a := initial -1; b := initial +1,</code> examines the value of the
+     * function at <code>a</code> and <code>b</code> and keeps moving
+     * the endpoints out by one unit each time through a loop that terminates
+     * when one of the following happens: <ul>
+     * <li> <code> f(a) * f(b) < 0 </code> --  success!</li>
+     * <li> <code> a = lower </code> and <code> b = upper</code>
+     * -- ConvergenceException </li>
+     * <li> <code> Integer.MAX_VALUE</code> iterations elapse
+     * -- ConvergenceException </li>
+     * </ul></p>
+     * <p>
+     * <strong>Note: </strong> this method can take
+     * <code>Integer.MAX_VALUE</code> iterations to throw a
+     * <code>ConvergenceException.</code>  Unless you are confident that there
+     * is a root between <code>lowerBound</code> and <code>upperBound</code>
+     * near <code>initial,</code> it is better to use
+     * {@link #bracket(UnivariateRealFunction, double, double, double, int)},
+     * explicitly specifying the maximum number of iterations.</p>
+     *
+     * @param function the function
+     * @param initial initial midpoint of interval being expanded to
+     * bracket a root
+     * @param lowerBound lower bound (a is never lower than this value)
+     * @param upperBound upper bound (b never is greater than this
+     * value)
+     * @return a two element array holding {a, b}
+     * @throws ConvergenceException if a root can not be bracketted
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if function is null, maximumIterations
+     * is not positive, or initial is not between lowerBound and upperBound
+     */
+    public static double[] bracket(UnivariateRealFunction function,
+            double initial, double lowerBound, double upperBound)
+    throws ConvergenceException, FunctionEvaluationException {
+        return bracket( function, initial, lowerBound, upperBound,
+            Integer.MAX_VALUE ) ;
+    }
+
+     /**
+     * This method attempts to find two values a and b satisfying <ul>
+     * <li> <code> lowerBound <= a < initial < b <= upperBound</code> </li>
+     * <li> <code> f(a) * f(b) <= 0 </code> </li>
+     * </ul>
+     * If f is continuous on <code>[a,b],</code> this means that <code>a</code>
+     * and <code>b</code> bracket a root of f.
+     * <p>
+     * The algorithm starts by setting
+     * <code>a := initial -1; b := initial +1,</code> examines the value of the
+     * function at <code>a</code> and <code>b</code> and keeps moving
+     * the endpoints out by one unit each time through a loop that terminates
+     * when one of the following happens: <ul>
+     * <li> <code> f(a) * f(b) <= 0 </code> --  success!</li>
+     * <li> <code> a = lower </code> and <code> b = upper</code>
+     * -- ConvergenceException </li>
+     * <li> <code> maximumIterations</code> iterations elapse
+     * -- ConvergenceException </li></ul></p>
+     *
+     * @param function the function
+     * @param initial initial midpoint of interval being expanded to
+     * bracket a root
+     * @param lowerBound lower bound (a is never lower than this value)
+     * @param upperBound upper bound (b never is greater than this
+     * value)
+     * @param maximumIterations maximum number of iterations to perform
+     * @return a two element array holding {a, b}.
+     * @throws ConvergenceException if the algorithm fails to find a and b
+     * satisfying the desired conditions
+     * @throws FunctionEvaluationException if an error occurs evaluating the function
+     * @throws IllegalArgumentException if function is null, maximumIterations
+     * is not positive, or initial is not between lowerBound and upperBound
+     */
+    public static double[] bracket(UnivariateRealFunction function,
+            double initial, double lowerBound, double upperBound,
+            int maximumIterations) throws ConvergenceException,
+            FunctionEvaluationException {
+
+        if (function == null) {
+            throw new NullArgumentException(LocalizedFormats.FUNCTION);
+        }
+        if (maximumIterations <= 0)  {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INVALID_MAX_ITERATIONS, maximumIterations);
+        }
+        if (initial < lowerBound || initial > upperBound || lowerBound >= upperBound) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INVALID_BRACKETING_PARAMETERS,
+                  lowerBound, initial, upperBound);
+        }
+        double a = initial;
+        double b = initial;
+        double fa;
+        double fb;
+        int numIterations = 0 ;
+
+        do {
+            a = FastMath.max(a - 1.0, lowerBound);
+            b = FastMath.min(b + 1.0, upperBound);
+            fa = function.value(a);
+
+            fb = function.value(b);
+            numIterations++ ;
+        } while ((fa * fb > 0.0) && (numIterations < maximumIterations) &&
+                ((a > lowerBound) || (b < upperBound)));
+
+        if (fa * fb > 0.0 ) {
+            throw new ConvergenceException(
+                      LocalizedFormats.FAILED_BRACKETING,
+                      numIterations, maximumIterations, initial,
+                      lowerBound, upperBound, a, b, fa, fb);
+        }
+
+        return new double[]{a, b};
+    }
+
+    /**
+     * Compute the midpoint of two values.
+     *
+     * @param a first value.
+     * @param b second value.
+     * @return the midpoint.
+     */
+    public static double midpoint(double a, double b) {
+        return (a + b) * .5;
+    }
+
+    /**
+     * Checks to see if f is null, throwing IllegalArgumentException if so.
+     * @param f  input function
+     * @throws IllegalArgumentException if f is null
+     */
+    private static void setup(UnivariateRealFunction f) {
+        if (f == null) {
+            throw new NullArgumentException(LocalizedFormats.FUNCTION);
+        }
+    }
+
+    // CHECKSTYLE: stop HideUtilityClassConstructor
+    /** Holder for the factory.
+     * <p>We use here the Initialization On Demand Holder Idiom.</p>
+     */
+    private static class LazyHolder {
+        /** Cached solver factory */
+        private static final UnivariateRealSolverFactory FACTORY = UnivariateRealSolverFactory.newInstance();
+    }
+    // CHECKSTYLE: resume HideUtilityClassConstructor
+
+}
diff --git a/src/main/java/org/apache/commons/math/analysis/solvers/package.html b/src/main/java/org/apache/commons/math/analysis/solvers/package.html
new file mode 100644
index 0000000..bbb49d1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/analysis/solvers/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+     Root finding algorithms, for univariate real functions.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/complex/Complex.java b/src/main/java/org/apache/commons/math/complex/Complex.java
new file mode 100644
index 0000000..ad2bc96
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/complex/Complex.java
@@ -0,0 +1,1007 @@
+/*
+ * 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.complex;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Representation of a Complex number - a number which has both a
+ * real and imaginary part.
+ * <p>
+ * Implementations of arithmetic operations handle <code>NaN</code> and
+ * infinite values according to the rules for {@link java.lang.Double}
+ * arithmetic, applying definitional formulas and returning <code>NaN</code> or
+ * infinite values in real or imaginary parts as these arise in computation.
+ * See individual method javadocs for details.</p>
+ * <p>
+ * {@link #equals} identifies all values with <code>NaN</code> in either real
+ * or imaginary part - e.g., <pre>
+ * <code>1 + NaNi  == NaN + i == NaN + NaNi.</code></pre></p>
+ *
+ * implements Serializable since 2.0
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public class Complex implements FieldElement<Complex>, Serializable  {
+
+    /** The square root of -1. A number representing "0.0 + 1.0i" */
+    public static final Complex I = new Complex(0.0, 1.0);
+
+    // CHECKSTYLE: stop ConstantName
+    /** A complex number representing "NaN + NaNi" */
+    public static final Complex NaN = new Complex(Double.NaN, Double.NaN);
+    // CHECKSTYLE: resume ConstantName
+
+    /** A complex number representing "+INF + INFi" */
+    public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
+
+    /** A complex number representing "1.0 + 0.0i" */
+    public static final Complex ONE = new Complex(1.0, 0.0);
+
+    /** A complex number representing "0.0 + 0.0i" */
+    public static final Complex ZERO = new Complex(0.0, 0.0);
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -6195664516687396620L;
+
+    /** The imaginary part. */
+    private final double imaginary;
+
+    /** The real part. */
+    private final double real;
+
+    /** Record whether this complex number is equal to NaN. */
+    private final transient boolean isNaN;
+
+    /** Record whether this complex number is infinite. */
+    private final transient boolean isInfinite;
+
+    /**
+     * Create a complex number given the real and imaginary parts.
+     *
+     * @param real the real part
+     * @param imaginary the imaginary part
+     */
+    public Complex(double real, double imaginary) {
+        super();
+        this.real = real;
+        this.imaginary = imaginary;
+
+        isNaN = Double.isNaN(real) || Double.isNaN(imaginary);
+        isInfinite = !isNaN &&
+        (Double.isInfinite(real) || Double.isInfinite(imaginary));
+    }
+
+    /**
+     * Return the absolute value of this complex number.
+     * <p>
+     * Returns <code>NaN</code> if either real or imaginary part is
+     * <code>NaN</code> and <code>Double.POSITIVE_INFINITY</code> if
+     * neither part is <code>NaN</code>, but at least one part takes an infinite
+     * value.</p>
+     *
+     * @return the absolute value
+     */
+    public double abs() {
+        if (isNaN()) {
+            return Double.NaN;
+        }
+
+        if (isInfinite()) {
+            return Double.POSITIVE_INFINITY;
+        }
+
+        if (FastMath.abs(real) < FastMath.abs(imaginary)) {
+            if (imaginary == 0.0) {
+                return FastMath.abs(real);
+            }
+            double q = real / imaginary;
+            return FastMath.abs(imaginary) * FastMath.sqrt(1 + q * q);
+        } else {
+            if (real == 0.0) {
+                return FastMath.abs(imaginary);
+            }
+            double q = imaginary / real;
+            return FastMath.abs(real) * FastMath.sqrt(1 + q * q);
+        }
+    }
+
+    /**
+     * Return the sum of this complex number and the given complex number.
+     * <p>
+     * Uses the definitional formula
+     * <pre>
+     * (a + bi) + (c + di) = (a+c) + (b+d)i
+     * </pre></p>
+     * <p>
+     * If either this or <code>rhs</code> has a NaN value in either part,
+     * {@link #NaN} is returned; otherwise Inifinite and NaN values are
+     * returned in the parts of the result according to the rules for
+     * {@link java.lang.Double} arithmetic.</p>
+     *
+     * @param rhs the other complex number
+     * @return the complex number sum
+     * @throws NullPointerException if <code>rhs</code> is null
+     */
+    public Complex add(Complex rhs) {
+        return createComplex(real + rhs.getReal(),
+            imaginary + rhs.getImaginary());
+    }
+
+    /**
+     * Return the conjugate of this complex number. The conjugate of
+     * "A + Bi" is "A - Bi".
+     * <p>
+     * {@link #NaN} is returned if either the real or imaginary
+     * part of this Complex number equals <code>Double.NaN</code>.</p>
+     * <p>
+     * If the imaginary part is infinite, and the real part is not NaN,
+     * the returned value has infinite imaginary part of the opposite
+     * sign - e.g. the conjugate of <code>1 + POSITIVE_INFINITY i</code>
+     * is <code>1 - NEGATIVE_INFINITY i</code></p>
+     *
+     * @return the conjugate of this Complex object
+     */
+    public Complex conjugate() {
+        if (isNaN()) {
+            return NaN;
+        }
+        return createComplex(real, -imaginary);
+    }
+
+    /**
+     * Return the quotient of this complex number and the given complex number.
+     * <p>
+     * Implements the definitional formula
+     * <pre><code>
+     *    a + bi          ac + bd + (bc - ad)i
+     *    ----------- = -------------------------
+     *    c + di         c<sup>2</sup> + d<sup>2</sup>
+     * </code></pre>
+     * but uses
+     * <a href="http://doi.acm.org/10.1145/1039813.1039814">
+     * prescaling of operands</a> to limit the effects of overflows and
+     * underflows in the computation.</p>
+     * <p>
+     * Infinite and NaN values are handled / returned according to the
+     * following rules, applied in the order presented:
+     * <ul>
+     * <li>If either this or <code>rhs</code> has a NaN value in either part,
+     *  {@link #NaN} is returned.</li>
+     * <li>If <code>rhs</code> equals {@link #ZERO}, {@link #NaN} is returned.
+     * </li>
+     * <li>If this and <code>rhs</code> are both infinite,
+     * {@link #NaN} is returned.</li>
+     * <li>If this is finite (i.e., has no infinite or NaN parts) and
+     *  <code>rhs</code> is infinite (one or both parts infinite),
+     * {@link #ZERO} is returned.</li>
+     * <li>If this is infinite and <code>rhs</code> is finite, NaN values are
+     * returned in the parts of the result if the {@link java.lang.Double}
+     * rules applied to the definitional formula force NaN results.</li>
+     * </ul></p>
+     *
+     * @param rhs the other complex number
+     * @return the complex number quotient
+     * @throws NullPointerException if <code>rhs</code> is null
+     */
+    public Complex divide(Complex rhs) {
+        if (isNaN() || rhs.isNaN()) {
+            return NaN;
+        }
+
+        double c = rhs.getReal();
+        double d = rhs.getImaginary();
+        if (c == 0.0 && d == 0.0) {
+            return NaN;
+        }
+
+        if (rhs.isInfinite() && !isInfinite()) {
+            return ZERO;
+        }
+
+        if (FastMath.abs(c) < FastMath.abs(d)) {
+            double q = c / d;
+            double denominator = c * q + d;
+            return createComplex((real * q + imaginary) / denominator,
+                (imaginary * q - real) / denominator);
+        } else {
+            double q = d / c;
+            double denominator = d * q + c;
+            return createComplex((imaginary * q + real) / denominator,
+                (imaginary - real * q) / denominator);
+        }
+    }
+
+    /**
+     * Test for the equality of two Complex objects.
+     * <p>
+     * If both the real and imaginary parts of two Complex numbers
+     * are exactly the same, and neither is <code>Double.NaN</code>, the two
+     * Complex objects are considered to be equal.</p>
+     * <p>
+     * All <code>NaN</code> values are considered to be equal - i.e, if either
+     * (or both) real and imaginary parts of the complex number are equal
+     * to <code>Double.NaN</code>, the complex number is equal to
+     * <code>Complex.NaN</code>.</p>
+     *
+     * @param other Object to test for equality to this
+     * @return true if two Complex objects are equal, false if
+     *         object is null, not an instance of Complex, or
+     *         not equal to this Complex instance
+     *
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof Complex){
+            Complex rhs = (Complex)other;
+            if (rhs.isNaN()) {
+                return this.isNaN();
+            } else {
+                return (real == rhs.real) && (imaginary == rhs.imaginary);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get a hashCode for the complex number.
+     * <p>
+     * All NaN values have the same hash code.</p>
+     *
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        if (isNaN()) {
+            return 7;
+        }
+        return 37 * (17 * MathUtils.hash(imaginary) +
+            MathUtils.hash(real));
+    }
+
+    /**
+     * Access the imaginary part.
+     *
+     * @return the imaginary part
+     */
+    public double getImaginary() {
+        return imaginary;
+    }
+
+    /**
+     * Access the real part.
+     *
+     * @return the real part
+     */
+    public double getReal() {
+        return real;
+    }
+
+    /**
+     * Returns true if either or both parts of this complex number is NaN;
+     * false otherwise
+     *
+     * @return  true if either or both parts of this complex number is NaN;
+     * false otherwise
+     */
+    public boolean isNaN() {
+        return isNaN;
+    }
+
+    /**
+     * Returns true if either the real or imaginary part of this complex number
+     * takes an infinite value (either <code>Double.POSITIVE_INFINITY</code> or
+     * <code>Double.NEGATIVE_INFINITY</code>) and neither part
+     * is <code>NaN</code>.
+     *
+     * @return true if one or both parts of this complex number are infinite
+     * and neither part is <code>NaN</code>
+     */
+    public boolean isInfinite() {
+        return isInfinite;
+    }
+
+    /**
+     * Return the product of this complex number and the given complex number.
+     * <p>
+     * Implements preliminary checks for NaN and infinity followed by
+     * the definitional formula:
+     * <pre><code>
+     * (a + bi)(c + di) = (ac - bd) + (ad + bc)i
+     * </code></pre>
+     * </p>
+     * <p>
+     * Returns {@link #NaN} if either this or <code>rhs</code> has one or more
+     * NaN parts.
+     * </p>
+     * Returns {@link #INF} if neither this nor <code>rhs</code> has one or more
+     * NaN parts and if either this or <code>rhs</code> has one or more
+     * infinite parts (same result is returned regardless of the sign of the
+     * components).
+     * </p>
+     * <p>
+     * Returns finite values in components of the result per the
+     * definitional formula in all remaining cases.
+     *  </p>
+     *
+     * @param rhs the other complex number
+     * @return the complex number product
+     * @throws NullPointerException if <code>rhs</code> is null
+     */
+    public Complex multiply(Complex rhs) {
+        if (isNaN() || rhs.isNaN()) {
+            return NaN;
+        }
+        if (Double.isInfinite(real) || Double.isInfinite(imaginary) ||
+            Double.isInfinite(rhs.real)|| Double.isInfinite(rhs.imaginary)) {
+            // we don't use Complex.isInfinite() to avoid testing for NaN again
+            return INF;
+        }
+        return createComplex(real * rhs.real - imaginary * rhs.imaginary,
+                real * rhs.imaginary + imaginary * rhs.real);
+    }
+
+    /**
+     * Return the product of this complex number and the given scalar number.
+     * <p>
+     * Implements preliminary checks for NaN and infinity followed by
+     * the definitional formula:
+     * <pre><code>
+     * c(a + bi) = (ca) + (cb)i
+     * </code></pre>
+     * </p>
+     * <p>
+     * Returns {@link #NaN} if either this or <code>rhs</code> has one or more
+     * NaN parts.
+     * </p>
+     * Returns {@link #INF} if neither this nor <code>rhs</code> has one or more
+     * NaN parts and if either this or <code>rhs</code> has one or more
+     * infinite parts (same result is returned regardless of the sign of the
+     * components).
+     * </p>
+     * <p>
+     * Returns finite values in components of the result per the
+     * definitional formula in all remaining cases.
+     *  </p>
+     *
+     * @param rhs the scalar number
+     * @return the complex number product
+     */
+    public Complex multiply(double rhs) {
+        if (isNaN() || Double.isNaN(rhs)) {
+            return NaN;
+        }
+        if (Double.isInfinite(real) || Double.isInfinite(imaginary) ||
+            Double.isInfinite(rhs)) {
+            // we don't use Complex.isInfinite() to avoid testing for NaN again
+            return INF;
+        }
+        return createComplex(real * rhs, imaginary * rhs);
+    }
+
+    /**
+     * Return the additive inverse of this complex number.
+     * <p>
+     * Returns <code>Complex.NaN</code> if either real or imaginary
+     * part of this Complex number equals <code>Double.NaN</code>.</p>
+     *
+     * @return the negation of this complex number
+     */
+    public Complex negate() {
+        if (isNaN()) {
+            return NaN;
+        }
+
+        return createComplex(-real, -imaginary);
+    }
+
+    /**
+     * Return the difference between this complex number and the given complex
+     * number.
+      * <p>
+     * Uses the definitional formula
+     * <pre>
+     * (a + bi) - (c + di) = (a-c) + (b-d)i
+     * </pre></p>
+     * <p>
+     * If either this or <code>rhs</code> has a NaN value in either part,
+     * {@link #NaN} is returned; otherwise inifinite and NaN values are
+     * returned in the parts of the result according to the rules for
+     * {@link java.lang.Double} arithmetic. </p>
+     *
+     * @param rhs the other complex number
+     * @return the complex number difference
+     * @throws NullPointerException if <code>rhs</code> is null
+     */
+    public Complex subtract(Complex rhs) {
+        if (isNaN() || rhs.isNaN()) {
+            return NaN;
+        }
+
+        return createComplex(real - rhs.getReal(),
+            imaginary - rhs.getImaginary());
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top">
+     * inverse cosine</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))</code></pre></p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code> or infinite.</p>
+     *
+     * @return the inverse cosine of this complex number
+     * @since 1.2
+     */
+    public Complex acos() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return this.add(this.sqrt1z().multiply(Complex.I)).log()
+              .multiply(Complex.I.negate());
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top">
+     * inverse sine</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz)) </code></pre></p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code> or infinite.</p>
+     *
+     * @return the inverse sine of this complex number.
+     * @since 1.2
+     */
+    public Complex asin() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return sqrt1z().add(this.multiply(Complex.I)).log()
+              .multiply(Complex.I.negate());
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top">
+     * inverse tangent</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> atan(z) = (i/2) log((i + z)/(i - z)) </code></pre></p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code> or infinite.</p>
+     *
+     * @return the inverse tangent of this complex number
+     * @since 1.2
+     */
+    public Complex atan() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return this.add(Complex.I).divide(Complex.I.subtract(this)).log()
+            .multiply(Complex.I.divide(createComplex(2.0, 0.0)));
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top">
+     * cosine</a>
+     * of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
+     * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * cos(1 &plusmn; INFINITY i) = 1 &#x2213; INFINITY i
+     * cos(&plusmn;INFINITY + i) = NaN + NaN i
+     * cos(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre></p>
+     *
+     * @return the cosine of this complex number
+     * @since 1.2
+     */
+    public Complex cos() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return createComplex(FastMath.cos(real) * MathUtils.cosh(imaginary),
+            -FastMath.sin(real) * MathUtils.sinh(imaginary));
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top">
+     * hyperbolic cosine</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
+     * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * cosh(1 &plusmn; INFINITY i) = NaN + NaN i
+     * cosh(&plusmn;INFINITY + i) = INFINITY &plusmn; INFINITY i
+     * cosh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre></p>
+     *
+     * @return the hyperbolic cosine of this complex number.
+     * @since 1.2
+     */
+    public Complex cosh() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return createComplex(MathUtils.cosh(real) * FastMath.cos(imaginary),
+            MathUtils.sinh(real) * FastMath.sin(imaginary));
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top">
+     * exponential function</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and
+     * {@link java.lang.Math#sin}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * exp(1 &plusmn; INFINITY i) = NaN + NaN i
+     * exp(INFINITY + i) = INFINITY + INFINITY i
+     * exp(-INFINITY + i) = 0 + 0i
+     * exp(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre></p>
+     *
+     * @return <i>e</i><sup><code>this</code></sup>
+     * @since 1.2
+     */
+    public Complex exp() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        double expReal = FastMath.exp(real);
+        return createComplex(expReal *  FastMath.cos(imaginary), expReal * FastMath.sin(imaginary));
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top">
+     * natural logarithm</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> log(a + bi) = ln(|a + bi|) + arg(a + bi)i</code></pre>
+     * where ln on the right hand side is {@link java.lang.Math#log},
+     * <code>|a + bi|</code> is the modulus, {@link Complex#abs},  and
+     * <code>arg(a + bi) = {@link java.lang.Math#atan2}(b, a)</code></p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite (or critical) values in real or imaginary parts of the input may
+     * result in infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * log(1 &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/2)i
+     * log(INFINITY + i) = INFINITY + 0i
+     * log(-INFINITY + i) = INFINITY + &pi;i
+     * log(INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (&pi;/4)i
+     * log(-INFINITY &plusmn; INFINITY i) = INFINITY &plusmn; (3&pi;/4)i
+     * log(0 + 0i) = -INFINITY + 0i
+     * </code></pre></p>
+     *
+     * @return ln of this complex number.
+     * @since 1.2
+     */
+    public Complex log() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return createComplex(FastMath.log(abs()),
+            FastMath.atan2(imaginary, real));
+    }
+
+    /**
+     * Returns of value of this complex number raised to the power of <code>x</code>.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> y<sup>x</sup> = exp(x&middot;log(y))</code></pre>
+     * where <code>exp</code> and <code>log</code> are {@link #exp} and
+     * {@link #log}, respectively.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code> or infinite, or if <code>y</code>
+     * equals {@link Complex#ZERO}.</p>
+     *
+     * @param x the exponent.
+     * @return <code>this</code><sup><code>x</code></sup>
+     * @throws NullPointerException if x is null
+     * @since 1.2
+     */
+    public Complex pow(Complex x) {
+        if (x == null) {
+            throw new NullPointerException();
+        }
+        return this.log().multiply(x).exp();
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top">
+     * sine</a>
+     * of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
+     * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * sin(1 &plusmn; INFINITY i) = 1 &plusmn; INFINITY i
+     * sin(&plusmn;INFINITY + i) = NaN + NaN i
+     * sin(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre></p>
+     *
+     * @return the sine of this complex number.
+     * @since 1.2
+     */
+    public Complex sin() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return createComplex(FastMath.sin(real) * MathUtils.cosh(imaginary),
+            FastMath.cos(real) * MathUtils.sinh(imaginary));
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top">
+     * hyperbolic sine</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code> sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
+     * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * sinh(1 &plusmn; INFINITY i) = NaN + NaN i
+     * sinh(&plusmn;INFINITY + i) = &plusmn; INFINITY + INFINITY i
+     * sinh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i</code></pre></p>
+     *
+     * @return the hyperbolic sine of this complex number
+     * @since 1.2
+     */
+    public Complex sinh() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        return createComplex(MathUtils.sinh(real) * FastMath.cos(imaginary),
+            MathUtils.cosh(real) * FastMath.sin(imaginary));
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
+     * square root</a> of this complex number.
+     * <p>
+     * Implements the following algorithm to compute <code>sqrt(a + bi)</code>:
+     * <ol><li>Let <code>t = sqrt((|a| + |a + bi|) / 2)</code></li>
+     * <li><pre>if <code> a &#8805; 0</code> return <code>t + (b/2t)i</code>
+     *  else return <code>|b|/2t + sign(b)t i </code></pre></li>
+     * </ol>
+     * where <ul>
+     * <li><code>|a| = {@link Math#abs}(a)</code></li>
+     * <li><code>|a + bi| = {@link Complex#abs}(a + bi) </code></li>
+     * <li><code>sign(b) =  {@link MathUtils#indicator}(b) </code>
+     * </ul></p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * sqrt(1 &plusmn; INFINITY i) = INFINITY + NaN i
+     * sqrt(INFINITY + i) = INFINITY + 0i
+     * sqrt(-INFINITY + i) = 0 + INFINITY i
+     * sqrt(INFINITY &plusmn; INFINITY i) = INFINITY + NaN i
+     * sqrt(-INFINITY &plusmn; INFINITY i) = NaN &plusmn; INFINITY i
+     * </code></pre></p>
+     *
+     * @return the square root of this complex number
+     * @since 1.2
+     */
+    public Complex sqrt() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        if (real == 0.0 && imaginary == 0.0) {
+            return createComplex(0.0, 0.0);
+        }
+
+        double t = FastMath.sqrt((FastMath.abs(real) + abs()) / 2.0);
+        if (real >= 0.0) {
+            return createComplex(t, imaginary / (2.0 * t));
+        } else {
+            return createComplex(FastMath.abs(imaginary) / (2.0 * t),
+                MathUtils.indicator(imaginary) * t);
+        }
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top">
+     * square root</a> of 1 - <code>this</code><sup>2</sup> for this complex
+     * number.
+     * <p>
+     * Computes the result directly as
+     * <code>sqrt(Complex.ONE.subtract(z.multiply(z)))</code>.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.</p>
+     *
+     * @return the square root of 1 - <code>this</code><sup>2</sup>
+     * @since 1.2
+     */
+    public Complex sqrt1z() {
+        return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt();
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top">
+     * tangent</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code>tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
+     * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite (or critical) values in real or imaginary parts of the input may
+     * result in infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * tan(1 &plusmn; INFINITY i) = 0 + NaN i
+     * tan(&plusmn;INFINITY + i) = NaN + NaN i
+     * tan(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
+     * tan(&plusmn;&pi;/2 + 0 i) = &plusmn;INFINITY + NaN i</code></pre></p>
+     *
+     * @return the tangent of this complex number
+     * @since 1.2
+     */
+    public Complex tan() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        double real2 = 2.0 * real;
+        double imaginary2 = 2.0 * imaginary;
+        double d = FastMath.cos(real2) + MathUtils.cosh(imaginary2);
+
+        return createComplex(FastMath.sin(real2) / d, MathUtils.sinh(imaginary2) / d);
+    }
+
+    /**
+     * Compute the
+     * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top">
+     * hyperbolic tangent</a> of this complex number.
+     * <p>
+     * Implements the formula: <pre>
+     * <code>tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i</code></pre>
+     * where the (real) functions on the right-hand side are
+     * {@link java.lang.Math#sin}, {@link java.lang.Math#cos},
+     * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p>
+     * <p>
+     * Returns {@link Complex#NaN} if either real or imaginary part of the
+     * input argument is <code>NaN</code>.</p>
+     * <p>
+     * Infinite values in real or imaginary parts of the input may result in
+     * infinite or NaN values returned in parts of the result.<pre>
+     * Examples:
+     * <code>
+     * tanh(1 &plusmn; INFINITY i) = NaN + NaN i
+     * tanh(&plusmn;INFINITY + i) = NaN + 0 i
+     * tanh(&plusmn;INFINITY &plusmn; INFINITY i) = NaN + NaN i
+     * tanh(0 + (&pi;/2)i) = NaN + INFINITY i</code></pre></p>
+     *
+     * @return the hyperbolic tangent of this complex number
+     * @since 1.2
+     */
+    public Complex tanh() {
+        if (isNaN()) {
+            return Complex.NaN;
+        }
+
+        double real2 = 2.0 * real;
+        double imaginary2 = 2.0 * imaginary;
+        double d = MathUtils.cosh(real2) + FastMath.cos(imaginary2);
+
+        return createComplex(MathUtils.sinh(real2) / d, FastMath.sin(imaginary2) / d);
+    }
+
+
+
+    /**
+     * <p>Compute the argument of this complex number.
+     * </p>
+     * <p>The argument is the angle phi between the positive real axis and the point
+     * representing this number in the complex plane. The value returned is between -PI (not inclusive)
+     * and PI (inclusive), with negative values returned for numbers with negative imaginary parts.
+     * </p>
+     * <p>If either real or imaginary part (or both) is NaN, NaN is returned.  Infinite parts are handled
+     * as java.Math.atan2 handles them, essentially treating finite parts as zero in the presence of
+     * an infinite coordinate and returning a multiple of pi/4 depending on the signs of the infinite
+     * parts.  See the javadoc for java.Math.atan2 for full details.</p>
+     *
+     * @return the argument of this complex number
+     */
+    public double getArgument() {
+        return FastMath.atan2(getImaginary(), getReal());
+    }
+
+    /**
+     * <p>Computes the n-th roots of this complex number.
+     * </p>
+     * <p>The nth roots are defined by the formula: <pre>
+     * <code> z<sub>k</sub> = abs<sup> 1/n</sup> (cos(phi + 2&pi;k/n) + i (sin(phi + 2&pi;k/n))</code></pre>
+     * for <i><code>k=0, 1, ..., n-1</code></i>, where <code>abs</code> and <code>phi</code> are
+     * respectively the {@link #abs() modulus} and {@link #getArgument() argument} of this complex number.
+     * </p>
+     * <p>If one or both parts of this complex number is NaN, a list with just one element,
+     *  {@link #NaN} is returned.</p>
+     * <p>if neither part is NaN, but at least one part is infinite, the result is a one-element
+     * list containing {@link #INF}.</p>
+     *
+     * @param n degree of root
+     * @return List<Complex> all nth roots of this complex number
+     * @throws IllegalArgumentException if parameter n is less than or equal to 0
+     * @since 2.0
+     */
+    public List<Complex> nthRoot(int n) throws IllegalArgumentException {
+
+        if (n <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N,
+                    n);
+        }
+
+        List<Complex> result = new ArrayList<Complex>();
+
+        if (isNaN()) {
+            result.add(Complex.NaN);
+            return result;
+        }
+
+        if (isInfinite()) {
+            result.add(Complex.INF);
+            return result;
+        }
+
+        // nth root of abs -- faster / more accurate to use a solver here?
+        final double nthRootOfAbs = FastMath.pow(abs(), 1.0 / n);
+
+        // Compute nth roots of complex number with k = 0, 1, ... n-1
+        final double nthPhi = getArgument()/n;
+        final double slice = 2 * FastMath.PI / n;
+        double innerPart = nthPhi;
+        for (int k = 0; k < n ; k++) {
+            // inner part
+            final double realPart      = nthRootOfAbs *  FastMath.cos(innerPart);
+            final double imaginaryPart = nthRootOfAbs *  FastMath.sin(innerPart);
+            result.add(createComplex(realPart, imaginaryPart));
+            innerPart += slice;
+        }
+
+        return result;
+    }
+
+    /**
+     * Create a complex number given the real and imaginary parts.
+     *
+     * @param realPart the real part
+     * @param imaginaryPart the imaginary part
+     * @return a new complex number instance
+     * @since 1.2
+     */
+    protected Complex createComplex(double realPart, double imaginaryPart) {
+        return new Complex(realPart, imaginaryPart);
+    }
+
+    /**
+     * <p>Resolve the transient fields in a deserialized Complex Object.</p>
+     * <p>Subclasses will need to override {@link #createComplex} to deserialize properly</p>
+     * @return A Complex instance with all fields resolved.
+     * @since 2.0
+     */
+    protected final Object readResolve() {
+        return createComplex(real, imaginary);
+    }
+
+    /** {@inheritDoc} */
+    public ComplexField getField() {
+        return ComplexField.getInstance();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/complex/ComplexField.java b/src/main/java/org/apache/commons/math/complex/ComplexField.java
new file mode 100644
index 0000000..5bce1d5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/complex/ComplexField.java
@@ -0,0 +1,78 @@
+/*
+ * 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.complex;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.Field;
+
+/**
+ * Representation of the complex numbers field.
+ * <p>
+ * This class is a singleton.
+ * </p>
+ * @see Complex
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public class ComplexField implements Field<Complex>, Serializable  {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -6130362688700788798L;
+
+    /** Private constructor for the singleton.
+     */
+    private ComplexField() {
+    }
+
+    /** Get the unique instance.
+     * @return the unique instance
+     */
+    public static ComplexField getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    /** {@inheritDoc} */
+    public Complex getOne() {
+        return Complex.ONE;
+    }
+
+    /** {@inheritDoc} */
+    public Complex getZero() {
+        return Complex.ZERO;
+    }
+
+    // CHECKSTYLE: stop HideUtilityClassConstructor
+    /** Holder for the instance.
+     * <p>We use here the Initialization On Demand Holder Idiom.</p>
+     */
+    private static class LazyHolder {
+        /** Cached field instance. */
+        private static final ComplexField INSTANCE = new ComplexField();
+    }
+    // CHECKSTYLE: resume HideUtilityClassConstructor
+
+    /** Handle deserialization of the singleton.
+     * @return the singleton instance
+     */
+    private Object readResolve() {
+        // return the singleton instance
+        return LazyHolder.INSTANCE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/complex/ComplexFormat.java b/src/main/java/org/apache/commons/math/complex/ComplexFormat.java
new file mode 100644
index 0000000..288d6de
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/complex/ComplexFormat.java
@@ -0,0 +1,383 @@
+/*
+ * 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.complex;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.CompositeFormat;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * Formats a Complex number in cartesian format "Re(c) + Im(c)i".  'i' can
+ * be replaced with 'j' (or anything else), and the number format for both real
+ * and imaginary parts can be configured.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class ComplexFormat extends CompositeFormat {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3343698360149467646L;
+
+     /** The default imaginary character. */
+    private static final String DEFAULT_IMAGINARY_CHARACTER = "i";
+
+    /** The notation used to signify the imaginary part of the complex number. */
+    private String imaginaryCharacter;
+
+    /** The format used for the imaginary part. */
+    private NumberFormat imaginaryFormat;
+
+    /** The format used for the real part. */
+    private NumberFormat realFormat;
+
+    /**
+     * Create an instance with the default imaginary character, 'i', and the
+     * default number format for both real and imaginary parts.
+     */
+    public ComplexFormat() {
+        this(DEFAULT_IMAGINARY_CHARACTER, getDefaultNumberFormat());
+    }
+
+    /**
+     * Create an instance with a custom number format for both real and
+     * imaginary parts.
+     * @param format the custom format for both real and imaginary parts.
+     */
+    public ComplexFormat(NumberFormat format) {
+        this(DEFAULT_IMAGINARY_CHARACTER, format);
+    }
+
+    /**
+     * Create an instance with a custom number format for the real part and a
+     * custom number format for the imaginary part.
+     * @param realFormat the custom format for the real part.
+     * @param imaginaryFormat the custom format for the imaginary part.
+     */
+    public ComplexFormat(NumberFormat realFormat, NumberFormat imaginaryFormat) {
+        this(DEFAULT_IMAGINARY_CHARACTER, realFormat, imaginaryFormat);
+    }
+
+    /**
+     * Create an instance with a custom imaginary character, and the default
+     * number format for both real and imaginary parts.
+     * @param imaginaryCharacter The custom imaginary character.
+     */
+    public ComplexFormat(String imaginaryCharacter) {
+        this(imaginaryCharacter, getDefaultNumberFormat());
+    }
+
+    /**
+     * Create an instance with a custom imaginary character, and a custom number
+     * format for both real and imaginary parts.
+     * @param imaginaryCharacter The custom imaginary character.
+     * @param format the custom format for both real and imaginary parts.
+     */
+    public ComplexFormat(String imaginaryCharacter, NumberFormat format) {
+        this(imaginaryCharacter, format, (NumberFormat)format.clone());
+    }
+
+    /**
+     * Create an instance with a custom imaginary character, a custom number
+     * format for the real part, and a custom number format for the imaginary
+     * part.
+     * @param imaginaryCharacter The custom imaginary character.
+     * @param realFormat the custom format for the real part.
+     * @param imaginaryFormat the custom format for the imaginary part.
+     */
+    public ComplexFormat(String imaginaryCharacter, NumberFormat realFormat,
+            NumberFormat imaginaryFormat) {
+        super();
+        setImaginaryCharacter(imaginaryCharacter);
+        setImaginaryFormat(imaginaryFormat);
+        setRealFormat(realFormat);
+    }
+
+    /**
+     * Get the set of locales for which complex formats are available.
+     * <p>This is the same set as the {@link NumberFormat} set.</p>
+     * @return available complex format locales.
+     */
+    public static Locale[] getAvailableLocales() {
+        return NumberFormat.getAvailableLocales();
+    }
+
+    /**
+     * This static method calls {@link #format(Object)} on a default instance of
+     * ComplexFormat.
+     *
+     * @param c Complex object to format
+     * @return A formatted number in the form "Re(c) + Im(c)i"
+     */
+    public static String formatComplex(Complex c) {
+        return getInstance().format(c);
+    }
+
+    /**
+     * Formats a {@link Complex} object to produce a string.
+     *
+     * @param complex 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(Complex complex, StringBuffer toAppendTo,
+            FieldPosition pos) {
+
+        pos.setBeginIndex(0);
+        pos.setEndIndex(0);
+
+        // format real
+        double re = complex.getReal();
+        formatDouble(re, getRealFormat(), toAppendTo, pos);
+
+        // format sign and imaginary
+        double im = complex.getImaginary();
+        if (im < 0.0) {
+            toAppendTo.append(" - ");
+            formatDouble(-im, getImaginaryFormat(), toAppendTo, pos);
+            toAppendTo.append(getImaginaryCharacter());
+        } else if (im > 0.0 || Double.isNaN(im)) {
+            toAppendTo.append(" + ");
+            formatDouble(im, getImaginaryFormat(), toAppendTo, pos);
+            toAppendTo.append(getImaginaryCharacter());
+        }
+
+        return toAppendTo;
+    }
+
+    /**
+     * Formats a object to produce a string.  <code>obj</code> must be either a
+     * {@link Complex} object or a {@link Number} 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 <code>obj</code> is not a valid type.
+     */
+    @Override
+    public StringBuffer format(Object obj, StringBuffer toAppendTo,
+            FieldPosition pos) {
+
+        StringBuffer ret = null;
+
+        if (obj instanceof Complex) {
+            ret = format( (Complex)obj, toAppendTo, pos);
+        } else if (obj instanceof Number) {
+            ret = format( new Complex(((Number)obj).doubleValue(), 0.0),
+                toAppendTo, pos);
+        } else {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.CANNOT_FORMAT_INSTANCE_AS_COMPLEX,
+                  obj.getClass().getName());
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the imaginaryCharacter.
+     * @return the imaginaryCharacter.
+     */
+    public String getImaginaryCharacter() {
+        return imaginaryCharacter;
+    }
+
+    /**
+     * Access the imaginaryFormat.
+     * @return the imaginaryFormat.
+     */
+    public NumberFormat getImaginaryFormat() {
+        return imaginaryFormat;
+    }
+
+    /**
+     * Returns the default complex format for the current locale.
+     * @return the default complex format.
+     */
+    public static ComplexFormat getInstance() {
+        return getInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns the default complex format for the given locale.
+     * @param locale the specific locale used by the format.
+     * @return the complex format specific to the given locale.
+     */
+    public static ComplexFormat getInstance(Locale locale) {
+        NumberFormat f = getDefaultNumberFormat(locale);
+        return new ComplexFormat(f);
+    }
+
+    /**
+     * Access the realFormat.
+     * @return the realFormat.
+     */
+    public NumberFormat getRealFormat() {
+        return realFormat;
+    }
+
+    /**
+     * Parses a string to produce a {@link Complex} object.
+     *
+     * @param source the string to parse
+     * @return the parsed {@link Complex} object.
+     * @exception ParseException if the beginning of the specified string
+     *            cannot be parsed.
+     */
+    public Complex parse(String source) throws ParseException {
+        ParsePosition parsePosition = new ParsePosition(0);
+        Complex result = parse(source, parsePosition);
+        if (parsePosition.getIndex() == 0) {
+            throw MathRuntimeException.createParseException(
+                    parsePosition.getErrorIndex(),
+                    LocalizedFormats.UNPARSEABLE_COMPLEX_NUMBER, source);
+        }
+        return result;
+    }
+
+    /**
+     * Parses a string to produce a {@link Complex} object.
+     *
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed {@link Complex} object.
+     */
+    public Complex parse(String source, ParsePosition pos) {
+        int initialIndex = pos.getIndex();
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse real
+        Number re = parseNumber(source, getRealFormat(), pos);
+        if (re == null) {
+            // invalid real number
+            // set index back to initial, error index should already be set
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse sign
+        int startIndex = pos.getIndex();
+        char c = parseNextCharacter(source, pos);
+        int sign = 0;
+        switch (c) {
+        case 0 :
+            // no sign
+            // return real only complex number
+            return new Complex(re.doubleValue(), 0.0);
+        case '-' :
+            sign = -1;
+            break;
+        case '+' :
+            sign = 1;
+            break;
+        default :
+            // invalid sign
+            // set index back to initial, error index should be the last
+            // character examined.
+            pos.setIndex(initialIndex);
+            pos.setErrorIndex(startIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse imaginary
+        Number im = parseNumber(source, getRealFormat(), pos);
+        if (im == null) {
+            // invalid imaginary number
+            // set index back to initial, error index should already be set
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse imaginary character
+        if (!parseFixedstring(source, getImaginaryCharacter(), pos)) {
+            return null;
+        }
+
+        return new Complex(re.doubleValue(), im.doubleValue() * sign);
+
+    }
+
+    /**
+     * 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)
+     */
+    @Override
+    public Object parseObject(String source, ParsePosition pos) {
+        return parse(source, pos);
+    }
+
+    /**
+     * Modify the imaginaryCharacter.
+     * @param imaginaryCharacter The new imaginaryCharacter value.
+     * @throws IllegalArgumentException if <code>imaginaryCharacter</code> is
+     *         <code>null</code> or an empty string.
+     */
+    public void setImaginaryCharacter(String imaginaryCharacter) {
+        if (imaginaryCharacter == null || imaginaryCharacter.length() == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.EMPTY_STRING_FOR_IMAGINARY_CHARACTER);
+        }
+        this.imaginaryCharacter = imaginaryCharacter;
+    }
+
+    /**
+     * Modify the imaginaryFormat.
+     * @param imaginaryFormat The new imaginaryFormat value.
+     * @throws NullArgumentException if {@code imaginaryFormat} is {@code null}.
+     */
+    public void setImaginaryFormat(NumberFormat imaginaryFormat) {
+        if (imaginaryFormat == null) {
+            throw new NullArgumentException(LocalizedFormats.IMAGINARY_FORMAT);
+        }
+        this.imaginaryFormat = imaginaryFormat;
+    }
+
+    /**
+     * Modify the realFormat.
+     * @param realFormat The new realFormat value.
+     * @throws NullArgumentException if {@code realFormat} is {@code null}.
+     */
+    public void setRealFormat(NumberFormat realFormat) {
+        if (realFormat == null) {
+            throw new NullArgumentException(LocalizedFormats.REAL_FORMAT);
+        }
+        this.realFormat = realFormat;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/complex/ComplexUtils.java b/src/main/java/org/apache/commons/math/complex/ComplexUtils.java
new file mode 100644
index 0000000..f7fb392
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/complex/ComplexUtils.java
@@ -0,0 +1,72 @@
+/*
+ * 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.complex;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Static implementations of common
+ * {@link org.apache.commons.math.complex.Complex} utilities functions.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public class ComplexUtils {
+
+    /**
+     * Default constructor.
+     */
+    private ComplexUtils() {
+        super();
+    }
+
+    /**
+     * Creates a complex number from the given polar representation.
+     * <p>
+     * The value returned is <code>r&middot;e<sup>i&middot;theta</sup></code>,
+     * computed as <code>r&middot;cos(theta) + r&middot;sin(theta)i</code></p>
+     * <p>
+     * If either <code>r</code> or <code>theta</code> is NaN, or
+     * <code>theta</code> is infinite, {@link Complex#NaN} is returned.</p>
+     * <p>
+     * If <code>r</code> is infinite and <code>theta</code> is finite,
+     * infinite or NaN values may be returned in parts of the result, following
+     * the rules for double arithmetic.<pre>
+     * Examples:
+     * <code>
+     * polar2Complex(INFINITY, &pi;/4) = INFINITY + INFINITY i
+     * polar2Complex(INFINITY, 0) = INFINITY + NaN i
+     * polar2Complex(INFINITY, -&pi;/4) = INFINITY - INFINITY i
+     * polar2Complex(INFINITY, 5&pi;/4) = -INFINITY - INFINITY i </code></pre></p>
+     *
+     * @param r the modulus of the complex number to create
+     * @param theta  the argument of the complex number to create
+     * @return <code>r&middot;e<sup>i&middot;theta</sup></code>
+     * @throws IllegalArgumentException  if r is negative
+     * @since 1.1
+     */
+    public static Complex polar2Complex(double r, double theta) {
+        if (r < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NEGATIVE_COMPLEX_MODULE, r);
+        }
+        return new Complex(r * FastMath.cos(theta), r * FastMath.sin(theta));
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/complex/package.html b/src/main/java/org/apache/commons/math/complex/package.html
new file mode 100644
index 0000000..755dba0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/complex/package.html
@@ -0,0 +1,23 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+     Complex number type and implementations of complex transcendental
+     functions.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/dfp/Dfp.java b/src/main/java/org/apache/commons/math/dfp/Dfp.java
new file mode 100644
index 0000000..7ce338c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/dfp/Dfp.java
@@ -0,0 +1,2399 @@
+/*
+ * 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.dfp;
+
+import java.util.Arrays;
+
+import org.apache.commons.math.FieldElement;
+
+/**
+ *  Decimal floating point library for Java
+ *
+ *  <p>Another floating point class.  This one is built using radix 10000
+ *  which is 10<sup>4</sup>, so its almost decimal.</p>
+ *
+ *  <p>The design goals here are:
+ *  <ol>
+ *    <li>Decimal math, or close to it</li>
+ *    <li>Settable precision (but no mix between numbers using different settings)</li>
+ *    <li>Portability.  Code should be keep as portable as possible.</li>
+ *    <li>Performance</li>
+ *    <li>Accuracy  - Results should always be +/- 1 ULP for basic
+ *         algebraic operation</li>
+ *    <li>Comply with IEEE 854-1987 as much as possible.
+ *         (See IEEE 854-1987 notes below)</li>
+ *  </ol></p>
+ *
+ *  <p>Trade offs:
+ *  <ol>
+ *    <li>Memory foot print.  I'm using more memory than necessary to
+ *         represent numbers to get better performance.</li>
+ *    <li>Digits are bigger, so rounding is a greater loss.  So, if you
+ *         really need 12 decimal digits, better use 4 base 10000 digits
+ *         there can be one partially filled.</li>
+ *  </ol></p>
+ *
+ *  <p>Numbers are represented  in the following form:
+ *  <pre>
+ *  n  =  sign &times; mant &times; (radix)<sup>exp</sup>;</p>
+ *  </pre>
+ *  where sign is &plusmn;1, mantissa represents a fractional number between
+ *  zero and one.  mant[0] is the least significant digit.
+ *  exp is in the range of -32767 to 32768</p>
+ *
+ *  <p>IEEE 854-1987  Notes and differences</p>
+ *
+ *  <p>IEEE 854 requires the radix to be either 2 or 10.  The radix here is
+ *  10000, so that requirement is not met, but  it is possible that a
+ *  subclassed can be made to make it behave as a radix 10
+ *  number.  It is my opinion that if it looks and behaves as a radix
+ *  10 number then it is one and that requirement would be met.</p>
+ *
+ *  <p>The radix of 10000 was chosen because it should be faster to operate
+ *  on 4 decimal digits at once instead of one at a time.  Radix 10 behavior
+ *  can be realized by add an additional rounding step to ensure that
+ *  the number of decimal digits represented is constant.</p>
+ *
+ *  <p>The IEEE standard specifically leaves out internal data encoding,
+ *  so it is reasonable to conclude that such a subclass of this radix
+ *  10000 system is merely an encoding of a radix 10 system.</p>
+ *
+ *  <p>IEEE 854 also specifies the existence of "sub-normal" numbers.  This
+ *  class does not contain any such entities.  The most significant radix
+ *  10000 digit is always non-zero.  Instead, we support "gradual underflow"
+ *  by raising the underflow flag for numbers less with exponent less than
+ *  expMin, but don't flush to zero until the exponent reaches MIN_EXP-digits.
+ *  Thus the smallest number we can represent would be:
+ *  1E(-(MIN_EXP-digits-1)*4),  eg, for digits=5, MIN_EXP=-32767, that would
+ *  be 1e-131092.</p>
+ *
+ *  <p>IEEE 854 defines that the implied radix point lies just to the right
+ *  of the most significant digit and to the left of the remaining digits.
+ *  This implementation puts the implied radix point to the left of all
+ *  digits including the most significant one.  The most significant digit
+ *  here is the one just to the right of the radix point.  This is a fine
+ *  detail and is really only a matter of definition.  Any side effects of
+ *  this can be rendered invisible by a subclass.</p>
+ * @see DfpField
+ * @version $Revision: 1003889 $ $Date: 2010-10-02 23:11:55 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+ */
+public class Dfp implements FieldElement<Dfp> {
+
+    /** The radix, or base of this system.  Set to 10000 */
+    public static final int RADIX = 10000;
+
+    /** The minimum exponent before underflow is signaled.  Flush to zero
+     *  occurs at minExp-DIGITS */
+    public static final int MIN_EXP = -32767;
+
+    /** The maximum exponent before overflow is signaled and results flushed
+     *  to infinity */
+    public static final int MAX_EXP =  32768;
+
+    /** The amount under/overflows are scaled by before going to trap handler */
+    public static final int ERR_SCALE = 32760;
+
+    /** Indicator value for normal finite numbers. */
+    public static final byte FINITE = 0;
+
+    /** Indicator value for Infinity. */
+    public static final byte INFINITE = 1;
+
+    /** Indicator value for signaling NaN. */
+    public static final byte SNAN = 2;
+
+    /** Indicator value for quiet NaN. */
+    public static final byte QNAN = 3;
+
+    /** String for NaN representation. */
+    private static final String NAN_STRING = "NaN";
+
+    /** String for positive infinity representation. */
+    private static final String POS_INFINITY_STRING = "Infinity";
+
+    /** String for negative infinity representation. */
+    private static final String NEG_INFINITY_STRING = "-Infinity";
+
+    /** Name for traps triggered by addition. */
+    private static final String ADD_TRAP = "add";
+
+    /** Name for traps triggered by multiplication. */
+    private static final String MULTIPLY_TRAP = "multiply";
+
+    /** Name for traps triggered by division. */
+    private static final String DIVIDE_TRAP = "divide";
+
+    /** Name for traps triggered by square root. */
+    private static final String SQRT_TRAP = "sqrt";
+
+    /** Name for traps triggered by alignment. */
+    private static final String ALIGN_TRAP = "align";
+
+    /** Name for traps triggered by truncation. */
+    private static final String TRUNC_TRAP = "trunc";
+
+    /** Name for traps triggered by nextAfter. */
+    private static final String NEXT_AFTER_TRAP = "nextAfter";
+
+    /** Name for traps triggered by lessThan. */
+    private static final String LESS_THAN_TRAP = "lessThan";
+
+    /** Name for traps triggered by greaterThan. */
+    private static final String GREATER_THAN_TRAP = "greaterThan";
+
+    /** Name for traps triggered by newInstance. */
+    private static final String NEW_INSTANCE_TRAP = "newInstance";
+
+    /** Mantissa. */
+    protected int[] mant;
+
+    /** Sign bit: & for positive, -1 for negative. */
+    protected byte sign;
+
+    /** Exponent. */
+    protected int exp;
+
+    /** Indicator for non-finite / non-number values. */
+    protected byte nans;
+
+    /** Factory building similar Dfp's. */
+    private final DfpField field;
+
+    /** Makes an instance with a value of zero.
+     * @param field field to which this instance belongs
+     */
+    protected Dfp(final DfpField field) {
+        mant = new int[field.getRadixDigits()];
+        sign = 1;
+        exp = 0;
+        nans = FINITE;
+        this.field = field;
+    }
+
+    /** Create an instance from a byte value.
+     * @param field field to which this instance belongs
+     * @param x value to convert to an instance
+     */
+    protected Dfp(final DfpField field, byte x) {
+        this(field, (long) x);
+    }
+
+    /** Create an instance from an int value.
+     * @param field field to which this instance belongs
+     * @param x value to convert to an instance
+     */
+    protected Dfp(final DfpField field, int x) {
+        this(field, (long) x);
+    }
+
+    /** Create an instance from a long value.
+     * @param field field to which this instance belongs
+     * @param x value to convert to an instance
+     */
+    protected Dfp(final DfpField field, long x) {
+
+        // initialize as if 0
+        mant = new int[field.getRadixDigits()];
+        nans = FINITE;
+        this.field = field;
+
+        boolean isLongMin = false;
+        if (x == Long.MIN_VALUE) {
+            // special case for Long.MIN_VALUE (-9223372036854775808)
+            // we must shift it before taking its absolute value
+            isLongMin = true;
+            ++x;
+        }
+
+        // set the sign
+        if (x < 0) {
+            sign = -1;
+            x = -x;
+        } else {
+            sign = 1;
+        }
+
+        exp = 0;
+        while (x != 0) {
+            System.arraycopy(mant, mant.length - exp, mant, mant.length - 1 - exp, exp);
+            mant[mant.length - 1] = (int) (x % RADIX);
+            x /= RADIX;
+            exp++;
+        }
+
+        if (isLongMin) {
+            // remove the shift added for Long.MIN_VALUE
+            // we know in this case that fixing the last digit is sufficient
+            for (int i = 0; i < mant.length - 1; i++) {
+                if (mant[i] != 0) {
+                    mant[i]++;
+                    break;
+                }
+            }
+        }
+    }
+
+    /** Create an instance from a double value.
+     * @param field field to which this instance belongs
+     * @param x value to convert to an instance
+     */
+    protected Dfp(final DfpField field, double x) {
+
+        // initialize as if 0
+        mant = new int[field.getRadixDigits()];
+        sign = 1;
+        exp = 0;
+        nans = FINITE;
+        this.field = field;
+
+        long bits = Double.doubleToLongBits(x);
+        long mantissa = bits & 0x000fffffffffffffL;
+        int exponent = (int) ((bits & 0x7ff0000000000000L) >> 52) - 1023;
+
+        if (exponent == -1023) {
+            // Zero or sub-normal
+            if (x == 0) {
+                return;
+            }
+
+            exponent++;
+
+            // Normalize the subnormal number
+            while ( (mantissa & 0x0010000000000000L) == 0) {
+                exponent--;
+                mantissa <<= 1;
+            }
+            mantissa &= 0x000fffffffffffffL;
+        }
+
+        if (exponent == 1024) {
+            // infinity or NAN
+            if (x != x) {
+                sign = (byte) 1;
+                nans = QNAN;
+            } else if (x < 0) {
+                sign = (byte) -1;
+                nans = INFINITE;
+            } else {
+                sign = (byte) 1;
+                nans = INFINITE;
+            }
+            return;
+        }
+
+        Dfp xdfp = new Dfp(field, mantissa);
+        xdfp = xdfp.divide(new Dfp(field, 4503599627370496l)).add(field.getOne());  // Divide by 2^52, then add one
+        xdfp = xdfp.multiply(DfpMath.pow(field.getTwo(), exponent));
+
+        if ((bits & 0x8000000000000000L) != 0) {
+            xdfp = xdfp.negate();
+        }
+
+        System.arraycopy(xdfp.mant, 0, mant, 0, mant.length);
+        sign = xdfp.sign;
+        exp  = xdfp.exp;
+        nans = xdfp.nans;
+
+    }
+
+    /** Copy constructor.
+     * @param d instance to copy
+     */
+    public Dfp(final Dfp d) {
+        mant  = d.mant.clone();
+        sign  = d.sign;
+        exp   = d.exp;
+        nans  = d.nans;
+        field = d.field;
+    }
+
+    /** Create an instance from a String representation.
+     * @param field field to which this instance belongs
+     * @param s string representation of the instance
+     */
+    protected Dfp(final DfpField field, final String s) {
+
+        // initialize as if 0
+        mant = new int[field.getRadixDigits()];
+        sign = 1;
+        exp = 0;
+        nans = FINITE;
+        this.field = field;
+
+        boolean decimalFound = false;
+        final int rsize = 4;   // size of radix in decimal digits
+        final int offset = 4;  // Starting offset into Striped
+        final char[] striped = new char[getRadixDigits() * rsize + offset * 2];
+
+        // Check some special cases
+        if (s.equals(POS_INFINITY_STRING)) {
+            sign = (byte) 1;
+            nans = INFINITE;
+            return;
+        }
+
+        if (s.equals(NEG_INFINITY_STRING)) {
+            sign = (byte) -1;
+            nans = INFINITE;
+            return;
+        }
+
+        if (s.equals(NAN_STRING)) {
+            sign = (byte) 1;
+            nans = QNAN;
+            return;
+        }
+
+        // Check for scientific notation
+        int p = s.indexOf("e");
+        if (p == -1) { // try upper case?
+            p = s.indexOf("E");
+        }
+
+        final String fpdecimal;
+        int sciexp = 0;
+        if (p != -1) {
+            // scientific notation
+            fpdecimal = s.substring(0, p);
+            String fpexp = s.substring(p+1);
+            boolean negative = false;
+
+            for (int i=0; i<fpexp.length(); i++)
+            {
+                if (fpexp.charAt(i) == '-')
+                {
+                    negative = true;
+                    continue;
+                }
+                if (fpexp.charAt(i) >= '0' && fpexp.charAt(i) <= '9')
+                    sciexp = sciexp * 10 + fpexp.charAt(i) - '0';
+            }
+
+            if (negative) {
+                sciexp = -sciexp;
+            }
+        } else {
+            // normal case
+            fpdecimal = s;
+        }
+
+        // If there is a minus sign in the number then it is negative
+        if (fpdecimal.indexOf("-") !=  -1) {
+            sign = -1;
+        }
+
+        // First off, find all of the leading zeros, trailing zeros, and significant digits
+        p = 0;
+
+        // Move p to first significant digit
+        int decimalPos = 0;
+        for (;;) {
+            if (fpdecimal.charAt(p) >= '1' && fpdecimal.charAt(p) <= '9') {
+                break;
+            }
+
+            if (decimalFound && fpdecimal.charAt(p) == '0') {
+                decimalPos--;
+            }
+
+            if (fpdecimal.charAt(p) == '.') {
+                decimalFound = true;
+            }
+
+            p++;
+
+            if (p == fpdecimal.length()) {
+                break;
+            }
+        }
+
+        // Copy the string onto Stripped
+        int q = offset;
+        striped[0] = '0';
+        striped[1] = '0';
+        striped[2] = '0';
+        striped[3] = '0';
+        int significantDigits=0;
+        for(;;) {
+            if (p == (fpdecimal.length())) {
+                break;
+            }
+
+            // Don't want to run pass the end of the array
+            if (q == mant.length*rsize+offset+1) {
+                break;
+            }
+
+            if (fpdecimal.charAt(p) == '.') {
+                decimalFound = true;
+                decimalPos = significantDigits;
+                p++;
+                continue;
+            }
+
+            if (fpdecimal.charAt(p) < '0' || fpdecimal.charAt(p) > '9') {
+                p++;
+                continue;
+            }
+
+            striped[q] = fpdecimal.charAt(p);
+            q++;
+            p++;
+            significantDigits++;
+        }
+
+
+        // If the decimal point has been found then get rid of trailing zeros.
+        if (decimalFound && q != offset) {
+            for (;;) {
+                q--;
+                if (q == offset) {
+                    break;
+                }
+                if (striped[q] == '0') {
+                    significantDigits--;
+                } else {
+                    break;
+                }
+            }
+        }
+
+        // special case of numbers like "0.00000"
+        if (decimalFound && significantDigits == 0) {
+            decimalPos = 0;
+        }
+
+        // Implicit decimal point at end of number if not present
+        if (!decimalFound) {
+            decimalPos = q-offset;
+        }
+
+        // Find the number of significant trailing zeros
+        q = offset;  // set q to point to first sig digit
+        p = significantDigits-1+offset;
+
+        int trailingZeros = 0;
+        while (p > q) {
+            if (striped[p] != '0') {
+                break;
+            }
+            trailingZeros++;
+            p--;
+        }
+
+        // Make sure the decimal is on a mod 10000 boundary
+        int i = ((rsize * 100) - decimalPos - sciexp % rsize) % rsize;
+        q -= i;
+        decimalPos += i;
+
+        // Make the mantissa length right by adding zeros at the end if necessary
+        while ((p - q) < (mant.length * rsize)) {
+            for (i = 0; i < rsize; i++) {
+                striped[++p] = '0';
+            }
+        }
+
+        // Ok, now we know how many trailing zeros there are,
+        // and where the least significant digit is
+        for (i = mant.length - 1; i >= 0; i--) {
+            mant[i] = (striped[q]   - '0') * 1000 +
+                      (striped[q+1] - '0') * 100  +
+                      (striped[q+2] - '0') * 10   +
+                      (striped[q+3] - '0');
+            q += 4;
+        }
+
+
+        exp = (decimalPos+sciexp) / rsize;
+
+        if (q < striped.length) {
+            // Is there possible another digit?
+            round((striped[q] - '0')*1000);
+        }
+
+    }
+
+    /** Creates an instance with a non-finite value.
+     * @param field field to which this instance belongs
+     * @param sign sign of the Dfp to create
+     * @param nans code of the value, must be one of {@link #INFINITE},
+     * {@link #SNAN},  {@link #QNAN}
+     */
+    protected Dfp(final DfpField field, final byte sign, final byte nans) {
+        this.field = field;
+        this.mant    = new int[field.getRadixDigits()];
+        this.sign    = sign;
+        this.exp     = 0;
+        this.nans    = nans;
+    }
+
+    /** Create an instance with a value of 0.
+     * Use this internally in preference to constructors to facilitate subclasses
+     * @return a new instance with a value of 0
+     */
+    public Dfp newInstance() {
+        return new Dfp(getField());
+    }
+
+    /** Create an instance from a byte value.
+     * @param x value to convert to an instance
+     * @return a new instance with value x
+     */
+    public Dfp newInstance(final byte x) {
+        return new Dfp(getField(), x);
+    }
+
+    /** Create an instance from an int value.
+     * @param x value to convert to an instance
+     * @return a new instance with value x
+     */
+    public Dfp newInstance(final int x) {
+        return new Dfp(getField(), x);
+    }
+
+    /** Create an instance from a long value.
+     * @param x value to convert to an instance
+     * @return a new instance with value x
+     */
+    public Dfp newInstance(final long x) {
+        return new Dfp(getField(), x);
+    }
+
+    /** Create an instance from a double value.
+     * @param x value to convert to an instance
+     * @return a new instance with value x
+     */
+    public Dfp newInstance(final double x) {
+        return new Dfp(getField(), x);
+    }
+
+    /** Create an instance by copying an existing one.
+     * Use this internally in preference to constructors to facilitate subclasses.
+     * @param d instance to copy
+     * @return a new instance with the same value as d
+     */
+    public Dfp newInstance(final Dfp d) {
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != d.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, NEW_INSTANCE_TRAP, d, result);
+        }
+
+        return new Dfp(d);
+
+    }
+
+    /** Create an instance from a String representation.
+     * Use this internally in preference to constructors to facilitate subclasses.
+     * @param s string representation of the instance
+     * @return a new instance parsed from specified string
+     */
+    public Dfp newInstance(final String s) {
+        return new Dfp(field, s);
+    }
+
+    /** Creates an instance with a non-finite value.
+     * @param sig sign of the Dfp to create
+     * @param code code of the value, must be one of {@link #INFINITE},
+     * {@link #SNAN},  {@link #QNAN}
+     * @return a new instance with a non-finite value
+     */
+    public Dfp newInstance(final byte sig, final byte code) {
+        return field.newDfp(sig, code);
+    }
+
+    /** Get the {@link org.apache.commons.math.Field Field} (really a {@link DfpField}) to which the instance belongs.
+     * <p>
+     * The field is linked to the number of digits and acts as a factory
+     * for {@link Dfp} instances.
+     * </p>
+     * @return {@link org.apache.commons.math.Field Field} (really a {@link DfpField}) to which the instance belongs
+     */
+    public DfpField getField() {
+        return field;
+    }
+
+    /** Get the number of radix digits of the instance.
+     * @return number of radix digits
+     */
+    public int getRadixDigits() {
+        return field.getRadixDigits();
+    }
+
+    /** Get the constant 0.
+     * @return a Dfp with value zero
+     */
+    public Dfp getZero() {
+        return field.getZero();
+    }
+
+    /** Get the constant 1.
+     * @return a Dfp with value one
+     */
+    public Dfp getOne() {
+        return field.getOne();
+    }
+
+    /** Get the constant 2.
+     * @return a Dfp with value two
+     */
+    public Dfp getTwo() {
+        return field.getTwo();
+    }
+
+    /** Shift the mantissa left, and adjust the exponent to compensate.
+     */
+    protected void shiftLeft() {
+        for (int i = mant.length - 1; i > 0; i--) {
+            mant[i] = mant[i-1];
+        }
+        mant[0] = 0;
+        exp--;
+    }
+
+    /* Note that shiftRight() does not call round() as that round() itself
+     uses shiftRight() */
+    /** Shift the mantissa right, and adjust the exponent to compensate.
+     */
+    protected void shiftRight() {
+        for (int i = 0; i < mant.length - 1; i++) {
+            mant[i] = mant[i+1];
+        }
+        mant[mant.length - 1] = 0;
+        exp++;
+    }
+
+    /** Make our exp equal to the supplied one, this may cause rounding.
+     *  Also causes de-normalized numbers.  These numbers are generally
+     *  dangerous because most routines assume normalized numbers.
+     *  Align doesn't round, so it will return the last digit destroyed
+     *  by shifting right.
+     *  @param e desired exponent
+     *  @return last digit destroyed by shifting right
+     */
+    protected int align(int e) {
+        int lostdigit = 0;
+        boolean inexact = false;
+
+        int diff = exp - e;
+
+        int adiff = diff;
+        if (adiff < 0) {
+            adiff = -adiff;
+        }
+
+        if (diff == 0) {
+            return 0;
+        }
+
+        if (adiff > (mant.length + 1)) {
+            // Special case
+            Arrays.fill(mant, 0);
+            exp = e;
+
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);
+
+            return 0;
+        }
+
+        for (int i = 0; i < adiff; i++) {
+            if (diff < 0) {
+                /* Keep track of loss -- only signal inexact after losing 2 digits.
+                 * the first lost digit is returned to add() and may be incorporated
+                 * into the result.
+                 */
+                if (lostdigit != 0) {
+                    inexact = true;
+                }
+
+                lostdigit = mant[0];
+
+                shiftRight();
+            } else {
+                shiftLeft();
+            }
+        }
+
+        if (inexact) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            dotrap(DfpField.FLAG_INEXACT, ALIGN_TRAP, this, this);
+        }
+
+        return lostdigit;
+
+    }
+
+    /** Check if instance is less than x.
+     * @param x number to check instance against
+     * @return true if instance is less than x and neither are NaN, false otherwise
+     */
+    public boolean lessThan(final Dfp x) {
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != x.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, result);
+            return false;
+        }
+
+        /* if a nan is involved, signal invalid and return false */
+        if (isNaN() || x.isNaN()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            dotrap(DfpField.FLAG_INVALID, LESS_THAN_TRAP, x, newInstance(getZero()));
+            return false;
+        }
+
+        return compare(this, x) < 0;
+    }
+
+    /** Check if instance is greater than x.
+     * @param x number to check instance against
+     * @return true if instance is greater than x and neither are NaN, false otherwise
+     */
+    public boolean greaterThan(final Dfp x) {
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != x.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, result);
+            return false;
+        }
+
+        /* if a nan is involved, signal invalid and return false */
+        if (isNaN() || x.isNaN()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            dotrap(DfpField.FLAG_INVALID, GREATER_THAN_TRAP, x, newInstance(getZero()));
+            return false;
+        }
+
+        return compare(this, x) > 0;
+    }
+
+    /** Check if instance is infinite.
+     * @return true if instance is infinite
+     */
+    public boolean isInfinite() {
+        return nans == INFINITE;
+    }
+
+    /** Check if instance is not a number.
+     * @return true if instance is not a number
+     */
+    public boolean isNaN() {
+        return (nans == QNAN) || (nans == SNAN);
+    }
+
+    /** Check if instance is equal to x.
+     * @param other object to check instance against
+     * @return true if instance is equal to x and neither are NaN, false otherwise
+     */
+    @Override
+    public boolean equals(final Object other) {
+
+        if (other instanceof Dfp) {
+            final Dfp x = (Dfp) other;
+            if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
+                return false;
+            }
+
+            return compare(this, x) == 0;
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Gets a hashCode for the instance.
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        return 17 + (sign << 8) + (nans << 16) + exp + Arrays.hashCode(mant);
+    }
+
+    /** Check if instance is not equal to x.
+     * @param x number to check instance against
+     * @return true if instance is not equal to x and neither are NaN, false otherwise
+     */
+    public boolean unequal(final Dfp x) {
+        if (isNaN() || x.isNaN() || field.getRadixDigits() != x.field.getRadixDigits()) {
+            return false;
+        }
+
+        return greaterThan(x) || lessThan(x);
+    }
+
+    /** Compare two instances.
+     * @param a first instance in comparison
+     * @param b second instance in comparison
+     * @return -1 if a<b, 1 if a>b and 0 if a==b
+     *  Note this method does not properly handle NaNs or numbers with different precision.
+     */
+    private static int compare(final Dfp a, final Dfp b) {
+        // Ignore the sign of zero
+        if (a.mant[a.mant.length - 1] == 0 && b.mant[b.mant.length - 1] == 0 &&
+            a.nans == FINITE && b.nans == FINITE) {
+            return 0;
+        }
+
+        if (a.sign != b.sign) {
+            if (a.sign == -1) {
+                return -1;
+            } else {
+                return 1;
+            }
+        }
+
+        // deal with the infinities
+        if (a.nans == INFINITE && b.nans == FINITE) {
+            return a.sign;
+        }
+
+        if (a.nans == FINITE && b.nans == INFINITE) {
+            return -b.sign;
+        }
+
+        if (a.nans == INFINITE && b.nans == INFINITE) {
+            return 0;
+        }
+
+        // Handle special case when a or b is zero, by ignoring the exponents
+        if (b.mant[b.mant.length-1] != 0 && a.mant[b.mant.length-1] != 0) {
+            if (a.exp < b.exp) {
+                return -a.sign;
+            }
+
+            if (a.exp > b.exp) {
+                return a.sign;
+            }
+        }
+
+        // compare the mantissas
+        for (int i = a.mant.length - 1; i >= 0; i--) {
+            if (a.mant[i] > b.mant[i]) {
+                return a.sign;
+            }
+
+            if (a.mant[i] < b.mant[i]) {
+                return -a.sign;
+            }
+        }
+
+        return 0;
+
+    }
+
+    /** Round to nearest integer using the round-half-even method.
+     *  That is round to nearest integer unless both are equidistant.
+     *  In which case round to the even one.
+     *  @return rounded value
+     */
+    public Dfp rint() {
+        return trunc(DfpField.RoundingMode.ROUND_HALF_EVEN);
+    }
+
+    /** Round to an integer using the round floor mode.
+     * That is, round toward -Infinity
+     *  @return rounded value
+     */
+    public Dfp floor() {
+        return trunc(DfpField.RoundingMode.ROUND_FLOOR);
+    }
+
+    /** Round to an integer using the round ceil mode.
+     * That is, round toward +Infinity
+     *  @return rounded value
+     */
+    public Dfp ceil() {
+        return trunc(DfpField.RoundingMode.ROUND_CEIL);
+    }
+
+    /** Returns the IEEE remainder.
+     * @param d divisor
+     * @return this less n &times; d, where n is the integer closest to this/d
+     */
+    public Dfp remainder(final Dfp d) {
+
+        final Dfp result = this.subtract(this.divide(d).rint().multiply(d));
+
+        // IEEE 854-1987 says that if the result is zero, then it carries the sign of this
+        if (result.mant[mant.length-1] == 0) {
+            result.sign = sign;
+        }
+
+        return result;
+
+    }
+
+    /** Does the integer conversions with the specified rounding.
+     * @param rmode rounding mode to use
+     * @return truncated value
+     */
+    protected Dfp trunc(final DfpField.RoundingMode rmode) {
+        boolean changed = false;
+
+        if (isNaN()) {
+            return newInstance(this);
+        }
+
+        if (nans == INFINITE) {
+            return newInstance(this);
+        }
+
+        if (mant[mant.length-1] == 0) {
+            // a is zero
+            return newInstance(this);
+        }
+
+        /* If the exponent is less than zero then we can certainly
+         * return zero */
+        if (exp < 0) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            Dfp result = newInstance(getZero());
+            result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
+            return result;
+        }
+
+        /* If the exponent is greater than or equal to digits, then it
+         * must already be an integer since there is no precision left
+         * for any fractional part */
+
+        if (exp >= mant.length) {
+            return newInstance(this);
+        }
+
+        /* General case:  create another dfp, result, that contains the
+         * a with the fractional part lopped off.  */
+
+        Dfp result = newInstance(this);
+        for (int i = 0; i < mant.length-result.exp; i++) {
+            changed |= result.mant[i] != 0;
+            result.mant[i] = 0;
+        }
+
+        if (changed) {
+            switch (rmode) {
+                case ROUND_FLOOR:
+                    if (result.sign == -1) {
+                        // then we must increment the mantissa by one
+                        result = result.add(newInstance(-1));
+                    }
+                    break;
+
+                case ROUND_CEIL:
+                    if (result.sign == 1) {
+                        // then we must increment the mantissa by one
+                        result = result.add(getOne());
+                    }
+                    break;
+
+                case ROUND_HALF_EVEN:
+                default:
+                    final Dfp half = newInstance("0.5");
+                    Dfp a = subtract(result);  // difference between this and result
+                    a.sign = 1;            // force positive (take abs)
+                    if (a.greaterThan(half)) {
+                        a = newInstance(getOne());
+                        a.sign = sign;
+                        result = result.add(a);
+                    }
+
+                    /** If exactly equal to 1/2 and odd then increment */
+                    if (a.equals(half) && result.exp > 0 && (result.mant[mant.length-result.exp]&1) != 0) {
+                        a = newInstance(getOne());
+                        a.sign = sign;
+                        result = result.add(a);
+                    }
+                    break;
+            }
+
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);  // signal inexact
+            result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
+            return result;
+        }
+
+        return result;
+    }
+
+    /** Convert this to an integer.
+     * If greater than 2147483647, it returns 2147483647. If less than -2147483648 it returns -2147483648.
+     * @return converted number
+     */
+    public int intValue() {
+        Dfp rounded;
+        int result = 0;
+
+        rounded = rint();
+
+        if (rounded.greaterThan(newInstance(2147483647))) {
+            return 2147483647;
+        }
+
+        if (rounded.lessThan(newInstance(-2147483648))) {
+            return -2147483648;
+        }
+
+        for (int i = mant.length - 1; i >= mant.length - rounded.exp; i--) {
+            result = result * RADIX + rounded.mant[i];
+        }
+
+        if (rounded.sign == -1) {
+            result = -result;
+        }
+
+        return result;
+    }
+
+    /** Get the exponent of the greatest power of 10000 that is
+     *  less than or equal to the absolute value of this.  I.E.  if
+     *  this is 10<sup>6</sup> then log10K would return 1.
+     *  @return integer base 10000 logarithm
+     */
+    public int log10K() {
+        return exp - 1;
+    }
+
+    /** Get the specified  power of 10000.
+     * @param e desired power
+     * @return 10000<sup>e</sup>
+     */
+    public Dfp power10K(final int e) {
+        Dfp d = newInstance(getOne());
+        d.exp = e + 1;
+        return d;
+    }
+
+    /** Get the exponent of the greatest power of 10 that is less than or equal to abs(this).
+     *  @return integer base 10 logarithm
+     */
+    public int log10()  {
+        if (mant[mant.length-1] > 1000) {
+            return exp * 4 - 1;
+        }
+        if (mant[mant.length-1] > 100) {
+            return exp * 4 - 2;
+        }
+        if (mant[mant.length-1] > 10) {
+            return exp * 4 - 3;
+        }
+        return exp * 4 - 4;
+    }
+
+    /** Return the specified  power of 10.
+     * @param e desired power
+     * @return 10<sup>e</sup>
+     */
+    public Dfp power10(final int e) {
+        Dfp d = newInstance(getOne());
+
+        if (e >= 0) {
+            d.exp = e / 4 + 1;
+        } else {
+            d.exp = (e + 1) / 4;
+        }
+
+        switch ((e % 4 + 4) % 4) {
+            case 0:
+                break;
+            case 1:
+                d = d.multiply(10);
+                break;
+            case 2:
+                d = d.multiply(100);
+                break;
+            default:
+                d = d.multiply(1000);
+        }
+
+        return d;
+    }
+
+    /** Negate the mantissa of this by computing the complement.
+     *  Leaves the sign bit unchanged, used internally by add.
+     *  Denormalized numbers are handled properly here.
+     *  @param extra ???
+     *  @return ???
+     */
+    protected int complement(int extra) {
+
+        extra = RADIX-extra;
+        for (int i = 0; i < mant.length; i++) {
+            mant[i] = RADIX-mant[i]-1;
+        }
+
+        int rh = extra / RADIX;
+        extra = extra - rh * RADIX;
+        for (int i = 0; i < mant.length; i++) {
+            final int r = mant[i] + rh;
+            rh = r / RADIX;
+            mant[i] = r - rh * RADIX;
+        }
+
+        return extra;
+    }
+
+    /** Add x to this.
+     * @param x number to add
+     * @return sum of this and x
+     */
+    public Dfp add(final Dfp x) {
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != x.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
+        }
+
+        /* handle special cases */
+        if (nans != FINITE || x.nans != FINITE) {
+            if (isNaN()) {
+                return this;
+            }
+
+            if (x.isNaN()) {
+                return x;
+            }
+
+            if (nans == INFINITE && x.nans == FINITE) {
+                return this;
+            }
+
+            if (x.nans == INFINITE && nans == FINITE) {
+                return x;
+            }
+
+            if (x.nans == INFINITE && nans == INFINITE && sign == x.sign) {
+                return x;
+            }
+
+            if (x.nans == INFINITE && nans == INFINITE && sign != x.sign) {
+                field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+                Dfp result = newInstance(getZero());
+                result.nans = QNAN;
+                result = dotrap(DfpField.FLAG_INVALID, ADD_TRAP, x, result);
+                return result;
+            }
+        }
+
+        /* copy this and the arg */
+        Dfp a = newInstance(this);
+        Dfp b = newInstance(x);
+
+        /* initialize the result object */
+        Dfp result = newInstance(getZero());
+
+        /* Make all numbers positive, but remember their sign */
+        final byte asign = a.sign;
+        final byte bsign = b.sign;
+
+        a.sign = 1;
+        b.sign = 1;
+
+        /* The result will be signed like the arg with greatest magnitude */
+        byte rsign = bsign;
+        if (compare(a, b) > 0) {
+            rsign = asign;
+        }
+
+        /* Handle special case when a or b is zero, by setting the exponent
+       of the zero number equal to the other one.  This avoids an alignment
+       which would cause catastropic loss of precision */
+        if (b.mant[mant.length-1] == 0) {
+            b.exp = a.exp;
+        }
+
+        if (a.mant[mant.length-1] == 0) {
+            a.exp = b.exp;
+        }
+
+        /* align number with the smaller exponent */
+        int aextradigit = 0;
+        int bextradigit = 0;
+        if (a.exp < b.exp) {
+            aextradigit = a.align(b.exp);
+        } else {
+            bextradigit = b.align(a.exp);
+        }
+
+        /* complement the smaller of the two if the signs are different */
+        if (asign != bsign) {
+            if (asign == rsign) {
+                bextradigit = b.complement(bextradigit);
+            } else {
+                aextradigit = a.complement(aextradigit);
+            }
+        }
+
+        /* add the mantissas */
+        int rh = 0; /* acts as a carry */
+        for (int i = 0; i < mant.length; i++) {
+            final int r = a.mant[i]+b.mant[i]+rh;
+            rh = r / RADIX;
+            result.mant[i] = r - rh * RADIX;
+        }
+        result.exp = a.exp;
+        result.sign = rsign;
+
+        /* handle overflow -- note, when asign!=bsign an overflow is
+         * normal and should be ignored.  */
+
+        if (rh != 0 && (asign == bsign)) {
+            final int lostdigit = result.mant[0];
+            result.shiftRight();
+            result.mant[mant.length-1] = rh;
+            final int excp = result.round(lostdigit);
+            if (excp != 0) {
+                result = dotrap(excp, ADD_TRAP, x, result);
+            }
+        }
+
+        /* normalize the result */
+        for (int i = 0; i < mant.length; i++) {
+            if (result.mant[mant.length-1] != 0) {
+                break;
+            }
+            result.shiftLeft();
+            if (i == 0) {
+                result.mant[0] = aextradigit+bextradigit;
+                aextradigit = 0;
+                bextradigit = 0;
+            }
+        }
+
+        /* result is zero if after normalization the most sig. digit is zero */
+        if (result.mant[mant.length-1] == 0) {
+            result.exp = 0;
+
+            if (asign != bsign) {
+                // Unless adding 2 negative zeros, sign is positive
+                result.sign = 1;  // Per IEEE 854-1987 Section 6.3
+            }
+        }
+
+        /* Call round to test for over/under flows */
+        final int excp = result.round(aextradigit + bextradigit);
+        if (excp != 0) {
+            result = dotrap(excp, ADD_TRAP, x, result);
+        }
+
+        return result;
+    }
+
+    /** Returns a number that is this number with the sign bit reversed.
+     * @return the opposite of this
+     */
+    public Dfp negate() {
+        Dfp result = newInstance(this);
+        result.sign = (byte) - result.sign;
+        return result;
+    }
+
+    /** Subtract x from this.
+     * @param x number to subtract
+     * @return difference of this and a
+     */
+    public Dfp subtract(final Dfp x) {
+        return add(x.negate());
+    }
+
+    /** Round this given the next digit n using the current rounding mode.
+     * @param n ???
+     * @return the IEEE flag if an exception occurred
+     */
+    protected int round(int n) {
+        boolean inc = false;
+        switch (field.getRoundingMode()) {
+            case ROUND_DOWN:
+                inc = false;
+                break;
+
+            case ROUND_UP:
+                inc = n != 0;       // round up if n!=0
+                break;
+
+            case ROUND_HALF_UP:
+                inc = n >= 5000;  // round half up
+                break;
+
+            case ROUND_HALF_DOWN:
+                inc = n > 5000;  // round half down
+                break;
+
+            case ROUND_HALF_EVEN:
+                inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 1);  // round half-even
+                break;
+
+            case ROUND_HALF_ODD:
+                inc = n > 5000 || (n == 5000 && (mant[0] & 1) == 0);  // round half-odd
+                break;
+
+            case ROUND_CEIL:
+                inc = sign == 1 && n != 0;  // round ceil
+                break;
+
+            case ROUND_FLOOR:
+            default:
+                inc = sign == -1 && n != 0;  // round floor
+                break;
+        }
+
+        if (inc) {
+            // increment if necessary
+            int rh = 1;
+            for (int i = 0; i < mant.length; i++) {
+                final int r = mant[i] + rh;
+                rh = r / RADIX;
+                mant[i] = r - rh * RADIX;
+            }
+
+            if (rh != 0) {
+                shiftRight();
+                mant[mant.length-1] = rh;
+            }
+        }
+
+        // check for exceptional cases and raise signals if necessary
+        if (exp < MIN_EXP) {
+            // Gradual Underflow
+            field.setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW);
+            return DfpField.FLAG_UNDERFLOW;
+        }
+
+        if (exp > MAX_EXP) {
+            // Overflow
+            field.setIEEEFlagsBits(DfpField.FLAG_OVERFLOW);
+            return DfpField.FLAG_OVERFLOW;
+        }
+
+        if (n != 0) {
+            // Inexact
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            return DfpField.FLAG_INEXACT;
+        }
+
+        return 0;
+
+    }
+
+    /** Multiply this by x.
+     * @param x multiplicand
+     * @return product of this and x
+     */
+    public Dfp multiply(final Dfp x) {
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != x.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
+        }
+
+        Dfp result = newInstance(getZero());
+
+        /* handle special cases */
+        if (nans != FINITE || x.nans != FINITE) {
+            if (isNaN()) {
+                return this;
+            }
+
+            if (x.isNaN()) {
+                return x;
+            }
+
+            if (nans == INFINITE && x.nans == FINITE && x.mant[mant.length-1] != 0) {
+                result = newInstance(this);
+                result.sign = (byte) (sign * x.sign);
+                return result;
+            }
+
+            if (x.nans == INFINITE && nans == FINITE && mant[mant.length-1] != 0) {
+                result = newInstance(x);
+                result.sign = (byte) (sign * x.sign);
+                return result;
+            }
+
+            if (x.nans == INFINITE && nans == INFINITE) {
+                result = newInstance(this);
+                result.sign = (byte) (sign * x.sign);
+                return result;
+            }
+
+            if ( (x.nans == INFINITE && nans == FINITE && mant[mant.length-1] == 0) ||
+                    (nans == INFINITE && x.nans == FINITE && x.mant[mant.length-1] == 0) ) {
+                field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+                result = newInstance(getZero());
+                result.nans = QNAN;
+                result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, x, result);
+                return result;
+            }
+        }
+
+        int[] product = new int[mant.length*2];  // Big enough to hold even the largest result
+
+        for (int i = 0; i < mant.length; i++) {
+            int rh = 0;  // acts as a carry
+            for (int j=0; j<mant.length; j++) {
+                int r = mant[i] * x.mant[j];    // multiply the 2 digits
+                r = r + product[i+j] + rh;  // add to the product digit with carry in
+
+                rh = r / RADIX;
+                product[i+j] = r - rh * RADIX;
+            }
+            product[i+mant.length] = rh;
+        }
+
+        // Find the most sig digit
+        int md = mant.length * 2 - 1;  // default, in case result is zero
+        for (int i = mant.length * 2 - 1; i >= 0; i--) {
+            if (product[i] != 0) {
+                md = i;
+                break;
+            }
+        }
+
+        // Copy the digits into the result
+        for (int i = 0; i < mant.length; i++) {
+            result.mant[mant.length - i - 1] = product[md - i];
+        }
+
+        // Fixup the exponent.
+        result.exp = exp + x.exp + md - 2 * mant.length + 1;
+        result.sign = (byte)((sign == x.sign)?1:-1);
+
+        if (result.mant[mant.length-1] == 0) {
+            // if result is zero, set exp to zero
+            result.exp = 0;
+        }
+
+        final int excp;
+        if (md > (mant.length-1)) {
+            excp = result.round(product[md-mant.length]);
+        } else {
+            excp = result.round(0); // has no effect except to check status
+        }
+
+        if (excp != 0) {
+            result = dotrap(excp, MULTIPLY_TRAP, x, result);
+        }
+
+        return result;
+
+    }
+
+    /** Multiply this by a single digit 0&lt;=x&lt;radix.
+     * There are speed advantages in this special case
+     * @param x multiplicand
+     * @return product of this and x
+     */
+    public Dfp multiply(final int x) {
+        Dfp result = newInstance(this);
+
+        /* handle special cases */
+        if (nans != FINITE) {
+            if (isNaN()) {
+                return this;
+            }
+
+            if (nans == INFINITE && x != 0) {
+                result = newInstance(this);
+                return result;
+            }
+
+            if (nans == INFINITE && x == 0) {
+                field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+                result = newInstance(getZero());
+                result.nans = QNAN;
+                result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, newInstance(getZero()), result);
+                return result;
+            }
+        }
+
+        /* range check x */
+        if (x < 0 || x >= RADIX) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            result = newInstance(getZero());
+            result.nans = QNAN;
+            result = dotrap(DfpField.FLAG_INVALID, MULTIPLY_TRAP, result, result);
+            return result;
+        }
+
+        int rh = 0;
+        for (int i = 0; i < mant.length; i++) {
+            final int r = mant[i] * x + rh;
+            rh = r / RADIX;
+            result.mant[i] = r - rh * RADIX;
+        }
+
+        int lostdigit = 0;
+        if (rh != 0) {
+            lostdigit = result.mant[0];
+            result.shiftRight();
+            result.mant[mant.length-1] = rh;
+        }
+
+        if (result.mant[mant.length-1] == 0) { // if result is zero, set exp to zero
+            result.exp = 0;
+        }
+
+        final int excp = result.round(lostdigit);
+        if (excp != 0) {
+            result = dotrap(excp, MULTIPLY_TRAP, result, result);
+        }
+
+        return result;
+    }
+
+    /** Divide this by divisor.
+     * @param divisor divisor
+     * @return quotient of this by divisor
+     */
+    public Dfp divide(Dfp divisor) {
+        int dividend[]; // current status of the dividend
+        int quotient[]; // quotient
+        int remainder[];// remainder
+        int qd;         // current quotient digit we're working with
+        int nsqd;       // number of significant quotient digits we have
+        int trial=0;    // trial quotient digit
+        int minadj;     // minimum adjustment
+        boolean trialgood; // Flag to indicate a good trail digit
+        int md=0;       // most sig digit in result
+        int excp;       // exceptions
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != divisor.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
+        }
+
+        Dfp result = newInstance(getZero());
+
+        /* handle special cases */
+        if (nans != FINITE || divisor.nans != FINITE) {
+            if (isNaN()) {
+                return this;
+            }
+
+            if (divisor.isNaN()) {
+                return divisor;
+            }
+
+            if (nans == INFINITE && divisor.nans == FINITE) {
+                result = newInstance(this);
+                result.sign = (byte) (sign * divisor.sign);
+                return result;
+            }
+
+            if (divisor.nans == INFINITE && nans == FINITE) {
+                result = newInstance(getZero());
+                result.sign = (byte) (sign * divisor.sign);
+                return result;
+            }
+
+            if (divisor.nans == INFINITE && nans == INFINITE) {
+                field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+                result = newInstance(getZero());
+                result.nans = QNAN;
+                result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, divisor, result);
+                return result;
+            }
+        }
+
+        /* Test for divide by zero */
+        if (divisor.mant[mant.length-1] == 0) {
+            field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
+            result = newInstance(getZero());
+            result.sign = (byte) (sign * divisor.sign);
+            result.nans = INFINITE;
+            result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, divisor, result);
+            return result;
+        }
+
+        dividend = new int[mant.length+1];  // one extra digit needed
+        quotient = new int[mant.length+2];  // two extra digits needed 1 for overflow, 1 for rounding
+        remainder = new int[mant.length+1]; // one extra digit needed
+
+        /* Initialize our most significant digits to zero */
+
+        dividend[mant.length] = 0;
+        quotient[mant.length] = 0;
+        quotient[mant.length+1] = 0;
+        remainder[mant.length] = 0;
+
+        /* copy our mantissa into the dividend, initialize the
+       quotient while we are at it */
+
+        for (int i = 0; i < mant.length; i++) {
+            dividend[i] = mant[i];
+            quotient[i] = 0;
+            remainder[i] = 0;
+        }
+
+        /* outer loop.  Once per quotient digit */
+        nsqd = 0;
+        for (qd = mant.length+1; qd >= 0; qd--) {
+            /* Determine outer limits of our quotient digit */
+
+            // r =  most sig 2 digits of dividend
+            final int divMsb = dividend[mant.length]*RADIX+dividend[mant.length-1];
+            int min = divMsb       / (divisor.mant[mant.length-1]+1);
+            int max = (divMsb + 1) / divisor.mant[mant.length-1];
+
+            trialgood = false;
+            while (!trialgood) {
+                // try the mean
+                trial = (min+max)/2;
+
+                /* Multiply by divisor and store as remainder */
+                int rh = 0;
+                for (int i = 0; i < mant.length + 1; i++) {
+                    int dm = (i<mant.length)?divisor.mant[i]:0;
+                    final int r = (dm * trial) + rh;
+                    rh = r / RADIX;
+                    remainder[i] = r - rh * RADIX;
+                }
+
+                /* subtract the remainder from the dividend */
+                rh = 1;  // carry in to aid the subtraction
+                for (int i = 0; i < mant.length + 1; i++) {
+                    final int r = ((RADIX-1) - remainder[i]) + dividend[i] + rh;
+                    rh = r / RADIX;
+                    remainder[i] = r - rh * RADIX;
+                }
+
+                /* Lets analyze what we have here */
+                if (rh == 0) {
+                    // trial is too big -- negative remainder
+                    max = trial-1;
+                    continue;
+                }
+
+                /* find out how far off the remainder is telling us we are */
+                minadj = (remainder[mant.length] * RADIX)+remainder[mant.length-1];
+                minadj = minadj / (divisor.mant[mant.length-1]+1);
+
+                if (minadj >= 2) {
+                    min = trial+minadj;  // update the minimum
+                    continue;
+                }
+
+                /* May have a good one here, check more thoroughly.  Basically
+           its a good one if it is less than the divisor */
+                trialgood = false;  // assume false
+                for (int i = mant.length - 1; i >= 0; i--) {
+                    if (divisor.mant[i] > remainder[i]) {
+                        trialgood = true;
+                    }
+                    if (divisor.mant[i] < remainder[i]) {
+                        break;
+                    }
+                }
+
+                if (remainder[mant.length] != 0) {
+                    trialgood = false;
+                }
+
+                if (trialgood == false) {
+                    min = trial+1;
+                }
+            }
+
+            /* Great we have a digit! */
+            quotient[qd] = trial;
+            if (trial != 0 || nsqd != 0) {
+                nsqd++;
+            }
+
+            if (field.getRoundingMode() == DfpField.RoundingMode.ROUND_DOWN && nsqd == mant.length) {
+                // We have enough for this mode
+                break;
+            }
+
+            if (nsqd > mant.length) {
+                // We have enough digits
+                break;
+            }
+
+            /* move the remainder into the dividend while left shifting */
+            dividend[0] = 0;
+            for (int i = 0; i < mant.length; i++) {
+                dividend[i + 1] = remainder[i];
+            }
+        }
+
+        /* Find the most sig digit */
+        md = mant.length;  // default
+        for (int i = mant.length + 1; i >= 0; i--) {
+            if (quotient[i] != 0) {
+                md = i;
+                break;
+            }
+        }
+
+        /* Copy the digits into the result */
+        for (int i=0; i<mant.length; i++) {
+            result.mant[mant.length-i-1] = quotient[md-i];
+        }
+
+        /* Fixup the exponent. */
+        result.exp = exp - divisor.exp + md - mant.length;
+        result.sign = (byte) ((sign == divisor.sign) ? 1 : -1);
+
+        if (result.mant[mant.length-1] == 0) { // if result is zero, set exp to zero
+            result.exp = 0;
+        }
+
+        if (md > (mant.length-1)) {
+            excp = result.round(quotient[md-mant.length]);
+        } else {
+            excp = result.round(0);
+        }
+
+        if (excp != 0) {
+            result = dotrap(excp, DIVIDE_TRAP, divisor, result);
+        }
+
+        return result;
+    }
+
+    /** Divide by a single digit less than radix.
+     *  Special case, so there are speed advantages. 0 &lt;= divisor &lt; radix
+     * @param divisor divisor
+     * @return quotient of this by divisor
+     */
+    public Dfp divide(int divisor) {
+
+        // Handle special cases
+        if (nans != FINITE) {
+            if (isNaN()) {
+                return this;
+            }
+
+            if (nans == INFINITE) {
+                return newInstance(this);
+            }
+        }
+
+        // Test for divide by zero
+        if (divisor == 0) {
+            field.setIEEEFlagsBits(DfpField.FLAG_DIV_ZERO);
+            Dfp result = newInstance(getZero());
+            result.sign = sign;
+            result.nans = INFINITE;
+            result = dotrap(DfpField.FLAG_DIV_ZERO, DIVIDE_TRAP, getZero(), result);
+            return result;
+        }
+
+        // range check divisor
+        if (divisor < 0 || divisor >= RADIX) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            result = dotrap(DfpField.FLAG_INVALID, DIVIDE_TRAP, result, result);
+            return result;
+        }
+
+        Dfp result = newInstance(this);
+
+        int rl = 0;
+        for (int i = mant.length-1; i >= 0; i--) {
+            final int r = rl*RADIX + result.mant[i];
+            final int rh = r / divisor;
+            rl = r - rh * divisor;
+            result.mant[i] = rh;
+        }
+
+        if (result.mant[mant.length-1] == 0) {
+            // normalize
+            result.shiftLeft();
+            final int r = rl * RADIX;        // compute the next digit and put it in
+            final int rh = r / divisor;
+            rl = r - rh * divisor;
+            result.mant[0] = rh;
+        }
+
+        final int excp = result.round(rl * RADIX / divisor);  // do the rounding
+        if (excp != 0) {
+            result = dotrap(excp, DIVIDE_TRAP, result, result);
+        }
+
+        return result;
+
+    }
+
+    /** Compute the square root.
+     * @return square root of the instance
+     */
+    public Dfp sqrt() {
+
+        // check for unusual cases
+        if (nans == FINITE && mant[mant.length-1] == 0) {
+            // if zero
+            return newInstance(this);
+        }
+
+        if (nans != FINITE) {
+            if (nans == INFINITE && sign == 1) {
+                // if positive infinity
+                return newInstance(this);
+            }
+
+            if (nans == QNAN) {
+                return newInstance(this);
+            }
+
+            if (nans == SNAN) {
+                Dfp result;
+
+                field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+                result = newInstance(this);
+                result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
+                return result;
+            }
+        }
+
+        if (sign == -1) {
+            // if negative
+            Dfp result;
+
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            result = newInstance(this);
+            result.nans = QNAN;
+            result = dotrap(DfpField.FLAG_INVALID, SQRT_TRAP, null, result);
+            return result;
+        }
+
+        Dfp x = newInstance(this);
+
+        /* Lets make a reasonable guess as to the size of the square root */
+        if (x.exp < -1 || x.exp > 1) {
+            x.exp = this.exp / 2;
+        }
+
+        /* Coarsely estimate the mantissa */
+        switch (x.mant[mant.length-1] / 2000) {
+            case 0:
+                x.mant[mant.length-1] = x.mant[mant.length-1]/2+1;
+                break;
+            case 2:
+                x.mant[mant.length-1] = 1500;
+                break;
+            case 3:
+                x.mant[mant.length-1] = 2200;
+                break;
+            default:
+                x.mant[mant.length-1] = 3000;
+        }
+
+        Dfp dx = newInstance(x);
+
+        /* Now that we have the first pass estimate, compute the rest
+       by the formula dx = (y - x*x) / (2x); */
+
+        Dfp px  = getZero();
+        Dfp ppx = getZero();
+        while (x.unequal(px)) {
+            dx = newInstance(x);
+            dx.sign = -1;
+            dx = dx.add(this.divide(x));
+            dx = dx.divide(2);
+            ppx = px;
+            px = x;
+            x = x.add(dx);
+
+            if (x.equals(ppx)) {
+                // alternating between two values
+                break;
+            }
+
+            // if dx is zero, break.  Note testing the most sig digit
+            // is a sufficient test since dx is normalized
+            if (dx.mant[mant.length-1] == 0) {
+                break;
+            }
+        }
+
+        return x;
+
+    }
+
+    /** Get a string representation of the instance.
+     * @return string representation of the instance
+     */
+    @Override
+    public String toString() {
+        if (nans != FINITE) {
+            // if non-finite exceptional cases
+            if (nans == INFINITE) {
+                return (sign < 0) ? NEG_INFINITY_STRING : POS_INFINITY_STRING;
+            } else {
+                return NAN_STRING;
+            }
+        }
+
+        if (exp > mant.length || exp < -1) {
+            return dfp2sci();
+        }
+
+        return dfp2string();
+
+    }
+
+    /** Convert an instance to a string using scientific notation.
+     * @return string representation of the instance in scientific notation
+     */
+    protected String dfp2sci() {
+        char rawdigits[]    = new char[mant.length * 4];
+        char outputbuffer[] = new char[mant.length * 4 + 20];
+        int p;
+        int q;
+        int e;
+        int ae;
+        int shf;
+
+        // Get all the digits
+        p = 0;
+        for (int i = mant.length - 1; i >= 0; i--) {
+            rawdigits[p++] = (char) ((mant[i] / 1000) + '0');
+            rawdigits[p++] = (char) (((mant[i] / 100) %10) + '0');
+            rawdigits[p++] = (char) (((mant[i] / 10) % 10) + '0');
+            rawdigits[p++] = (char) (((mant[i]) % 10) + '0');
+        }
+
+        // Find the first non-zero one
+        for (p = 0; p < rawdigits.length; p++) {
+            if (rawdigits[p] != '0') {
+                break;
+            }
+        }
+        shf = p;
+
+        // Now do the conversion
+        q = 0;
+        if (sign == -1) {
+            outputbuffer[q++] = '-';
+        }
+
+        if (p != rawdigits.length) {
+            // there are non zero digits...
+            outputbuffer[q++] = rawdigits[p++];
+            outputbuffer[q++] = '.';
+
+            while (p<rawdigits.length) {
+                outputbuffer[q++] = rawdigits[p++];
+            }
+        } else {
+            outputbuffer[q++] = '0';
+            outputbuffer[q++] = '.';
+            outputbuffer[q++] = '0';
+            outputbuffer[q++] = 'e';
+            outputbuffer[q++] = '0';
+            return new String(outputbuffer, 0, 5);
+        }
+
+        outputbuffer[q++] = 'e';
+
+        // Find the msd of the exponent
+
+        e = exp * 4 - shf - 1;
+        ae = e;
+        if (e < 0) {
+            ae = -e;
+        }
+
+        // Find the largest p such that p < e
+        for (p = 1000000000; p > ae; p /= 10) {
+            // nothing to do
+        }
+
+        if (e < 0) {
+            outputbuffer[q++] = '-';
+        }
+
+        while (p > 0) {
+            outputbuffer[q++] = (char)(ae / p + '0');
+            ae = ae % p;
+            p = p / 10;
+        }
+
+        return new String(outputbuffer, 0, q);
+
+    }
+
+    /** Convert an instance to a string using normal notation.
+     * @return string representation of the instance in normal notation
+     */
+    protected String dfp2string() {
+        char buffer[] = new char[mant.length*4 + 20];
+        int p = 1;
+        int q;
+        int e = exp;
+        boolean pointInserted = false;
+
+        buffer[0] = ' ';
+
+        if (e <= 0) {
+            buffer[p++] = '0';
+            buffer[p++] = '.';
+            pointInserted = true;
+        }
+
+        while (e < 0) {
+            buffer[p++] = '0';
+            buffer[p++] = '0';
+            buffer[p++] = '0';
+            buffer[p++] = '0';
+            e++;
+        }
+
+        for (int i = mant.length - 1; i >= 0; i--) {
+            buffer[p++] = (char) ((mant[i] / 1000) + '0');
+            buffer[p++] = (char) (((mant[i] / 100) % 10) + '0');
+            buffer[p++] = (char) (((mant[i] / 10) % 10) + '0');
+            buffer[p++] = (char) (((mant[i]) % 10) + '0');
+            if (--e == 0) {
+                buffer[p++] = '.';
+                pointInserted = true;
+            }
+        }
+
+        while (e > 0) {
+            buffer[p++] = '0';
+            buffer[p++] = '0';
+            buffer[p++] = '0';
+            buffer[p++] = '0';
+            e--;
+        }
+
+        if (!pointInserted) {
+            // Ensure we have a radix point!
+            buffer[p++] = '.';
+        }
+
+        // Suppress leading zeros
+        q = 1;
+        while (buffer[q] == '0') {
+            q++;
+        }
+        if (buffer[q] == '.') {
+            q--;
+        }
+
+        // Suppress trailing zeros
+        while (buffer[p-1] == '0') {
+            p--;
+        }
+
+        // Insert sign
+        if (sign < 0) {
+            buffer[--q] = '-';
+        }
+
+        return new String(buffer, q, p - q);
+
+    }
+
+    /** Raises a trap.  This does not set the corresponding flag however.
+     *  @param type the trap type
+     *  @param what - name of routine trap occurred in
+     *  @param oper - input operator to function
+     *  @param result - the result computed prior to the trap
+     *  @return The suggested return value from the trap handler
+     */
+    public Dfp dotrap(int type, String what, Dfp oper, Dfp result) {
+        Dfp def = result;
+
+        switch (type) {
+            case DfpField.FLAG_INVALID:
+                def = newInstance(getZero());
+                def.sign = result.sign;
+                def.nans = QNAN;
+                break;
+
+            case DfpField.FLAG_DIV_ZERO:
+                if (nans == FINITE && mant[mant.length-1] != 0) {
+                    // normal case, we are finite, non-zero
+                    def = newInstance(getZero());
+                    def.sign = (byte)(sign*oper.sign);
+                    def.nans = INFINITE;
+                }
+
+                if (nans == FINITE && mant[mant.length-1] == 0) {
+                    //  0/0
+                    def = newInstance(getZero());
+                    def.nans = QNAN;
+                }
+
+                if (nans == INFINITE || nans == QNAN) {
+                    def = newInstance(getZero());
+                    def.nans = QNAN;
+                }
+
+                if (nans == INFINITE || nans == SNAN) {
+                    def = newInstance(getZero());
+                    def.nans = QNAN;
+                }
+                break;
+
+            case DfpField.FLAG_UNDERFLOW:
+                if ( (result.exp+mant.length) < MIN_EXP) {
+                    def = newInstance(getZero());
+                    def.sign = result.sign;
+                } else {
+                    def = newInstance(result);  // gradual underflow
+                }
+                result.exp = result.exp + ERR_SCALE;
+                break;
+
+            case DfpField.FLAG_OVERFLOW:
+                result.exp = result.exp - ERR_SCALE;
+                def = newInstance(getZero());
+                def.sign = result.sign;
+                def.nans = INFINITE;
+                break;
+
+            default: def = result; break;
+        }
+
+        return trap(type, what, oper, def, result);
+
+    }
+
+    /** Trap handler.  Subclasses may override this to provide trap
+     *  functionality per IEEE 854-1987.
+     *
+     *  @param type  The exception type - e.g. FLAG_OVERFLOW
+     *  @param what  The name of the routine we were in e.g. divide()
+     *  @param oper  An operand to this function if any
+     *  @param def   The default return value if trap not enabled
+     *  @param result    The result that is specified to be delivered per
+     *                   IEEE 854, if any
+     *  @return the value that should be return by the operation triggering the trap
+     */
+    protected Dfp trap(int type, String what, Dfp oper, Dfp def, Dfp result) {
+        return def;
+    }
+
+    /** Returns the type - one of FINITE, INFINITE, SNAN, QNAN.
+     * @return type of the number
+     */
+    public int classify() {
+        return nans;
+    }
+
+    /** Creates an instance that is the same as x except that it has the sign of y.
+     * abs(x) = dfp.copysign(x, dfp.one)
+     * @param x number to get the value from
+     * @param y number to get the sign from
+     * @return a number with the value of x and the sign of y
+     */
+    public static Dfp copysign(final Dfp x, final Dfp y) {
+        Dfp result = x.newInstance(x);
+        result.sign = y.sign;
+        return result;
+    }
+
+    /** Returns the next number greater than this one in the direction of x.
+     * If this==x then simply returns this.
+     * @param x direction where to look at
+     * @return closest number next to instance in the direction of x
+     */
+    public Dfp nextAfter(final Dfp x) {
+
+        // make sure we don't mix number with different precision
+        if (field.getRadixDigits() != x.field.getRadixDigits()) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, NEXT_AFTER_TRAP, x, result);
+        }
+
+        // if this is greater than x
+        boolean up = false;
+        if (this.lessThan(x)) {
+            up = true;
+        }
+
+        if (compare(this, x) == 0) {
+            return newInstance(x);
+        }
+
+        if (lessThan(getZero())) {
+            up = !up;
+        }
+
+        final Dfp inc;
+        Dfp result;
+        if (up) {
+            inc = newInstance(getOne());
+            inc.exp = this.exp-mant.length+1;
+            inc.sign = this.sign;
+
+            if (this.equals(getZero())) {
+                inc.exp = MIN_EXP-mant.length;
+            }
+
+            result = add(inc);
+        } else {
+            inc = newInstance(getOne());
+            inc.exp = this.exp;
+            inc.sign = this.sign;
+
+            if (this.equals(inc)) {
+                inc.exp = this.exp-mant.length;
+            } else {
+                inc.exp = this.exp-mant.length+1;
+            }
+
+            if (this.equals(getZero())) {
+                inc.exp = MIN_EXP-mant.length;
+            }
+
+            result = this.subtract(inc);
+        }
+
+        if (result.classify() == INFINITE && this.classify() != INFINITE) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
+        }
+
+        if (result.equals(getZero()) && this.equals(getZero()) == false) {
+            field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            result = dotrap(DfpField.FLAG_INEXACT, NEXT_AFTER_TRAP, x, result);
+        }
+
+        return result;
+
+    }
+
+    /** Convert the instance into a double.
+     * @return a double approximating the instance
+     * @see #toSplitDouble()
+     */
+    public double toDouble() {
+
+        if (isInfinite()) {
+            if (lessThan(getZero())) {
+                return Double.NEGATIVE_INFINITY;
+            } else {
+                return Double.POSITIVE_INFINITY;
+            }
+        }
+
+        if (isNaN()) {
+            return Double.NaN;
+        }
+
+        Dfp y = this;
+        boolean negate = false;
+        if (lessThan(getZero())) {
+            y = negate();
+            negate = true;
+        }
+
+        /* Find the exponent, first estimate by integer log10, then adjust.
+         Should be faster than doing a natural logarithm.  */
+        int exponent = (int)(y.log10() * 3.32);
+        if (exponent < 0) {
+            exponent--;
+        }
+
+        Dfp tempDfp = DfpMath.pow(getTwo(), exponent);
+        while (tempDfp.lessThan(y) || tempDfp.equals(y)) {
+            tempDfp = tempDfp.multiply(2);
+            exponent++;
+        }
+        exponent--;
+
+        /* We have the exponent, now work on the mantissa */
+
+        y = y.divide(DfpMath.pow(getTwo(), exponent));
+        if (exponent > -1023) {
+            y = y.subtract(getOne());
+        }
+
+        if (exponent < -1074) {
+            return 0;
+        }
+
+        if (exponent > 1023) {
+            return negate ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+        }
+
+
+        y = y.multiply(newInstance(4503599627370496l)).rint();
+        String str = y.toString();
+        str = str.substring(0, str.length()-1);
+        long mantissa = Long.parseLong(str);
+
+        if (mantissa == 4503599627370496L) {
+            // Handle special case where we round up to next power of two
+            mantissa = 0;
+            exponent++;
+        }
+
+        /* Its going to be subnormal, so make adjustments */
+        if (exponent <= -1023) {
+            exponent--;
+        }
+
+        while (exponent < -1023) {
+            exponent++;
+            mantissa >>>= 1;
+        }
+
+        long bits = mantissa | ((exponent + 1023L) << 52);
+        double x = Double.longBitsToDouble(bits);
+
+        if (negate) {
+            x = -x;
+        }
+
+        return x;
+
+    }
+
+    /** Convert the instance into a split double.
+     * @return an array of two doubles which sum represent the instance
+     * @see #toDouble()
+     */
+    public double[] toSplitDouble() {
+        double split[] = new double[2];
+        long mask = 0xffffffffc0000000L;
+
+        split[0] = Double.longBitsToDouble(Double.doubleToLongBits(toDouble()) & mask);
+        split[1] = subtract(newInstance(split[0])).toDouble();
+
+        return split;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/dfp/DfpDec.java b/src/main/java/org/apache/commons/math/dfp/DfpDec.java
new file mode 100644
index 0000000..d2c3b56
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/dfp/DfpDec.java
@@ -0,0 +1,369 @@
+/*
+ * 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.dfp;
+
+/** Subclass of {@link Dfp} which hides the radix-10000 artifacts of the superclass.
+ * This should give outward appearances of being a decimal number with DIGITS*4-3
+ * decimal digits. This class can be subclassed to appear to be an arbitrary number
+ * of decimal digits less than DIGITS*4-3.
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+ */
+public class DfpDec extends Dfp {
+
+    /** Makes an instance with a value of zero.
+     * @param factory factory linked to this instance
+     */
+    protected DfpDec(final DfpField factory) {
+        super(factory);
+    }
+
+    /** Create an instance from a byte value.
+     * @param factory factory linked to this instance
+     * @param x value to convert to an instance
+     */
+    protected DfpDec(final DfpField factory, byte x) {
+        super(factory, x);
+    }
+
+    /** Create an instance from an int value.
+     * @param factory factory linked to this instance
+     * @param x value to convert to an instance
+     */
+    protected DfpDec(final DfpField factory, int x) {
+        super(factory, x);
+    }
+
+    /** Create an instance from a long value.
+     * @param factory factory linked to this instance
+     * @param x value to convert to an instance
+     */
+    protected DfpDec(final DfpField factory, long x) {
+        super(factory, x);
+    }
+
+    /** Create an instance from a double value.
+     * @param factory factory linked to this instance
+     * @param x value to convert to an instance
+     */
+    protected DfpDec(final DfpField factory, double x) {
+        super(factory, x);
+        round(0);
+    }
+
+    /** Copy constructor.
+     * @param d instance to copy
+     */
+    public DfpDec(final Dfp d) {
+        super(d);
+        round(0);
+    }
+
+    /** Create an instance from a String representation.
+     * @param factory factory linked to this instance
+     * @param s string representation of the instance
+     */
+    protected DfpDec(final DfpField factory, final String s) {
+        super(factory, s);
+        round(0);
+    }
+
+    /** Creates an instance with a non-finite value.
+     * @param factory factory linked to this instance
+     * @param sign sign of the Dfp to create
+     * @param nans code of the value, must be one of {@link #INFINITE},
+     * {@link #SNAN},  {@link #QNAN}
+     */
+    protected DfpDec(final DfpField factory, final byte sign, final byte nans) {
+        super(factory, sign, nans);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance() {
+        return new DfpDec(getField());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final byte x) {
+        return new DfpDec(getField(), x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final int x) {
+        return new DfpDec(getField(), x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final long x) {
+        return new DfpDec(getField(), x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final double x) {
+        return new DfpDec(getField(), x);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final Dfp d) {
+
+        // make sure we don't mix number with different precision
+        if (getField().getRadixDigits() != d.getField().getRadixDigits()) {
+            getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, "newInstance", d, result);
+        }
+
+        return new DfpDec(d);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final String s) {
+        return new DfpDec(getField(), s);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp newInstance(final byte sign, final byte nans) {
+        return new DfpDec(getField(), sign, nans);
+    }
+
+    /** Get the number of decimal digits this class is going to represent.
+     * Default implementation returns {@link #getRadixDigits()}*4-3. Subclasses can
+     * override this to return something less.
+     * @return number of decimal digits this class is going to represent
+     */
+    protected int getDecimalDigits() {
+        return getRadixDigits() * 4 - 3;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int round(int in) {
+
+        int msb = mant[mant.length-1];
+        if (msb == 0) {
+            // special case -- this == zero
+            return 0;
+        }
+
+        int cmaxdigits = mant.length * 4;
+        int lsbthreshold = 1000;
+        while (lsbthreshold > msb) {
+            lsbthreshold /= 10;
+            cmaxdigits --;
+        }
+
+
+        final int digits = getDecimalDigits();
+        final int lsbshift = cmaxdigits - digits;
+        final int lsd = lsbshift / 4;
+
+        lsbthreshold = 1;
+        for (int i = 0; i < lsbshift % 4; i++) {
+            lsbthreshold *= 10;
+        }
+
+        final int lsb = mant[lsd];
+
+        if (lsbthreshold <= 1 && digits == 4 * mant.length - 3) {
+            return super.round(in);
+        }
+
+        int discarded = in;  // not looking at this after this point
+        final int n;
+        if (lsbthreshold == 1) {
+            // look to the next digit for rounding
+            n = (mant[lsd-1] / 1000) % 10;
+            mant[lsd-1] %= 1000;
+            discarded |= mant[lsd-1];
+        } else {
+            n = (lsb * 10 / lsbthreshold) % 10;
+            discarded |= lsb % (lsbthreshold/10);
+        }
+
+        for (int i = 0; i < lsd; i++) {
+            discarded |= mant[i];    // need to know if there are any discarded bits
+            mant[i] = 0;
+        }
+
+        mant[lsd] = lsb / lsbthreshold * lsbthreshold;
+
+        final boolean inc;
+        switch (getField().getRoundingMode()) {
+            case ROUND_DOWN:
+                inc = false;
+                break;
+
+            case ROUND_UP:
+                inc = (n != 0) || (discarded != 0); // round up if n!=0
+                break;
+
+            case ROUND_HALF_UP:
+                inc = n >= 5;  // round half up
+                break;
+
+            case ROUND_HALF_DOWN:
+                inc = n > 5;  // round half down
+                break;
+
+            case ROUND_HALF_EVEN:
+                inc = (n > 5) ||
+                      (n == 5 && discarded != 0) ||
+                      (n == 5 && discarded == 0 && ((lsb / lsbthreshold) & 1) == 1);  // round half-even
+                break;
+
+            case ROUND_HALF_ODD:
+                inc = (n > 5) ||
+                      (n == 5 && discarded != 0) ||
+                      (n == 5 && discarded == 0 && ((lsb / lsbthreshold) & 1) == 0);  // round half-odd
+                break;
+
+            case ROUND_CEIL:
+                inc = (sign == 1) && (n != 0 || discarded != 0);  // round ceil
+                break;
+
+            case ROUND_FLOOR:
+            default:
+                inc = (sign == -1) && (n != 0 || discarded != 0);  // round floor
+                break;
+        }
+
+        if (inc) {
+            // increment if necessary
+            int rh = lsbthreshold;
+            for (int i = lsd; i < mant.length; i++) {
+                final int r = mant[i] + rh;
+                rh = r / RADIX;
+                mant[i] = r % RADIX;
+            }
+
+            if (rh != 0) {
+                shiftRight();
+                mant[mant.length-1]=rh;
+            }
+        }
+
+        // Check for exceptional cases and raise signals if necessary
+        if (exp < MIN_EXP) {
+            // Gradual Underflow
+            getField().setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW);
+            return DfpField.FLAG_UNDERFLOW;
+        }
+
+        if (exp > MAX_EXP) {
+            // Overflow
+            getField().setIEEEFlagsBits(DfpField.FLAG_OVERFLOW);
+            return DfpField.FLAG_OVERFLOW;
+        }
+
+        if (n != 0 || discarded != 0) {
+            // Inexact
+            getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            return DfpField.FLAG_INEXACT;
+        }
+        return 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Dfp nextAfter(Dfp x) {
+
+        final String trapName = "nextAfter";
+
+        // make sure we don't mix number with different precision
+        if (getField().getRadixDigits() != x.getField().getRadixDigits()) {
+            getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = newInstance(getZero());
+            result.nans = QNAN;
+            return dotrap(DfpField.FLAG_INVALID, trapName, x, result);
+        }
+
+        boolean up = false;
+        Dfp result;
+        Dfp inc;
+
+        // if this is greater than x
+        if (this.lessThan(x)) {
+            up = true;
+        }
+
+        if (equals(x)) {
+            return newInstance(x);
+        }
+
+        if (lessThan(getZero())) {
+            up = !up;
+        }
+
+        if (up) {
+            inc = power10(log10() - getDecimalDigits() + 1);
+            inc = copysign(inc, this);
+
+            if (this.equals(getZero())) {
+                inc = power10K(MIN_EXP-mant.length-1);
+            }
+
+            if (inc.equals(getZero())) {
+                result = copysign(newInstance(getZero()), this);
+            } else {
+                result = add(inc);
+            }
+        } else {
+            inc = power10(log10());
+            inc = copysign(inc, this);
+
+            if (this.equals(inc)) {
+                inc = inc.divide(power10(getDecimalDigits()));
+            } else {
+                inc = inc.divide(power10(getDecimalDigits() - 1));
+            }
+
+            if (this.equals(getZero())) {
+                inc = power10K(MIN_EXP-mant.length-1);
+            }
+
+            if (inc.equals(getZero())) {
+                result = copysign(newInstance(getZero()), this);
+            } else {
+                result = subtract(inc);
+            }
+        }
+
+        if (result.classify() == INFINITE && this.classify() != INFINITE) {
+            getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            result = dotrap(DfpField.FLAG_INEXACT, trapName, x, result);
+        }
+
+        if (result.equals(getZero()) && this.equals(getZero()) == false) {
+            getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT);
+            result = dotrap(DfpField.FLAG_INEXACT, trapName, x, result);
+        }
+
+        return result;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/dfp/DfpField.java b/src/main/java/org/apache/commons/math/dfp/DfpField.java
new file mode 100644
index 0000000..65a25f4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/dfp/DfpField.java
@@ -0,0 +1,750 @@
+/*
+ * 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.dfp;
+
+import org.apache.commons.math.Field;
+
+/** Field for Decimal floating point instances.
+ * @version $Revision: 995987 $ $Date: 2010-09-10 23:24:15 +0200 (ven. 10 sept. 2010) $
+ * @since 2.2
+ */
+public class DfpField implements Field<Dfp> {
+
+    /** Enumerate for rounding modes. */
+    public enum RoundingMode {
+
+        /** Rounds toward zero (truncation). */
+        ROUND_DOWN,
+
+        /** Rounds away from zero if discarded digit is non-zero. */
+        ROUND_UP,
+
+        /** Rounds towards nearest unless both are equidistant in which case it rounds away from zero. */
+        ROUND_HALF_UP,
+
+        /** Rounds towards nearest unless both are equidistant in which case it rounds toward zero. */
+        ROUND_HALF_DOWN,
+
+        /** Rounds towards nearest unless both are equidistant in which case it rounds toward the even neighbor.
+         * This is the default as  specified by IEEE 854-1987
+         */
+        ROUND_HALF_EVEN,
+
+        /** Rounds towards nearest unless both are equidistant in which case it rounds toward the odd neighbor.  */
+        ROUND_HALF_ODD,
+
+        /** Rounds towards positive infinity. */
+        ROUND_CEIL,
+
+        /** Rounds towards negative infinity. */
+        ROUND_FLOOR;
+
+    }
+
+    /** IEEE 854-1987 flag for invalid operation. */
+    public static final int FLAG_INVALID   =  1;
+
+    /** IEEE 854-1987 flag for division by zero. */
+    public static final int FLAG_DIV_ZERO  =  2;
+
+    /** IEEE 854-1987 flag for overflow. */
+    public static final int FLAG_OVERFLOW  =  4;
+
+    /** IEEE 854-1987 flag for underflow. */
+    public static final int FLAG_UNDERFLOW =  8;
+
+    /** IEEE 854-1987 flag for inexact result. */
+    public static final int FLAG_INEXACT   = 16;
+
+    /** High precision string representation of &radic;2. */
+    private static String sqr2String;
+
+    /** High precision string representation of &radic;2 / 2. */
+    private static String sqr2ReciprocalString;
+
+    /** High precision string representation of &radic;3. */
+    private static String sqr3String;
+
+    /** High precision string representation of &radic;3 / 3. */
+    private static String sqr3ReciprocalString;
+
+    /** High precision string representation of &pi;. */
+    private static String piString;
+
+    /** High precision string representation of e. */
+    private static String eString;
+
+    /** High precision string representation of ln(2). */
+    private static String ln2String;
+
+    /** High precision string representation of ln(5). */
+    private static String ln5String;
+
+    /** High precision string representation of ln(10). */
+    private static String ln10String;
+
+    /** The number of radix digits.
+     * Note these depend on the radix which is 10000 digits,
+     * so each one is equivalent to 4 decimal digits.
+     */
+    private final int radixDigits;
+
+    /** A {@link Dfp} with value 0. */
+    private final Dfp zero;
+
+    /** A {@link Dfp} with value 1. */
+    private final Dfp one;
+
+    /** A {@link Dfp} with value 2. */
+    private final Dfp two;
+
+    /** A {@link Dfp} with value &radic;2. */
+    private final Dfp sqr2;
+
+    /** A two elements {@link Dfp} array with value &radic;2 split in two pieces. */
+    private final Dfp[] sqr2Split;
+
+    /** A {@link Dfp} with value &radic;2 / 2. */
+    private final Dfp sqr2Reciprocal;
+
+    /** A {@link Dfp} with value &radic;3. */
+    private final Dfp sqr3;
+
+    /** A {@link Dfp} with value &radic;3 / 3. */
+    private final Dfp sqr3Reciprocal;
+
+    /** A {@link Dfp} with value &pi;. */
+    private final Dfp pi;
+
+    /** A two elements {@link Dfp} array with value &pi; split in two pieces. */
+    private final Dfp[] piSplit;
+
+    /** A {@link Dfp} with value e. */
+    private final Dfp e;
+
+    /** A two elements {@link Dfp} array with value e split in two pieces. */
+    private final Dfp[] eSplit;
+
+    /** A {@link Dfp} with value ln(2). */
+    private final Dfp ln2;
+
+    /** A two elements {@link Dfp} array with value ln(2) split in two pieces. */
+    private final Dfp[] ln2Split;
+
+    /** A {@link Dfp} with value ln(5). */
+    private final Dfp ln5;
+
+    /** A two elements {@link Dfp} array with value ln(5) split in two pieces. */
+    private final Dfp[] ln5Split;
+
+    /** A {@link Dfp} with value ln(10). */
+    private final Dfp ln10;
+
+    /** Current rounding mode. */
+    private RoundingMode rMode;
+
+    /** IEEE 854-1987 signals. */
+    private int ieeeFlags;
+
+    /** Create a factory for the specified number of radix digits.
+     * <p>
+     * Note that since the {@link Dfp} class uses 10000 as its radix, each radix
+     * digit is equivalent to 4 decimal digits. This implies that asking for
+     * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in
+     * all cases.
+     * </p>
+     * @param decimalDigits minimal number of decimal digits.
+     */
+    public DfpField(final int decimalDigits) {
+        this(decimalDigits, true);
+    }
+
+    /** Create a factory for the specified number of radix digits.
+     * <p>
+     * Note that since the {@link Dfp} class uses 10000 as its radix, each radix
+     * digit is equivalent to 4 decimal digits. This implies that asking for
+     * 13, 14, 15 or 16 decimal digits will really lead to a 4 radix 10000 digits in
+     * all cases.
+     * </p>
+     * @param decimalDigits minimal number of decimal digits
+     * @param computeConstants if true, the transcendental constants for the given precision
+     * must be computed (setting this flag to false is RESERVED for the internal recursive call)
+     */
+    private DfpField(final int decimalDigits, final boolean computeConstants) {
+
+        this.radixDigits = (decimalDigits < 13) ? 4 : (decimalDigits + 3) / 4;
+        this.rMode       = RoundingMode.ROUND_HALF_EVEN;
+        this.ieeeFlags   = 0;
+        this.zero        = new Dfp(this, 0);
+        this.one         = new Dfp(this, 1);
+        this.two         = new Dfp(this, 2);
+
+        if (computeConstants) {
+            // set up transcendental constants
+            synchronized (DfpField.class) {
+
+                // as a heuristic to circumvent Table-Maker's Dilemma, we set the string
+                // representation of the constants to be at least 3 times larger than the
+                // number of decimal digits, also as an attempt to really compute these
+                // constants only once, we set a minimum number of digits
+                computeStringConstants((decimalDigits < 67) ? 200 : (3 * decimalDigits));
+
+                // set up the constants at current field accuracy
+                sqr2           = new Dfp(this, sqr2String);
+                sqr2Split      = split(sqr2String);
+                sqr2Reciprocal = new Dfp(this, sqr2ReciprocalString);
+                sqr3           = new Dfp(this, sqr3String);
+                sqr3Reciprocal = new Dfp(this, sqr3ReciprocalString);
+                pi             = new Dfp(this, piString);
+                piSplit        = split(piString);
+                e              = new Dfp(this, eString);
+                eSplit         = split(eString);
+                ln2            = new Dfp(this, ln2String);
+                ln2Split       = split(ln2String);
+                ln5            = new Dfp(this, ln5String);
+                ln5Split       = split(ln5String);
+                ln10           = new Dfp(this, ln10String);
+
+            }
+        } else {
+            // dummy settings for unused constants
+            sqr2           = null;
+            sqr2Split      = null;
+            sqr2Reciprocal = null;
+            sqr3           = null;
+            sqr3Reciprocal = null;
+            pi             = null;
+            piSplit        = null;
+            e              = null;
+            eSplit         = null;
+            ln2            = null;
+            ln2Split       = null;
+            ln5            = null;
+            ln5Split       = null;
+            ln10           = null;
+        }
+
+    }
+
+    /** Get the number of radix digits of the {@link Dfp} instances built by this factory.
+     * @return number of radix digits
+     */
+    public int getRadixDigits() {
+        return radixDigits;
+    }
+
+    /** Set the rounding mode.
+     *  If not set, the default value is {@link RoundingMode#ROUND_HALF_EVEN}.
+     * @param mode desired rounding mode
+     * Note that the rounding mode is common to all {@link Dfp} instances
+     * belonging to the current {@link DfpField} in the system and will
+     * affect all future calculations.
+     */
+    public void setRoundingMode(final RoundingMode mode) {
+        rMode = mode;
+    }
+
+    /** Get the current rounding mode.
+     * @return current rounding mode
+     */
+    public RoundingMode getRoundingMode() {
+        return rMode;
+    }
+
+    /** Get the IEEE 854 status flags.
+     * @return IEEE 854 status flags
+     * @see #clearIEEEFlags()
+     * @see #setIEEEFlags(int)
+     * @see #setIEEEFlagsBits(int)
+     * @see #FLAG_INVALID
+     * @see #FLAG_DIV_ZERO
+     * @see #FLAG_OVERFLOW
+     * @see #FLAG_UNDERFLOW
+     * @see #FLAG_INEXACT
+     */
+    public int getIEEEFlags() {
+        return ieeeFlags;
+    }
+
+    /** Clears the IEEE 854 status flags.
+     * @see #getIEEEFlags()
+     * @see #setIEEEFlags(int)
+     * @see #setIEEEFlagsBits(int)
+     * @see #FLAG_INVALID
+     * @see #FLAG_DIV_ZERO
+     * @see #FLAG_OVERFLOW
+     * @see #FLAG_UNDERFLOW
+     * @see #FLAG_INEXACT
+     */
+    public void clearIEEEFlags() {
+        ieeeFlags = 0;
+    }
+
+    /** Sets the IEEE 854 status flags.
+     * @param flags desired value for the flags
+     * @see #getIEEEFlags()
+     * @see #clearIEEEFlags()
+     * @see #setIEEEFlagsBits(int)
+     * @see #FLAG_INVALID
+     * @see #FLAG_DIV_ZERO
+     * @see #FLAG_OVERFLOW
+     * @see #FLAG_UNDERFLOW
+     * @see #FLAG_INEXACT
+     */
+    public void setIEEEFlags(final int flags) {
+        ieeeFlags = flags & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT);
+    }
+
+    /** Sets some bits in the IEEE 854 status flags, without changing the already set bits.
+     * <p>
+     * Calling this method is equivalent to call {@code setIEEEFlags(getIEEEFlags() | bits)}
+     * </p>
+     * @param bits bits to set
+     * @see #getIEEEFlags()
+     * @see #clearIEEEFlags()
+     * @see #setIEEEFlags(int)
+     * @see #FLAG_INVALID
+     * @see #FLAG_DIV_ZERO
+     * @see #FLAG_OVERFLOW
+     * @see #FLAG_UNDERFLOW
+     * @see #FLAG_INEXACT
+     */
+    public void setIEEEFlagsBits(final int bits) {
+        ieeeFlags |= bits & (FLAG_INVALID | FLAG_DIV_ZERO | FLAG_OVERFLOW | FLAG_UNDERFLOW | FLAG_INEXACT);
+    }
+
+    /** Makes a {@link Dfp} with a value of 0.
+     * @return a new {@link Dfp} with a value of 0
+     */
+    public Dfp newDfp() {
+        return new Dfp(this);
+    }
+
+    /** Create an instance from a byte value.
+     * @param x value to convert to an instance
+     * @return a new {@link Dfp} with the same value as x
+     */
+    public Dfp newDfp(final byte x) {
+        return new Dfp(this, x);
+    }
+
+    /** Create an instance from an int value.
+     * @param x value to convert to an instance
+     * @return a new {@link Dfp} with the same value as x
+     */
+    public Dfp newDfp(final int x) {
+        return new Dfp(this, x);
+    }
+
+    /** Create an instance from a long value.
+     * @param x value to convert to an instance
+     * @return a new {@link Dfp} with the same value as x
+     */
+    public Dfp newDfp(final long x) {
+        return new Dfp(this, x);
+    }
+
+    /** Create an instance from a double value.
+     * @param x value to convert to an instance
+     * @return a new {@link Dfp} with the same value as x
+     */
+    public Dfp newDfp(final double x) {
+        return new Dfp(this, x);
+    }
+
+    /** Copy constructor.
+     * @param d instance to copy
+     * @return a new {@link Dfp} with the same value as d
+     */
+    public Dfp newDfp(Dfp d) {
+        return new Dfp(d);
+    }
+
+    /** Create a {@link Dfp} given a String representation.
+     * @param s string representation of the instance
+     * @return a new {@link Dfp} parsed from specified string
+     */
+    public Dfp newDfp(final String s) {
+        return new Dfp(this, s);
+    }
+
+    /** Creates a {@link Dfp} with a non-finite value.
+     * @param sign sign of the Dfp to create
+     * @param nans code of the value, must be one of {@link Dfp#INFINITE},
+     * {@link Dfp#SNAN},  {@link Dfp#QNAN}
+     * @return a new {@link Dfp} with a non-finite value
+     */
+    public Dfp newDfp(final byte sign, final byte nans) {
+        return new Dfp(this, sign, nans);
+    }
+
+    /** Get the constant 0.
+     * @return a {@link Dfp} with value 0
+     */
+    public Dfp getZero() {
+        return zero;
+    }
+
+    /** Get the constant 1.
+     * @return a {@link Dfp} with value 1
+     */
+    public Dfp getOne() {
+        return one;
+    }
+
+    /** Get the constant 2.
+     * @return a {@link Dfp} with value 2
+     */
+    public Dfp getTwo() {
+        return two;
+    }
+
+    /** Get the constant &radic;2.
+     * @return a {@link Dfp} with value &radic;2
+     */
+    public Dfp getSqr2() {
+        return sqr2;
+    }
+
+    /** Get the constant &radic;2 split in two pieces.
+     * @return a {@link Dfp} with value &radic;2 split in two pieces
+     */
+    public Dfp[] getSqr2Split() {
+        return sqr2Split.clone();
+    }
+
+    /** Get the constant &radic;2 / 2.
+     * @return a {@link Dfp} with value &radic;2 / 2
+     */
+    public Dfp getSqr2Reciprocal() {
+        return sqr2Reciprocal;
+    }
+
+    /** Get the constant &radic;3.
+     * @return a {@link Dfp} with value &radic;3
+     */
+    public Dfp getSqr3() {
+        return sqr3;
+    }
+
+    /** Get the constant &radic;3 / 3.
+     * @return a {@link Dfp} with value &radic;3 / 3
+     */
+    public Dfp getSqr3Reciprocal() {
+        return sqr3Reciprocal;
+    }
+
+    /** Get the constant &pi;.
+     * @return a {@link Dfp} with value &pi;
+     */
+    public Dfp getPi() {
+        return pi;
+    }
+
+    /** Get the constant &pi; split in two pieces.
+     * @return a {@link Dfp} with value &pi; split in two pieces
+     */
+    public Dfp[] getPiSplit() {
+        return piSplit.clone();
+    }
+
+    /** Get the constant e.
+     * @return a {@link Dfp} with value e
+     */
+    public Dfp getE() {
+        return e;
+    }
+
+    /** Get the constant e split in two pieces.
+     * @return a {@link Dfp} with value e split in two pieces
+     */
+    public Dfp[] getESplit() {
+        return eSplit.clone();
+    }
+
+    /** Get the constant ln(2).
+     * @return a {@link Dfp} with value ln(2)
+     */
+    public Dfp getLn2() {
+        return ln2;
+    }
+
+    /** Get the constant ln(2) split in two pieces.
+     * @return a {@link Dfp} with value ln(2) split in two pieces
+     */
+    public Dfp[] getLn2Split() {
+        return ln2Split.clone();
+    }
+
+    /** Get the constant ln(5).
+     * @return a {@link Dfp} with value ln(5)
+     */
+    public Dfp getLn5() {
+        return ln5;
+    }
+
+    /** Get the constant ln(5) split in two pieces.
+     * @return a {@link Dfp} with value ln(5) split in two pieces
+     */
+    public Dfp[] getLn5Split() {
+        return ln5Split.clone();
+    }
+
+    /** Get the constant ln(10).
+     * @return a {@link Dfp} with value ln(10)
+     */
+    public Dfp getLn10() {
+        return ln10;
+    }
+
+    /** Breaks a string representation up into two {@link Dfp}'s.
+     * The split is such that the sum of them is equivalent to the input string,
+     * but has higher precision than using a single Dfp.
+     * @param a string representation of the number to split
+     * @return an array of two {@link Dfp Dfp} instances which sum equals a
+     */
+    private Dfp[] split(final String a) {
+      Dfp result[] = new Dfp[2];
+      boolean leading = true;
+      int sp = 0;
+      int sig = 0;
+
+      char[] buf = new char[a.length()];
+
+      for (int i = 0; i < buf.length; i++) {
+        buf[i] = a.charAt(i);
+
+        if (buf[i] >= '1' && buf[i] <= '9') {
+            leading = false;
+        }
+
+        if (buf[i] == '.') {
+          sig += (400 - sig) % 4;
+          leading = false;
+        }
+
+        if (sig == (radixDigits / 2) * 4) {
+          sp = i;
+          break;
+        }
+
+        if (buf[i] >= '0' && buf[i] <= '9' && !leading) {
+            sig ++;
+        }
+      }
+
+      result[0] = new Dfp(this, new String(buf, 0, sp));
+
+      for (int i = 0; i < buf.length; i++) {
+        buf[i] = a.charAt(i);
+        if (buf[i] >= '0' && buf[i] <= '9' && i < sp) {
+            buf[i] = '0';
+        }
+      }
+
+      result[1] = new Dfp(this, new String(buf));
+
+      return result;
+
+    }
+
+    /** Recompute the high precision string constants.
+     * @param highPrecisionDecimalDigits precision at which the string constants mus be computed
+     */
+    private static void computeStringConstants(final int highPrecisionDecimalDigits) {
+        if (sqr2String == null || sqr2String.length() < highPrecisionDecimalDigits - 3) {
+
+            // recompute the string representation of the transcendental constants
+            final DfpField highPrecisionField = new DfpField(highPrecisionDecimalDigits, false);
+            final Dfp highPrecisionOne        = new Dfp(highPrecisionField, 1);
+            final Dfp highPrecisionTwo        = new Dfp(highPrecisionField, 2);
+            final Dfp highPrecisionThree      = new Dfp(highPrecisionField, 3);
+
+            final Dfp highPrecisionSqr2 = highPrecisionTwo.sqrt();
+            sqr2String           = highPrecisionSqr2.toString();
+            sqr2ReciprocalString = highPrecisionOne.divide(highPrecisionSqr2).toString();
+
+            final Dfp highPrecisionSqr3 = highPrecisionThree.sqrt();
+            sqr3String           = highPrecisionSqr3.toString();
+            sqr3ReciprocalString = highPrecisionOne.divide(highPrecisionSqr3).toString();
+
+            piString   = computePi(highPrecisionOne, highPrecisionTwo, highPrecisionThree).toString();
+            eString    = computeExp(highPrecisionOne, highPrecisionOne).toString();
+            ln2String  = computeLn(highPrecisionTwo, highPrecisionOne, highPrecisionTwo).toString();
+            ln5String  = computeLn(new Dfp(highPrecisionField, 5),  highPrecisionOne, highPrecisionTwo).toString();
+            ln10String = computeLn(new Dfp(highPrecisionField, 10), highPrecisionOne, highPrecisionTwo).toString();
+
+        }
+    }
+
+    /** Compute &pi; using Jonathan and Peter Borwein quartic formula.
+     * @param one constant with value 1 at desired precision
+     * @param two constant with value 2 at desired precision
+     * @param three constant with value 3 at desired precision
+     * @return &pi;
+     */
+    private static Dfp computePi(final Dfp one, final Dfp two, final Dfp three) {
+
+        Dfp sqrt2   = two.sqrt();
+        Dfp yk      = sqrt2.subtract(one);
+        Dfp four    = two.add(two);
+        Dfp two2kp3 = two;
+        Dfp ak      = two.multiply(three.subtract(two.multiply(sqrt2)));
+
+        // The formula converges quartically. This means the number of correct
+        // digits is multiplied by 4 at each iteration! Five iterations are
+        // sufficient for about 160 digits, eight iterations give about
+        // 10000 digits (this has been checked) and 20 iterations more than
+        // 160 billions of digits (this has NOT been checked).
+        // So the limit here is considered sufficient for most purposes ...
+        for (int i = 1; i < 20; i++) {
+            final Dfp ykM1 = yk;
+
+            final Dfp y2         = yk.multiply(yk);
+            final Dfp oneMinusY4 = one.subtract(y2.multiply(y2));
+            final Dfp s          = oneMinusY4.sqrt().sqrt();
+            yk = one.subtract(s).divide(one.add(s));
+
+            two2kp3 = two2kp3.multiply(four);
+
+            final Dfp p = one.add(yk);
+            final Dfp p2 = p.multiply(p);
+            ak = ak.multiply(p2.multiply(p2)).subtract(two2kp3.multiply(yk).multiply(one.add(yk).add(yk.multiply(yk))));
+
+            if (yk.equals(ykM1)) {
+                break;
+            }
+        }
+
+        return one.divide(ak);
+
+    }
+
+    /** Compute exp(a).
+     * @param a number for which we want the exponential
+     * @param one constant with value 1 at desired precision
+     * @return exp(a)
+     */
+    public static Dfp computeExp(final Dfp a, final Dfp one) {
+
+        Dfp y  = new Dfp(one);
+        Dfp py = new Dfp(one);
+        Dfp f  = new Dfp(one);
+        Dfp fi = new Dfp(one);
+        Dfp x  = new Dfp(one);
+
+        for (int i = 0; i < 10000; i++) {
+            x = x.multiply(a);
+            y = y.add(x.divide(f));
+            fi = fi.add(one);
+            f = f.multiply(fi);
+            if (y.equals(py)) {
+                break;
+            }
+            py = new Dfp(y);
+        }
+
+        return y;
+
+    }
+
+
+    /** Compute ln(a).
+     *
+     *  Let f(x) = ln(x),
+     *
+     *  We know that f'(x) = 1/x, thus from Taylor's theorem we have:
+     *
+     *           -----          n+1         n
+     *  f(x) =   \           (-1)    (x - 1)
+     *           /          ----------------    for 1 <= n <= infinity
+     *           -----             n
+     *
+     *  or
+     *                       2        3       4
+     *                   (x-1)   (x-1)    (x-1)
+     *  ln(x) =  (x-1) - ----- + ------ - ------ + ...
+     *                     2       3        4
+     *
+     *  alternatively,
+     *
+     *                  2    3   4
+     *                 x    x   x
+     *  ln(x+1) =  x - -  + - - - + ...
+     *                 2    3   4
+     *
+     *  This series can be used to compute ln(x), but it converges too slowly.
+     *
+     *  If we substitute -x for x above, we get
+     *
+     *                   2    3    4
+     *                  x    x    x
+     *  ln(1-x) =  -x - -  - -  - - + ...
+     *                  2    3    4
+     *
+     *  Note that all terms are now negative.  Because the even powered ones
+     *  absorbed the sign.  Now, subtract the series above from the previous
+     *  one to get ln(x+1) - ln(1-x).  Note the even terms cancel out leaving
+     *  only the odd ones
+     *
+     *                             3     5      7
+     *                           2x    2x     2x
+     *  ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ...
+     *                            3     5      7
+     *
+     *  By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have:
+     *
+     *                                3        5        7
+     *      x+1           /          x        x        x          \
+     *  ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  |
+     *      x-1           \          3        5        7          /
+     *
+     *  But now we want to find ln(a), so we need to find the value of x
+     *  such that a = (x+1)/(x-1).   This is easily solved to find that
+     *  x = (a-1)/(a+1).
+     * @param a number for which we want the exponential
+     * @param one constant with value 1 at desired precision
+     * @param two constant with value 2 at desired precision
+     * @return ln(a)
+     */
+
+    public static Dfp computeLn(final Dfp a, final Dfp one, final Dfp two) {
+
+        int den = 1;
+        Dfp x = a.add(new Dfp(a.getField(), -1)).divide(a.add(one));
+
+        Dfp y = new Dfp(x);
+        Dfp num = new Dfp(x);
+        Dfp py = new Dfp(y);
+        for (int i = 0; i < 10000; i++) {
+            num = num.multiply(x);
+            num = num.multiply(x);
+            den = den + 2;
+            Dfp t = num.divide(den);
+            y = y.add(t);
+            if (y.equals(py)) {
+                break;
+            }
+            py = new Dfp(y);
+        }
+
+        return y.multiply(two);
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/dfp/DfpMath.java b/src/main/java/org/apache/commons/math/dfp/DfpMath.java
new file mode 100644
index 0000000..56af1d2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/dfp/DfpMath.java
@@ -0,0 +1,969 @@
+/*
+ * 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.dfp;
+
+/** Mathematical routines for use with {@link Dfp}.
+ * The constants are defined in {@link DfpField}
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ * @since 2.2
+ */
+public class DfpMath {
+
+    /** Name for traps triggered by pow. */
+    private static final String POW_TRAP = "pow";
+
+    /**
+     * Private Constructor.
+     */
+    private DfpMath() {
+    }
+
+    /** Breaks a string representation up into two dfp's.
+     * <p>The two dfp are such that the sum of them is equivalent
+     * to the input string, but has higher precision than using a
+     * single dfp. This is useful for improving accuracy of
+     * exponentiation and critical multiplies.
+     * @param field field to which the Dfp must belong
+     * @param a string representation to split
+     * @return an array of two {@link Dfp} which sum is a
+     */
+    protected static Dfp[] split(final DfpField field, final String a) {
+        Dfp result[] = new Dfp[2];
+        char[] buf;
+        boolean leading = true;
+        int sp = 0;
+        int sig = 0;
+
+        buf = new char[a.length()];
+
+        for (int i = 0; i < buf.length; i++) {
+            buf[i] = a.charAt(i);
+
+            if (buf[i] >= '1' && buf[i] <= '9') {
+                leading = false;
+            }
+
+            if (buf[i] == '.') {
+                sig += (400 - sig) % 4;
+                leading = false;
+            }
+
+            if (sig == (field.getRadixDigits() / 2) * 4) {
+                sp = i;
+                break;
+            }
+
+            if (buf[i] >= '0' && buf[i] <= '9' && !leading) {
+                sig ++;
+            }
+        }
+
+        result[0] = field.newDfp(new String(buf, 0, sp));
+
+        for (int i = 0; i < buf.length; i++) {
+            buf[i] = a.charAt(i);
+            if (buf[i] >= '0' && buf[i] <= '9' && i < sp) {
+                buf[i] = '0';
+            }
+        }
+
+        result[1] = field.newDfp(new String(buf));
+
+        return result;
+    }
+
+    /** Splits a {@link Dfp} into 2 {@link Dfp}'s such that their sum is equal to the input {@link Dfp}.
+     * @param a number to split
+     * @return two elements array containing the split number
+     */
+    protected static Dfp[] split(final Dfp a) {
+        final Dfp[] result = new Dfp[2];
+        final Dfp shift = a.multiply(a.power10K(a.getRadixDigits() / 2));
+        result[0] = a.add(shift).subtract(shift);
+        result[1] = a.subtract(result[0]);
+        return result;
+    }
+
+    /** Multiply two numbers that are split in to two pieces that are
+     *  meant to be added together.
+     *  Use binomial multiplication so ab = a0 b0 + a0 b1 + a1 b0 + a1 b1
+     *  Store the first term in result0, the rest in result1
+     *  @param a first factor of the multiplication, in split form
+     *  @param b second factor of the multiplication, in split form
+     *  @return a &times; b, in split form
+     */
+    protected static Dfp[] splitMult(final Dfp[] a, final Dfp[] b) {
+        final Dfp[] result = new Dfp[2];
+
+        result[1] = a[0].getZero();
+        result[0] = a[0].multiply(b[0]);
+
+        /* If result[0] is infinite or zero, don't compute result[1].
+         * Attempting to do so may produce NaNs.
+         */
+
+        if (result[0].classify() == Dfp.INFINITE || result[0].equals(result[1])) {
+            return result;
+        }
+
+        result[1] = a[0].multiply(b[1]).add(a[1].multiply(b[0])).add(a[1].multiply(b[1]));
+
+        return result;
+    }
+
+    /** Divide two numbers that are split in to two pieces that are meant to be added together.
+     * Inverse of split multiply above:
+     *  (a+b) / (c+d) = (a/c) + ( (bc-ad)/(c**2+cd) )
+     *  @param a dividend, in split form
+     *  @param b divisor, in split form
+     *  @return a / b, in split form
+     */
+    protected static Dfp[] splitDiv(final Dfp[] a, final Dfp[] b) {
+        final Dfp[] result;
+
+        result = new Dfp[2];
+
+        result[0] = a[0].divide(b[0]);
+        result[1] = a[1].multiply(b[0]).subtract(a[0].multiply(b[1]));
+        result[1] = result[1].divide(b[0].multiply(b[0]).add(b[0].multiply(b[1])));
+
+        return result;
+    }
+
+    /** Raise a split base to the a power.
+     * @param base number to raise
+     * @param a power
+     * @return base<sup>a</sup>
+     */
+    protected static Dfp splitPow(final Dfp[] base, int a) {
+        boolean invert = false;
+
+        Dfp[] r = new Dfp[2];
+
+        Dfp[] result = new Dfp[2];
+        result[0] = base[0].getOne();
+        result[1] = base[0].getZero();
+
+        if (a == 0) {
+            // Special case a = 0
+            return result[0].add(result[1]);
+        }
+
+        if (a < 0) {
+            // If a is less than zero
+            invert = true;
+            a = -a;
+        }
+
+        // Exponentiate by successive squaring
+        do {
+            r[0] = new Dfp(base[0]);
+            r[1] = new Dfp(base[1]);
+            int trial = 1;
+
+            int prevtrial;
+            while (true) {
+                prevtrial = trial;
+                trial = trial * 2;
+                if (trial > a) {
+                    break;
+                }
+                r = splitMult(r, r);
+            }
+
+            trial = prevtrial;
+
+            a -= trial;
+            result = splitMult(result, r);
+
+        } while (a >= 1);
+
+        result[0] = result[0].add(result[1]);
+
+        if (invert) {
+            result[0] = base[0].getOne().divide(result[0]);
+        }
+
+        return result[0];
+
+    }
+
+    /** Raises base to the power a by successive squaring.
+     * @param base number to raise
+     * @param a power
+     * @return base<sup>a</sup>
+     */
+    public static Dfp pow(Dfp base, int a)
+    {
+        boolean invert = false;
+
+        Dfp result = base.getOne();
+
+        if (a == 0) {
+            // Special case
+            return result;
+        }
+
+        if (a < 0) {
+            invert = true;
+            a = -a;
+        }
+
+        // Exponentiate by successive squaring
+        do {
+            Dfp r = new Dfp(base);
+            Dfp prevr;
+            int trial = 1;
+            int prevtrial;
+
+            do {
+                prevr = new Dfp(r);
+                prevtrial = trial;
+                r = r.multiply(r);
+                trial = trial * 2;
+            } while (a>trial);
+
+            r = prevr;
+            trial = prevtrial;
+
+            a = a - trial;
+            result = result.multiply(r);
+
+        } while (a >= 1);
+
+        if (invert) {
+            result = base.getOne().divide(result);
+        }
+
+        return base.newInstance(result);
+
+    }
+
+    /** Computes e to the given power.
+     * a is broken into two parts, such that a = n+m  where n is an integer.
+     * We use pow() to compute e<sup>n</sup> and a Taylor series to compute
+     * e<sup>m</sup>.  We return e*<sup>n</sup> &times; e<sup>m</sup>
+     * @param a power at which e should be raised
+     * @return e<sup>a</sup>
+     */
+    public static Dfp exp(final Dfp a) {
+
+        final Dfp inta = a.rint();
+        final Dfp fraca = a.subtract(inta);
+
+        final int ia = inta.intValue();
+        if (ia > 2147483646) {
+            // return +Infinity
+            return a.newInstance((byte)1, Dfp.INFINITE);
+        }
+
+        if (ia < -2147483646) {
+            // return 0;
+            return a.newInstance();
+        }
+
+        final Dfp einta = splitPow(a.getField().getESplit(), ia);
+        final Dfp efraca = expInternal(fraca);
+
+        return einta.multiply(efraca);
+    }
+
+    /** Computes e to the given power.
+     * Where -1 < a < 1.  Use the classic Taylor series.  1 + x**2/2! + x**3/3! + x**4/4!  ...
+     * @param a power at which e should be raised
+     * @return e<sup>a</sup>
+     */
+    protected static Dfp expInternal(final Dfp a) {
+        Dfp y = a.getOne();
+        Dfp x = a.getOne();
+        Dfp fact = a.getOne();
+        Dfp py = new Dfp(y);
+
+        for (int i = 1; i < 90; i++) {
+            x = x.multiply(a);
+            fact = fact.divide(i);
+            y = y.add(x.multiply(fact));
+            if (y.equals(py)) {
+                break;
+            }
+            py = new Dfp(y);
+        }
+
+        return y;
+    }
+
+    /** Returns the natural logarithm of a.
+     * a is first split into three parts such that  a = (10000^h)(2^j)k.
+     * ln(a) is computed by ln(a) = ln(5)*h + ln(2)*(h+j) + ln(k)
+     * k is in the range 2/3 < k <4/3 and is passed on to a series expansion.
+     * @param a number from which logarithm is requested
+     * @return log(a)
+     */
+    public static Dfp log(Dfp a) {
+        int lr;
+        Dfp x;
+        int ix;
+        int p2 = 0;
+
+        // Check the arguments somewhat here
+        if (a.equals(a.getZero()) || a.lessThan(a.getZero()) || a.isNaN()) {
+            // negative, zero or NaN
+            a.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            return a.dotrap(DfpField.FLAG_INVALID, "ln", a, a.newInstance((byte)1, Dfp.QNAN));
+        }
+
+        if (a.classify() == Dfp.INFINITE) {
+            return a;
+        }
+
+        x = new Dfp(a);
+        lr = x.log10K();
+
+        x = x.divide(pow(a.newInstance(10000), lr));  /* This puts x in the range 0-10000 */
+        ix = x.floor().intValue();
+
+        while (ix > 2) {
+            ix >>= 1;
+            p2++;
+        }
+
+
+        Dfp[] spx = split(x);
+        Dfp[] spy = new Dfp[2];
+        spy[0] = pow(a.getTwo(), p2);          // use spy[0] temporarily as a divisor
+        spx[0] = spx[0].divide(spy[0]);
+        spx[1] = spx[1].divide(spy[0]);
+
+        spy[0] = a.newInstance("1.33333");    // Use spy[0] for comparison
+        while (spx[0].add(spx[1]).greaterThan(spy[0])) {
+            spx[0] = spx[0].divide(2);
+            spx[1] = spx[1].divide(2);
+            p2++;
+        }
+
+        // X is now in the range of 2/3 < x < 4/3
+        Dfp[] spz = logInternal(spx);
+
+        spx[0] = a.newInstance(new StringBuilder().append(p2+4*lr).toString());
+        spx[1] = a.getZero();
+        spy = splitMult(a.getField().getLn2Split(), spx);
+
+        spz[0] = spz[0].add(spy[0]);
+        spz[1] = spz[1].add(spy[1]);
+
+        spx[0] = a.newInstance(new StringBuilder().append(4*lr).toString());
+        spx[1] = a.getZero();
+        spy = splitMult(a.getField().getLn5Split(), spx);
+
+        spz[0] = spz[0].add(spy[0]);
+        spz[1] = spz[1].add(spy[1]);
+
+        return a.newInstance(spz[0].add(spz[1]));
+
+    }
+
+    /** Computes the natural log of a number between 0 and 2.
+     *  Let f(x) = ln(x),
+     *
+     *  We know that f'(x) = 1/x, thus from Taylor's theorum we have:
+     *
+     *           -----          n+1         n
+     *  f(x) =   \           (-1)    (x - 1)
+     *           /          ----------------    for 1 <= n <= infinity
+     *           -----             n
+     *
+     *  or
+     *                       2        3       4
+     *                   (x-1)   (x-1)    (x-1)
+     *  ln(x) =  (x-1) - ----- + ------ - ------ + ...
+     *                     2       3        4
+     *
+     *  alternatively,
+     *
+     *                  2    3   4
+     *                 x    x   x
+     *  ln(x+1) =  x - -  + - - - + ...
+     *                 2    3   4
+     *
+     *  This series can be used to compute ln(x), but it converges too slowly.
+     *
+     *  If we substitute -x for x above, we get
+     *
+     *                   2    3    4
+     *                  x    x    x
+     *  ln(1-x) =  -x - -  - -  - - + ...
+     *                  2    3    4
+     *
+     *  Note that all terms are now negative.  Because the even powered ones
+     *  absorbed the sign.  Now, subtract the series above from the previous
+     *  one to get ln(x+1) - ln(1-x).  Note the even terms cancel out leaving
+     *  only the odd ones
+     *
+     *                             3     5      7
+     *                           2x    2x     2x
+     *  ln(x+1) - ln(x-1) = 2x + --- + --- + ---- + ...
+     *                            3     5      7
+     *
+     *  By the property of logarithms that ln(a) - ln(b) = ln (a/b) we have:
+     *
+     *                                3        5        7
+     *      x+1           /          x        x        x          \
+     *  ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  |
+     *      x-1           \          3        5        7          /
+     *
+     *  But now we want to find ln(a), so we need to find the value of x
+     *  such that a = (x+1)/(x-1).   This is easily solved to find that
+     *  x = (a-1)/(a+1).
+     * @param a number from which logarithm is requested, in split form
+     * @return log(a)
+     */
+    protected static Dfp[] logInternal(final Dfp a[]) {
+
+        /* Now we want to compute x = (a-1)/(a+1) but this is prone to
+         * loss of precision.  So instead, compute x = (a/4 - 1/4) / (a/4 + 1/4)
+         */
+        Dfp t = a[0].divide(4).add(a[1].divide(4));
+        Dfp x = t.add(a[0].newInstance("-0.25")).divide(t.add(a[0].newInstance("0.25")));
+
+        Dfp y = new Dfp(x);
+        Dfp num = new Dfp(x);
+        Dfp py = new Dfp(y);
+        int den = 1;
+        for (int i = 0; i < 10000; i++) {
+            num = num.multiply(x);
+            num = num.multiply(x);
+            den = den + 2;
+            t = num.divide(den);
+            y = y.add(t);
+            if (y.equals(py)) {
+                break;
+            }
+            py = new Dfp(y);
+        }
+
+        y = y.multiply(a[0].getTwo());
+
+        return split(y);
+
+    }
+
+    /** Computes x to the y power.<p>
+     *
+     *  Uses the following method:<p>
+     *
+     *  <ol>
+     *  <li> Set u = rint(y), v = y-u
+     *  <li> Compute a = v * ln(x)
+     *  <li> Compute b = rint( a/ln(2) )
+     *  <li> Compute c = a - b*ln(2)
+     *  <li> x<sup>y</sup> = x<sup>u</sup>  *   2<sup>b</sup> * e<sup>c</sup>
+     *  </ol>
+     *  if |y| > 1e8, then we compute by exp(y*ln(x))   <p>
+     *
+     *  <b>Special Cases</b><p>
+     *  <ul>
+     *  <li>  if y is 0.0 or -0.0 then result is 1.0
+     *  <li>  if y is 1.0 then result is x
+     *  <li>  if y is NaN then result is NaN
+     *  <li>  if x is NaN and y is not zero then result is NaN
+     *  <li>  if |x| > 1.0 and y is +Infinity then result is +Infinity
+     *  <li>  if |x| < 1.0 and y is -Infinity then result is +Infinity
+     *  <li>  if |x| > 1.0 and y is -Infinity then result is +0
+     *  <li>  if |x| < 1.0 and y is +Infinity then result is +0
+     *  <li>  if |x| = 1.0 and y is +/-Infinity then result is NaN
+     *  <li>  if x = +0 and y > 0 then result is +0
+     *  <li>  if x = +Inf and y < 0 then result is +0
+     *  <li>  if x = +0 and y < 0 then result is +Inf
+     *  <li>  if x = +Inf and y > 0 then result is +Inf
+     *  <li>  if x = -0 and y > 0, finite, not odd integer then result is +0
+     *  <li>  if x = -0 and y < 0, finite, and odd integer then result is -Inf
+     *  <li>  if x = -Inf and y > 0, finite, and odd integer then result is -Inf
+     *  <li>  if x = -0 and y < 0, not finite odd integer then result is +Inf
+     *  <li>  if x = -Inf and y > 0, not finite odd integer then result is +Inf
+     *  <li>  if x < 0 and y > 0, finite, and odd integer then result is -(|x|<sup>y</sup>)
+     *  <li>  if x < 0 and y > 0, finite, and not integer then result is NaN
+     *  </ul>
+     *  @param x base to be raised
+     *  @param y power to which base should be raised
+     *  @return x<sup>y</sup>
+     */
+    public static Dfp pow(Dfp x, final Dfp y) {
+
+        // make sure we don't mix number with different precision
+        if (x.getField().getRadixDigits() != y.getField().getRadixDigits()) {
+            x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            final Dfp result = x.newInstance(x.getZero());
+            result.nans = Dfp.QNAN;
+            return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, result);
+        }
+
+        final Dfp zero = x.getZero();
+        final Dfp one  = x.getOne();
+        final Dfp two  = x.getTwo();
+        boolean invert = false;
+        int ui;
+
+        /* Check for special cases */
+        if (y.equals(zero)) {
+            return x.newInstance(one);
+        }
+
+        if (y.equals(one)) {
+            if (x.isNaN()) {
+                // Test for NaNs
+                x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+                return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x);
+            }
+            return x;
+        }
+
+        if (x.isNaN() || y.isNaN()) {
+            // Test for NaNs
+            x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x.newInstance((byte)1, Dfp.QNAN));
+        }
+
+        // X == 0
+        if (x.equals(zero)) {
+            if (Dfp.copysign(one, x).greaterThan(zero)) {
+                // X == +0
+                if (y.greaterThan(zero)) {
+                    return x.newInstance(zero);
+                } else {
+                    return x.newInstance(x.newInstance((byte)1, Dfp.INFINITE));
+                }
+            } else {
+                // X == -0
+                if (y.classify() == Dfp.FINITE && y.rint().equals(y) && !y.remainder(two).equals(zero)) {
+                    // If y is odd integer
+                    if (y.greaterThan(zero)) {
+                        return x.newInstance(zero.negate());
+                    } else {
+                        return x.newInstance(x.newInstance((byte)-1, Dfp.INFINITE));
+                    }
+                } else {
+                    // Y is not odd integer
+                    if (y.greaterThan(zero)) {
+                        return x.newInstance(zero);
+                    } else {
+                        return x.newInstance(x.newInstance((byte)1, Dfp.INFINITE));
+                    }
+                }
+            }
+        }
+
+        if (x.lessThan(zero)) {
+            // Make x positive, but keep track of it
+            x = x.negate();
+            invert = true;
+        }
+
+        if (x.greaterThan(one) && y.classify() == Dfp.INFINITE) {
+            if (y.greaterThan(zero)) {
+                return y;
+            } else {
+                return x.newInstance(zero);
+            }
+        }
+
+        if (x.lessThan(one) && y.classify() == Dfp.INFINITE) {
+            if (y.greaterThan(zero)) {
+                return x.newInstance(zero);
+            } else {
+                return x.newInstance(Dfp.copysign(y, one));
+            }
+        }
+
+        if (x.equals(one) && y.classify() == Dfp.INFINITE) {
+            x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x.newInstance((byte)1, Dfp.QNAN));
+        }
+
+        if (x.classify() == Dfp.INFINITE) {
+            // x = +/- inf
+            if (invert) {
+                // negative infinity
+                if (y.classify() == Dfp.FINITE && y.rint().equals(y) && !y.remainder(two).equals(zero)) {
+                    // If y is odd integer
+                    if (y.greaterThan(zero)) {
+                        return x.newInstance(x.newInstance((byte)-1, Dfp.INFINITE));
+                    } else {
+                        return x.newInstance(zero.negate());
+                    }
+                } else {
+                    // Y is not odd integer
+                    if (y.greaterThan(zero)) {
+                        return x.newInstance(x.newInstance((byte)1, Dfp.INFINITE));
+                    } else {
+                        return x.newInstance(zero);
+                    }
+                }
+            } else {
+                // positive infinity
+                if (y.greaterThan(zero)) {
+                    return x;
+                } else {
+                    return x.newInstance(zero);
+                }
+            }
+        }
+
+        if (invert && !y.rint().equals(y)) {
+            x.getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
+            return x.dotrap(DfpField.FLAG_INVALID, POW_TRAP, x, x.newInstance((byte)1, Dfp.QNAN));
+        }
+
+        // End special cases
+
+        Dfp r;
+        if (y.lessThan(x.newInstance(100000000)) && y.greaterThan(x.newInstance(-100000000))) {
+            final Dfp u = y.rint();
+            ui = u.intValue();
+
+            final Dfp v = y.subtract(u);
+
+            if (v.unequal(zero)) {
+                final Dfp a = v.multiply(log(x));
+                final Dfp b = a.divide(x.getField().getLn2()).rint();
+
+                final Dfp c = a.subtract(b.multiply(x.getField().getLn2()));
+                r = splitPow(split(x), ui);
+                r = r.multiply(pow(two, b.intValue()));
+                r = r.multiply(exp(c));
+            } else {
+                r = splitPow(split(x), ui);
+            }
+        } else {
+            // very large exponent.  |y| > 1e8
+            r = exp(log(x).multiply(y));
+        }
+
+        if (invert) {
+            // if y is odd integer
+            if (y.rint().equals(y) && !y.remainder(two).equals(zero)) {
+                r = r.negate();
+            }
+        }
+
+        return x.newInstance(r);
+
+    }
+
+    /** Computes sin(a)  Used when 0 < a < pi/4.
+     * Uses the classic Taylor series.  x - x**3/3! + x**5/5!  ...
+     * @param a number from which sine is desired, in split form
+     * @return sin(a)
+     */
+    protected static Dfp sinInternal(Dfp a[]) {
+
+        Dfp c = a[0].add(a[1]);
+        Dfp y = c;
+        c = c.multiply(c);
+        Dfp x = y;
+        Dfp fact = a[0].getOne();
+        Dfp py = new Dfp(y);
+
+        for (int i = 3; i < 90; i += 2) {
+            x = x.multiply(c);
+            x = x.negate();
+
+            fact = fact.divide((i-1)*i);  // 1 over fact
+            y = y.add(x.multiply(fact));
+            if (y.equals(py))
+                break;
+            py = new Dfp(y);
+        }
+
+        return y;
+
+    }
+
+    /** Computes cos(a)  Used when 0 < a < pi/4.
+     * Uses the classic Taylor series for cosine.  1 - x**2/2! + x**4/4!  ...
+     * @param a number from which cosine is desired, in split form
+     * @return cos(a)
+     */
+    protected static Dfp cosInternal(Dfp a[]) {
+        final Dfp one = a[0].getOne();
+
+
+        Dfp x = one;
+        Dfp y = one;
+        Dfp c = a[0].add(a[1]);
+        c = c.multiply(c);
+
+        Dfp fact = one;
+        Dfp py = new Dfp(y);
+
+        for (int i = 2; i < 90; i += 2) {
+            x = x.multiply(c);
+            x = x.negate();
+
+            fact = fact.divide((i - 1) * i);  // 1 over fact
+
+            y = y.add(x.multiply(fact));
+            if (y.equals(py)) {
+                break;
+            }
+            py = new Dfp(y);
+        }
+
+        return y;
+
+    }
+
+    /** computes the sine of the argument.
+     * @param a number from which sine is desired
+     * @return sin(a)
+     */
+    public static Dfp sin(final Dfp a) {
+        final Dfp pi = a.getField().getPi();
+        final Dfp zero = a.getField().getZero();
+        boolean neg = false;
+
+        /* First reduce the argument to the range of +/- PI */
+        Dfp x = a.remainder(pi.multiply(2));
+
+        /* if x < 0 then apply identity sin(-x) = -sin(x) */
+        /* This puts x in the range 0 < x < PI            */
+        if (x.lessThan(zero)) {
+            x = x.negate();
+            neg = true;
+        }
+
+        /* Since sine(x) = sine(pi - x) we can reduce the range to
+         * 0 < x < pi/2
+         */
+
+        if (x.greaterThan(pi.divide(2))) {
+            x = pi.subtract(x);
+        }
+
+        Dfp y;
+        if (x.lessThan(pi.divide(4))) {
+            Dfp c[] = new Dfp[2];
+            c[0] = x;
+            c[1] = zero;
+
+            //y = sinInternal(c);
+            y = sinInternal(split(x));
+        } else {
+            final Dfp c[] = new Dfp[2];
+            final Dfp[] piSplit = a.getField().getPiSplit();
+            c[0] = piSplit[0].divide(2).subtract(x);
+            c[1] = piSplit[1].divide(2);
+            y = cosInternal(c);
+        }
+
+        if (neg) {
+            y = y.negate();
+        }
+
+        return a.newInstance(y);
+
+    }
+
+    /** computes the cosine of the argument.
+     * @param a number from which cosine is desired
+     * @return cos(a)
+     */
+    public static Dfp cos(Dfp a) {
+        final Dfp pi = a.getField().getPi();
+        final Dfp zero = a.getField().getZero();
+        boolean neg = false;
+
+        /* First reduce the argument to the range of +/- PI */
+        Dfp x = a.remainder(pi.multiply(2));
+
+        /* if x < 0 then apply identity cos(-x) = cos(x) */
+        /* This puts x in the range 0 < x < PI           */
+        if (x.lessThan(zero)) {
+            x = x.negate();
+        }
+
+        /* Since cos(x) = -cos(pi - x) we can reduce the range to
+         * 0 < x < pi/2
+         */
+
+        if (x.greaterThan(pi.divide(2))) {
+            x = pi.subtract(x);
+            neg = true;
+        }
+
+        Dfp y;
+        if (x.lessThan(pi.divide(4))) {
+            Dfp c[] = new Dfp[2];
+            c[0] = x;
+            c[1] = zero;
+
+            y = cosInternal(c);
+        } else {
+            final Dfp c[] = new Dfp[2];
+            final Dfp[] piSplit = a.getField().getPiSplit();
+            c[0] = piSplit[0].divide(2).subtract(x);
+            c[1] = piSplit[1].divide(2);
+            y = sinInternal(c);
+        }
+
+        if (neg) {
+            y = y.negate();
+        }
+
+        return a.newInstance(y);
+
+    }
+
+    /** computes the tangent of the argument.
+     * @param a number from which tangent is desired
+     * @return tan(a)
+     */
+    public static Dfp tan(final Dfp a) {
+        return sin(a).divide(cos(a));
+    }
+
+    /** computes the arc-tangent of the argument.
+     * @param a number from which arc-tangent is desired
+     * @return atan(a)
+     */
+    protected static Dfp atanInternal(final Dfp a) {
+
+        Dfp y = new Dfp(a);
+        Dfp x = new Dfp(y);
+        Dfp py = new Dfp(y);
+
+        for (int i = 3; i < 90; i += 2) {
+            x = x.multiply(a);
+            x = x.multiply(a);
+            x = x.negate();
+            y = y.add(x.divide(i));
+            if (y.equals(py)) {
+                break;
+            }
+            py = new Dfp(y);
+        }
+
+        return y;
+
+    }
+
+    /** computes the arc tangent of the argument
+     *
+     *  Uses the typical taylor series
+     *
+     *  but may reduce arguments using the following identity
+     * tan(x+y) = (tan(x) + tan(y)) / (1 - tan(x)*tan(y))
+     *
+     * since tan(PI/8) = sqrt(2)-1,
+     *
+     * atan(x) = atan( (x - sqrt(2) + 1) / (1+x*sqrt(2) - x) + PI/8.0
+     * @param a number from which arc-tangent is desired
+     * @return atan(a)
+     */
+    public static Dfp atan(final Dfp a) {
+        final Dfp   zero      = a.getField().getZero();
+        final Dfp   one       = a.getField().getOne();
+        final Dfp[] sqr2Split = a.getField().getSqr2Split();
+        final Dfp[] piSplit   = a.getField().getPiSplit();
+        boolean recp = false;
+        boolean neg = false;
+        boolean sub = false;
+
+        final Dfp ty = sqr2Split[0].subtract(one).add(sqr2Split[1]);
+
+        Dfp x = new Dfp(a);
+        if (x.lessThan(zero)) {
+            neg = true;
+            x = x.negate();
+        }
+
+        if (x.greaterThan(one)) {
+            recp = true;
+            x = one.divide(x);
+        }
+
+        if (x.greaterThan(ty)) {
+            Dfp sty[] = new Dfp[2];
+            sub = true;
+
+            sty[0] = sqr2Split[0].subtract(one);
+            sty[1] = sqr2Split[1];
+
+            Dfp[] xs = split(x);
+
+            Dfp[] ds = splitMult(xs, sty);
+            ds[0] = ds[0].add(one);
+
+            xs[0] = xs[0].subtract(sty[0]);
+            xs[1] = xs[1].subtract(sty[1]);
+
+            xs = splitDiv(xs, ds);
+            x = xs[0].add(xs[1]);
+
+            //x = x.subtract(ty).divide(dfp.one.add(x.multiply(ty)));
+        }
+
+        Dfp y = atanInternal(x);
+
+        if (sub) {
+            y = y.add(piSplit[0].divide(8)).add(piSplit[1].divide(8));
+        }
+
+        if (recp) {
+            y = piSplit[0].divide(2).subtract(y).add(piSplit[1].divide(2));
+        }
+
+        if (neg) {
+            y = y.negate();
+        }
+
+        return a.newInstance(y);
+
+    }
+
+    /** computes the arc-sine of the argument.
+     * @param a number from which arc-sine is desired
+     * @return asin(a)
+     */
+    public static Dfp asin(final Dfp a) {
+        return atan(a.divide(a.getOne().subtract(a.multiply(a)).sqrt()));
+    }
+
+    /** computes the arc-cosine of the argument.
+     * @param a number from which arc-cosine is desired
+     * @return acos(a)
+     */
+    public static Dfp acos(Dfp a) {
+        Dfp result;
+        boolean negative = false;
+
+        if (a.lessThan(a.getZero())) {
+            negative = true;
+        }
+
+        a = Dfp.copysign(a, a.getOne());  // absolute value
+
+        result = atan(a.getOne().subtract(a.multiply(a)).sqrt().divide(a));
+
+        if (negative) {
+            result = a.getField().getPi().subtract(result);
+        }
+
+        return a.newInstance(result);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/dfp/package.html b/src/main/java/org/apache/commons/math/dfp/package.html
new file mode 100644
index 0000000..f63dd6e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/dfp/package.html
@@ -0,0 +1,88 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 992696 $ $Date: 2010-09-05 00:57:31 +0200 (dim. 05 sept. 2010) $ -->
+    <body>
+Decimal floating point library for Java
+
+<p>Another floating point class.  This one is built using radix 10000
+which is 10<sup>4</sup>, so its almost decimal.</p>
+
+<p>The design goals here are:
+<ol>
+  <li>Decimal math, or close to it</li>
+  <li>Settable precision (but no mix between numbers using different settings)</li>
+  <li>Portability.  Code should be keep as portable as possible.</li>
+  <li>Performance</li>
+  <li>Accuracy  - Results should always be +/- 1 ULP for basic
+       algebraic operation</li>
+  <li>Comply with IEEE 854-1987 as much as possible.
+       (See IEEE 854-1987 notes below)</li>
+</ol></p>
+
+<p>Trade offs:
+<ol>
+  <li>Memory foot print.  I'm using more memory than necessary to
+       represent numbers to get better performance.</li>
+  <li>Digits are bigger, so rounding is a greater loss.  So, if you
+       really need 12 decimal digits, better use 4 base 10000 digits
+       there can be one partially filled.</li>
+</ol></p>
+
+<p>Numbers are represented  in the following form:
+<pre>
+n  =  sign &times; mant &times; (radix)<sup>exp</sup>;</p>
+</pre>
+where sign is &plusmn;1, mantissa represents a fractional number between
+zero and one.  mant[0] is the least significant digit.
+exp is in the range of -32767 to 32768</p>
+
+<p>IEEE 854-1987  Notes and differences</p>
+
+<p>IEEE 854 requires the radix to be either 2 or 10.  The radix here is
+10000, so that requirement is not met, but  it is possible that a
+subclassed can be made to make it behave as a radix 10
+number.  It is my opinion that if it looks and behaves as a radix
+10 number then it is one and that requirement would be met.</p>
+
+<p>The radix of 10000 was chosen because it should be faster to operate
+on 4 decimal digits at once instead of one at a time.  Radix 10 behavior
+can be realized by add an additional rounding step to ensure that
+the number of decimal digits represented is constant.</p>
+
+<p>The IEEE standard specifically leaves out internal data encoding,
+so it is reasonable to conclude that such a subclass of this radix
+10000 system is merely an encoding of a radix 10 system.</p>
+
+<p>IEEE 854 also specifies the existence of "sub-normal" numbers.  This
+class does not contain any such entities.  The most significant radix
+10000 digit is always non-zero.  Instead, we support "gradual underflow"
+by raising the underflow flag for numbers less with exponent less than
+expMin, but don't flush to zero until the exponent reaches MIN_EXP-digits.
+Thus the smallest number we can represent would be:
+1E(-(MIN_EXP-digits-1)*4),  eg, for digits=5, MIN_EXP=-32767, that would
+be 1e-131092.</p>
+
+<p>IEEE 854 defines that the implied radix point lies just to the right
+of the most significant digit and to the left of the remaining digits.
+This implementation puts the implied radix point to the left of all
+digits including the most significant one.  The most significant digit
+here is the one just to the right of the radix point.  This is a fine
+detail and is really only a matter of definition.  Any side effects of
+this can be rendered invisible by a subclass.</p>
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java b/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
new file mode 100644
index 0000000..aaa2efd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
@@ -0,0 +1,231 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.solvers.BrentSolver;
+import org.apache.commons.math.analysis.solvers.UnivariateRealSolverUtils;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomDataImpl;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Base class for continuous distributions.  Default implementations are
+ * provided for some of the methods that do not vary from distribution to
+ * distribution.
+ *
+ * @version $Revision: 1073498 $ $Date: 2011-02-22 21:57:26 +0100 (mar. 22 févr. 2011) $
+ */
+public abstract class AbstractContinuousDistribution
+    extends AbstractDistribution
+    implements ContinuousDistribution, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -38038050983108802L;
+
+    /**
+     * RandomData instance used to generate samples from the distribution
+     * @since 2.2
+     */
+    protected final RandomDataImpl randomData = new RandomDataImpl();
+
+    /**
+     * Solver absolute accuracy for inverse cumulative computation
+     * @since 2.1
+     */
+    private double solverAbsoluteAccuracy = BrentSolver.DEFAULT_ABSOLUTE_ACCURACY;
+
+    /**
+     * Default constructor.
+     */
+    protected AbstractContinuousDistribution() {
+        super();
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     * @param x  The point at which the density should be computed.
+     * @return  The pdf at point x.
+     * @throws MathRuntimeException if the specialized class hasn't implemented this function
+     * @since 2.1
+     */
+    public double density(double x) throws MathRuntimeException {
+        throw new MathRuntimeException(new UnsupportedOperationException(),
+                LocalizedFormats.NO_DENSITY_FOR_THIS_DISTRIBUTION);
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    public double inverseCumulativeProbability(final double p)
+        throws MathException {
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        }
+
+        // by default, do simple root finding using bracketing and default solver.
+        // subclasses can override if there is a better method.
+        UnivariateRealFunction rootFindingFunction =
+            new UnivariateRealFunction() {
+            public double value(double x) throws FunctionEvaluationException {
+                double ret = Double.NaN;
+                try {
+                    ret = cumulativeProbability(x) - p;
+                } catch (MathException ex) {
+                    throw new FunctionEvaluationException(x, ex.getSpecificPattern(), ex.getGeneralPattern(), ex.getArguments());
+                }
+                if (Double.isNaN(ret)) {
+                    throw new FunctionEvaluationException(x, LocalizedFormats.CUMULATIVE_PROBABILITY_RETURNED_NAN, x, p);
+                }
+                return ret;
+            }
+        };
+
+        // Try to bracket root, test domain endpoints if this fails
+        double lowerBound = getDomainLowerBound(p);
+        double upperBound = getDomainUpperBound(p);
+        double[] bracket = null;
+        try {
+            bracket = UnivariateRealSolverUtils.bracket(
+                    rootFindingFunction, getInitialDomain(p),
+                    lowerBound, upperBound);
+        }  catch (ConvergenceException ex) {
+            /*
+             * Check domain endpoints to see if one gives value that is within
+             * the default solver's defaultAbsoluteAccuracy of 0 (will be the
+             * case if density has bounded support and p is 0 or 1).
+             */
+            if (FastMath.abs(rootFindingFunction.value(lowerBound)) < getSolverAbsoluteAccuracy()) {
+                return lowerBound;
+            }
+            if (FastMath.abs(rootFindingFunction.value(upperBound)) < getSolverAbsoluteAccuracy()) {
+                return upperBound;
+            }
+            // Failed bracket convergence was not because of corner solution
+            throw new MathException(ex);
+        }
+
+        // find root
+        double root = UnivariateRealSolverUtils.solve(rootFindingFunction,
+                // override getSolverAbsoluteAccuracy() to use a Brent solver with
+                // absolute accuracy different from BrentSolver default
+                bracket[0],bracket[1], getSolverAbsoluteAccuracy());
+        return root;
+    }
+
+    /**
+     * Reseeds the random generator used to generate samples.
+     *
+     * @param seed the new seed
+     * @since 2.2
+     */
+    public void reseedRandomGenerator(long seed) {
+        randomData.reSeed(seed);
+    }
+
+    /**
+     * Generates a random value sampled from this distribution. The default
+     * implementation uses the
+     * <a href="http://en.wikipedia.org/wiki/Inverse_transform_sampling"> inversion method.</a>
+     *
+     * @return random value
+     * @since 2.2
+     * @throws MathException if an error occurs generating the random value
+     */
+    public double sample() throws MathException {
+        return randomData.nextInversionDeviate(this);
+    }
+
+    /**
+     * Generates a random sample from the distribution.  The default implementation
+     * generates the sample by calling {@link #sample()} in a loop.
+     *
+     * @param sampleSize number of random values to generate
+     * @since 2.2
+     * @return an array representing the random sample
+     * @throws MathException if an error occurs generating the sample
+     * @throws IllegalArgumentException if sampleSize is not positive
+     */
+    public double[] sample(int sampleSize) throws MathException {
+        if (sampleSize <= 0) {
+            MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, sampleSize);
+        }
+        double[] out = new double[sampleSize];
+        for (int i = 0; i < sampleSize; i++) {
+            out[i] = sample();
+        }
+        return out;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    protected abstract double getInitialDomain(double p);
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    protected abstract double getDomainLowerBound(double p);
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    protected abstract double getDomainUpperBound(double p);
+
+    /**
+     * Returns the solver absolute accuracy for inverse cumulative computation.
+     *
+     * @return the maximum absolute error in inverse cumulative probability estimates
+     * @since 2.1
+     */
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java b/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java
new file mode 100644
index 0000000..c32ba29
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/AbstractDistribution.java
@@ -0,0 +1,69 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Base class for probability distributions.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public abstract class AbstractDistribution
+    implements Distribution, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -38038050983108802L;
+
+    /**
+     * Default constructor.
+     */
+    protected AbstractDistribution() {
+        super();
+    }
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(x0 &le; X &le; x1).
+     * <p>
+     * The default implementation uses the identity</p>
+     * <p>
+     * P(x0 &le; X &le; x1) = P(X &le; x1) - P(X &le; x0) </p>
+     *
+     * @param x0 the (inclusive) lower bound
+     * @param x1 the (inclusive) upper bound
+     * @return the probability that a random variable with this distribution
+     * will take a value between <code>x0</code> and <code>x1</code>,
+     * including the endpoints.
+     * @throws MathException if the cumulative probability can not be
+     * computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>x0 > x1</code>
+     */
+    public double cumulativeProbability(double x0, double x1)
+        throws MathException {
+        if (x0 > x1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT,
+                  x0, x1);
+        }
+        return cumulativeProbability(x1) - cumulativeProbability(x0);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java b/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
new file mode 100644
index 0000000..96cfe5d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
@@ -0,0 +1,319 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomDataImpl;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Base class for integer-valued discrete distributions.  Default
+ * implementations are provided for some of the methods that do not vary
+ * from distribution to distribution.
+ *
+ * @version $Revision: 1067494 $ $Date: 2011-02-05 20:49:07 +0100 (sam. 05 févr. 2011) $
+ */
+public abstract class AbstractIntegerDistribution extends AbstractDistribution
+    implements IntegerDistribution, Serializable {
+
+   /** Serializable version identifier */
+    private static final long serialVersionUID = -1146319659338487221L;
+
+    /**
+     * RandomData instance used to generate samples from the distribution
+     * @since 2.2
+     */
+    protected final RandomDataImpl randomData = new RandomDataImpl();
+
+    /**
+     * Default constructor.
+     */
+    protected AbstractIntegerDistribution() {
+        super();
+    }
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X &le; x).  In other words,
+     * this method represents the  (cumulative) distribution function, or
+     * CDF, for this distribution.
+     * <p>
+     * If <code>x</code> does not represent an integer value, the CDF is
+     * evaluated at the greatest integer less than x.
+     *
+     * @param x the value at which the distribution function is evaluated.
+     * @return cumulative probability that a random variable with this
+     * distribution takes a value less than or equal to <code>x</code>
+     * @throws MathException if the cumulative probability can not be
+     * computed due to convergence or other numerical errors.
+     */
+    public double cumulativeProbability(double x) throws MathException {
+        return cumulativeProbability((int) FastMath.floor(x));
+    }
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(x0 &le; X &le; x1).
+     *
+     * @param x0 the (inclusive) lower bound
+     * @param x1 the (inclusive) upper bound
+     * @return the probability that a random variable with this distribution
+     * will take a value between <code>x0</code> and <code>x1</code>,
+     * including the endpoints.
+     * @throws MathException if the cumulative probability can not be
+     * computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>x0 > x1</code>
+     */
+    @Override
+    public double cumulativeProbability(double x0, double x1)
+        throws MathException {
+        if (x0 > x1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1);
+        }
+        if (FastMath.floor(x0) < x0) {
+            return cumulativeProbability(((int) FastMath.floor(x0)) + 1,
+               (int) FastMath.floor(x1)); // don't want to count mass below x0
+        } else { // x0 is mathematical integer, so use as is
+            return cumulativeProbability((int) FastMath.floor(x0),
+                (int) FastMath.floor(x1));
+        }
+    }
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X &le; x).  In other words,
+     * this method represents the probability distribution function, or PDF,
+     * for this distribution.
+     *
+     * @param x the value at which the PDF is evaluated.
+     * @return PDF for this distribution.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    public abstract double cumulativeProbability(int x) throws MathException;
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X = x). In other words, this
+     * method represents the probability mass function,  or PMF, for the distribution.
+     * <p>
+     * If <code>x</code> does not represent an integer value, 0 is returned.
+     *
+     * @param x the value at which the probability density function is evaluated
+     * @return the value of the probability density function at x
+     */
+    public double probability(double x) {
+        double fl = FastMath.floor(x);
+        if (fl == x) {
+            return this.probability((int) x);
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+    * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(x0 &le; X &le; x1).
+     *
+     * @param x0 the inclusive, lower bound
+     * @param x1 the inclusive, upper bound
+     * @return the cumulative probability.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if x0 > x1
+     */
+    public double cumulativeProbability(int x0, int x1) throws MathException {
+        if (x0 > x1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1);
+        }
+        return cumulativeProbability(x1) - cumulativeProbability(x0 - 1);
+    }
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns the largest x, such
+     * that P(X &le; x) &le; <code>p</code>.
+     *
+     * @param p the desired probability
+     * @return the largest x such that P(X &le; x) <= p
+     * @throws MathException if the inverse cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if p < 0 or p > 1
+     */
+    public int inverseCumulativeProbability(final double p) throws MathException{
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        }
+
+        // by default, do simple bisection.
+        // subclasses can override if there is a better method.
+        int x0 = getDomainLowerBound(p);
+        int x1 = getDomainUpperBound(p);
+        double pm;
+        while (x0 < x1) {
+            int xm = x0 + (x1 - x0) / 2;
+            pm = checkedCumulativeProbability(xm);
+            if (pm > p) {
+                // update x1
+                if (xm == x1) {
+                    // this can happen with integer division
+                    // simply decrement x1
+                    --x1;
+                } else {
+                    // update x1 normally
+                    x1 = xm;
+                }
+            } else {
+                // update x0
+                if (xm == x0) {
+                    // this can happen with integer division
+                    // simply increment x0
+                    ++x0;
+                } else {
+                    // update x0 normally
+                    x0 = xm;
+                }
+            }
+        }
+
+        // insure x0 is the correct critical point
+        pm = checkedCumulativeProbability(x0);
+        while (pm > p) {
+            --x0;
+            pm = checkedCumulativeProbability(x0);
+        }
+
+        return x0;
+    }
+
+    /**
+     * Reseeds the random generator used to generate samples.
+     *
+     * @param seed the new seed
+     * @since 2.2
+     */
+    public void reseedRandomGenerator(long seed) {
+        randomData.reSeed(seed);
+    }
+
+    /**
+     * Generates a random value sampled from this distribution. The default
+     * implementation uses the
+     * <a href="http://en.wikipedia.org/wiki/Inverse_transform_sampling"> inversion method.</a>
+     *
+     * @return random value
+     * @since 2.2
+     * @throws MathException if an error occurs generating the random value
+     */
+    public int sample() throws MathException {
+        return randomData.nextInversionDeviate(this);
+    }
+
+    /**
+     * Generates a random sample from the distribution.  The default implementation
+     * generates the sample by calling {@link #sample()} in a loop.
+     *
+     * @param sampleSize number of random values to generate
+     * @since 2.2
+     * @return an array representing the random sample
+     * @throws MathException if an error occurs generating the sample
+     * @throws IllegalArgumentException if sampleSize is not positive
+     */
+    public int[] sample(int sampleSize) throws MathException {
+        if (sampleSize <= 0) {
+            MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, sampleSize);
+        }
+        int[] out = new int[sampleSize];
+        for (int i = 0; i < sampleSize; i++) {
+            out[i] = sample();
+        }
+        return out;
+    }
+
+    /**
+     * Computes the cumulative probability function and checks for NaN values returned.
+     * Throws MathException if the value is NaN. Rethrows any MathException encountered
+     * evaluating the cumulative probability function. Throws
+     * MathException if the cumulative probability function returns NaN.
+     *
+     * @param argument input value
+     * @return cumulative probability
+     * @throws MathException if the cumulative probability is NaN
+     */
+    private double checkedCumulativeProbability(int argument) throws MathException {
+        double result = Double.NaN;
+            result = cumulativeProbability(argument);
+        if (Double.isNaN(result)) {
+            throw new MathException(LocalizedFormats.DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN, argument);
+        }
+        return result;
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a PDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    protected abstract int getDomainLowerBound(double p);
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a PDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    protected abstract int getDomainUpperBound(double p);
+
+    /**
+     * Use this method to get information about whether the lower bound
+     * of the support is inclusive or not. For discrete support,
+     * only true here is meaningful.
+     *
+     * @return true (always but at Integer.MIN_VALUE because of the nature of discrete support)
+     * @since 2.2
+     */
+    public boolean isSupportLowerBoundInclusive() {
+        return true;
+    }
+
+    /**
+     * Use this method to get information about whether the upper bound
+     * of the support is inclusive or not. For discrete support,
+     * only true here is meaningful.
+     *
+     * @return true (always but at Integer.MAX_VALUE because of the nature of discrete support)
+     * @since 2.2
+     */
+    public boolean isSupportUpperBoundInclusive() {
+        return true;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/BetaDistribution.java b/src/main/java/org/apache/commons/math/distribution/BetaDistribution.java
new file mode 100644
index 0000000..7693b04
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/BetaDistribution.java
@@ -0,0 +1,65 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Computes the cumulative, inverse cumulative and density functions for the beta distribuiton.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Beta_distribution">Beta_distribution</a>
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ * @since 2.0
+ */
+public interface BetaDistribution extends ContinuousDistribution, HasDensity<Double> {
+    /**
+     * Modify the shape parameter, alpha.
+     * @param alpha the new shape parameter.
+     * @deprecated as of 2.1
+     */
+    @Deprecated
+    void setAlpha(double alpha);
+
+     /**
+      * Access the shape parameter, alpha
+      * @return alpha.
+      */
+     double getAlpha();
+
+     /**
+      * Modify the shape parameter, beta.
+      * @param beta the new scale parameter.
+      * @deprecated as of 2.1
+      */
+     @Deprecated
+     void setBeta(double beta);
+
+     /**
+      * Access the shape parameter, beta
+      * @return beta.
+      */
+     double getBeta();
+
+     /**
+      * Return the probability density for a particular point.
+      * @param x  The point at which the density should be computed.
+      * @return  The pdf at point x.
+      * @exception MathException if probability density cannot be computed
+      */
+     double density(Double x) throws MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java
new file mode 100644
index 0000000..4d96187
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/BetaDistributionImpl.java
@@ -0,0 +1,284 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Gamma;
+import org.apache.commons.math.special.Beta;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the Beta distribution.
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://en.wikipedia.org/wiki/Beta_distribution">
+ * Beta distribution</a></li>
+ * </ul>
+ * </p>
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ * @since 2.0
+ */
+public class BetaDistributionImpl
+    extends AbstractContinuousDistribution implements BetaDistribution {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -1221965979403477668L;
+
+    /** First shape parameter. */
+    private double alpha;
+
+    /** Second shape parameter. */
+    private double beta;
+
+    /** Normalizing factor used in density computations.
+     * updated whenever alpha or beta are changed.
+     */
+    private double z;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Build a new instance.
+     * @param alpha first shape parameter (must be positive)
+     * @param beta second shape parameter (must be positive)
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public BetaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) {
+        this.alpha = alpha;
+        this.beta = beta;
+        z = Double.NaN;
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * Build a new instance.
+     * @param alpha first shape parameter (must be positive)
+     * @param beta second shape parameter (must be positive)
+     */
+    public BetaDistributionImpl(double alpha, double beta) {
+        this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /** {@inheritDoc}
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setAlpha(double alpha) {
+        this.alpha = alpha;
+        z = Double.NaN;
+    }
+
+    /** {@inheritDoc} */
+    public double getAlpha() {
+        return alpha;
+    }
+
+    /** {@inheritDoc}
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setBeta(double beta) {
+        this.beta = beta;
+        z = Double.NaN;
+    }
+
+    /** {@inheritDoc} */
+    public double getBeta() {
+        return beta;
+    }
+
+    /**
+     * Recompute the normalization factor.
+     */
+    private void recomputeZ() {
+        if (Double.isNaN(z)) {
+            z = Gamma.logGamma(alpha) + Gamma.logGamma(beta) - Gamma.logGamma(alpha + beta);
+        }
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @deprecated
+     */
+    @Deprecated
+    public double density(Double x) {
+        return density(x.doubleValue());
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        recomputeZ();
+        if (x < 0 || x > 1) {
+            return 0;
+        } else if (x == 0) {
+            if (alpha < 1) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA, alpha);
+            }
+            return 0;
+        } else if (x == 1) {
+            if (beta < 1) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA, beta);
+            }
+            return 0;
+        } else {
+            double logX = FastMath.log(x);
+            double log1mX = FastMath.log1p(-x);
+            return FastMath.exp((alpha - 1) * logX + (beta - 1) * log1mX - z);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double inverseCumulativeProbability(double p) throws MathException {
+        if (p == 0) {
+            return 0;
+        } else if (p == 1) {
+            return 1;
+        } else {
+            return super.inverseCumulativeProbability(p);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected double getInitialDomain(double p) {
+        return p;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        return 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        return 1;
+    }
+
+    /** {@inheritDoc} */
+    public double cumulativeProbability(double x) throws MathException {
+        if (x <= 0) {
+            return 0;
+        } else if (x >= 1) {
+            return 1;
+        } else {
+            return Beta.regularizedBeta(x, alpha, beta);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double cumulativeProbability(double x0, double x1) throws MathException {
+        return cumulativeProbability(x1) - cumulativeProbability(x0);
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for this distribution.
+     * The support of the Beta distribution is always [0, 1], regardless
+     * of the parameters, so this method always returns 0.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for this distribution.
+     * The support of the Beta distribution is always [0, 1], regardless
+     * of the parameters, so this method always returns 1.
+     *
+     * @return lower bound of the support (always 1)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return 1;
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For first shape parameter <code>s1</code> and
+     * second shape parameter <code>s2</code>, the mean is
+     * <code>s1 / (s1 + s2)</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        final double a = getAlpha();
+        return a / (a + getBeta());
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For first shape parameter <code>s1</code> and
+     * second shape parameter <code>s2</code>,
+     * the variance is
+     * <code>[ s1 * s2 ] / [ (s1 + s2)^2 * (s1 + s2 + 1) ]</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double a = getAlpha();
+        final double b = getBeta();
+        final double alphabetasum = a + b;
+        return (a * b) / ((alphabetasum * alphabetasum) * (alphabetasum + 1));
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/BinomialDistribution.java b/src/main/java/org/apache/commons/math/distribution/BinomialDistribution.java
new file mode 100644
index 0000000..94b3236
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/BinomialDistribution.java
@@ -0,0 +1,60 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Binomial Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/BinomialDistribution.html">
+ * Binomial Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface BinomialDistribution extends IntegerDistribution {
+    /**
+     * Access the number of trials for this distribution.
+     * @return the number of trials.
+     */
+    int getNumberOfTrials();
+
+    /**
+     * Access the probability of success for this distribution.
+     * @return the probability of success.
+     */
+    double getProbabilityOfSuccess();
+
+    /**
+     * Change the number of trials for this distribution.
+     * @param trials the new number of trials.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setNumberOfTrials(int trials);
+
+    /**
+     * Change the probability of success for this distribution.
+     * @param p the new probability of success.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setProbabilityOfSuccess(double p);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java
new file mode 100644
index 0000000..9ebb629
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/BinomialDistributionImpl.java
@@ -0,0 +1,279 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Beta;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * The default implementation of {@link BinomialDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class BinomialDistributionImpl extends AbstractIntegerDistribution
+        implements BinomialDistribution, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 6751309484392813623L;
+
+    /** The number of trials. */
+    private int numberOfTrials;
+
+    /** The probability of success. */
+    private double probabilityOfSuccess;
+
+    /**
+     * Create a binomial distribution with the given number of trials and
+     * probability of success.
+     *
+     * @param trials the number of trials.
+     * @param p the probability of success.
+     */
+    public BinomialDistributionImpl(int trials, double p) {
+        super();
+        setNumberOfTrialsInternal(trials);
+        setProbabilityOfSuccessInternal(p);
+    }
+
+    /**
+     * Access the number of trials for this distribution.
+     *
+     * @return the number of trials.
+     */
+    public int getNumberOfTrials() {
+        return numberOfTrials;
+    }
+
+    /**
+     * Access the probability of success for this distribution.
+     *
+     * @return the probability of success.
+     */
+    public double getProbabilityOfSuccess() {
+        return probabilityOfSuccess;
+    }
+
+    /**
+     * Change the number of trials for this distribution.
+     *
+     * @param trials the new number of trials.
+     * @throws IllegalArgumentException if <code>trials</code> is not a valid
+     *             number of trials.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setNumberOfTrials(int trials) {
+        setNumberOfTrialsInternal(trials);
+    }
+
+    /**
+     * Change the number of trials for this distribution.
+     *
+     * @param trials the new number of trials.
+     * @throws IllegalArgumentException if <code>trials</code> is not a valid
+     *             number of trials.
+     */
+    private void setNumberOfTrialsInternal(int trials) {
+        if (trials < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NEGATIVE_NUMBER_OF_TRIALS, trials);
+        }
+        numberOfTrials = trials;
+    }
+
+    /**
+     * Change the probability of success for this distribution.
+     *
+     * @param p the new probability of success.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *             probability.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setProbabilityOfSuccess(double p) {
+        setProbabilityOfSuccessInternal(p);
+    }
+
+    /**
+     * Change the probability of success for this distribution.
+     *
+     * @param p the new probability of success.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *             probability.
+     */
+    private void setProbabilityOfSuccessInternal(double p) {
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        }
+        probabilityOfSuccess = p;
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e. P(X &lt; <i>lower bound</i>) &lt;
+     *         <code>p</code>
+     */
+    @Override
+    protected int getDomainLowerBound(double p) {
+        return -1;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e. P(X &lt; <i>upper bound</i>) &gt;
+     *         <code>p</code>
+     */
+    @Override
+    protected int getDomainUpperBound(double p) {
+        return numberOfTrials;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &le; x).
+     *
+     * @param x the value at which the PDF is evaluated.
+     * @return PDF for this distribution.
+     * @throws MathException if the cumulative probability can not be computed
+     *             due to convergence or other numerical errors.
+     */
+    @Override
+    public double cumulativeProbability(int x) throws MathException {
+        double ret;
+        if (x < 0) {
+            ret = 0.0;
+        } else if (x >= numberOfTrials) {
+            ret = 1.0;
+        } else {
+            ret = 1.0 - Beta.regularizedBeta(getProbabilityOfSuccess(),
+                    x + 1.0, numberOfTrials - x);
+        }
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X = x).
+     *
+     * @param x the value at which the PMF is evaluated.
+     * @return PMF for this distribution.
+     */
+    public double probability(int x) {
+        double ret;
+        if (x < 0 || x > numberOfTrials) {
+            ret = 0.0;
+        } else {
+            ret = FastMath.exp(SaddlePointExpansion.logBinomialProbability(x,
+                    numberOfTrials, probabilityOfSuccess,
+                    1.0 - probabilityOfSuccess));
+        }
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns the largest x, such that
+     * P(X &le; x) &le; <code>p</code>.
+     * <p>
+     * Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code> for
+     * p=1.
+     * </p>
+     *
+     * @param p the desired probability
+     * @return the largest x such that P(X &le; x) <= p
+     * @throws MathException if the inverse cumulative probability can not be
+     *             computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if p < 0 or p > 1
+     */
+    @Override
+    public int inverseCumulativeProbability(final double p)
+            throws MathException {
+        // handle extreme values explicitly
+        if (p == 0) {
+            return -1;
+        }
+        if (p == 1) {
+            return Integer.MAX_VALUE;
+        }
+
+        // use default bisection impl
+        return super.inverseCumulativeProbability(p);
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0 no matter the number of trials
+     * and probability parameter.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public int getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is the number of trials.
+     *
+     * @return upper bound of the support (equal to number of trials)
+     * @since 2.2
+     */
+    public int getSupportUpperBound() {
+        return getNumberOfTrials();
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For <code>n</code> number of trials and
+     * probability parameter <code>p</code>, the mean is
+     * <code>n * p</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        return (double)getNumberOfTrials() * getProbabilityOfSuccess();
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For <code>n</code> number of trials and
+     * probability parameter <code>p</code>, the variance is
+     * <code>n * p * (1 - p)</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double p = getProbabilityOfSuccess();
+        return (double)getNumberOfTrials() * p * (1 - p);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/CauchyDistribution.java b/src/main/java/org/apache/commons/math/distribution/CauchyDistribution.java
new file mode 100644
index 0000000..7a4ccbd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/CauchyDistribution.java
@@ -0,0 +1,63 @@
+/*
+ * 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.distribution;
+
+/**
+ * Cauchy Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/CauchyDistribution.html">
+ * Cauchy Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @since 1.1
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface CauchyDistribution extends ContinuousDistribution {
+
+    /**
+     * Access the median.
+     * @return median for this distribution
+     */
+    double getMedian();
+
+    /**
+     * Access the scale parameter.
+     * @return scale parameter for this distribution
+     */
+    double getScale();
+
+    /**
+     * Modify the median.
+     * @param median for this distribution
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setMedian(double median);
+
+    /**
+     * Modify the scale parameter.
+     * @param s scale parameter for this distribution
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setScale(double s);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java
new file mode 100644
index 0000000..b076924
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/CauchyDistributionImpl.java
@@ -0,0 +1,320 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Default implementation of
+ * {@link org.apache.commons.math.distribution.CauchyDistribution}.
+ *
+ * @since 1.1
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class CauchyDistributionImpl extends AbstractContinuousDistribution
+        implements CauchyDistribution, Serializable {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 8589540077390120676L;
+
+    /** The median of this distribution. */
+    private double median = 0;
+
+    /** The scale of this distribution. */
+    private double scale = 1;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Creates cauchy distribution with the medain equal to zero and scale
+     * equal to one.
+     */
+    public CauchyDistributionImpl(){
+        this(0.0, 1.0);
+    }
+
+    /**
+     * Create a cauchy distribution using the given median and scale.
+     * @param median median for this distribution
+     * @param s scale parameter for this distribution
+     */
+    public CauchyDistributionImpl(double median, double s){
+        this(median, s, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Create a cauchy distribution using the given median and scale.
+     * @param median median for this distribution
+     * @param s scale parameter for this distribution
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public CauchyDistributionImpl(double median, double s, double inverseCumAccuracy) {
+        super();
+        setMedianInternal(median);
+        setScaleInternal(s);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; <code>x</code>).
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF evaluated at <code>x</code>.
+     */
+    public double cumulativeProbability(double x) {
+        return 0.5 + (FastMath.atan((x - median) / scale) / FastMath.PI);
+    }
+
+    /**
+     * Access the median.
+     * @return median for this distribution
+     */
+    public double getMedian() {
+        return median;
+    }
+
+    /**
+     * Access the scale parameter.
+     * @return scale parameter for this distribution
+     */
+    public double getScale() {
+        return scale;
+    }
+
+    /**
+     * Returns the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        final double dev = x - median;
+        return (1 / FastMath.PI) * (scale / (dev * dev + scale * scale));
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
+     * <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(double p) {
+        double ret;
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        } else if (p == 0) {
+            ret = Double.NEGATIVE_INFINITY;
+        } else  if (p == 1) {
+            ret = Double.POSITIVE_INFINITY;
+        } else {
+            ret = median + scale * FastMath.tan(FastMath.PI * (p - .5));
+        }
+        return ret;
+    }
+
+    /**
+     * Modify the median.
+     * @param median for this distribution
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setMedian(double median) {
+        setMedianInternal(median);
+    }
+
+    /**
+     * Modify the median.
+     * @param newMedian for this distribution
+     */
+    private void setMedianInternal(double newMedian) {
+        this.median = newMedian;
+    }
+
+    /**
+     * Modify the scale parameter.
+     * @param s scale parameter for this distribution
+     * @throws IllegalArgumentException if <code>sd</code> is not positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setScale(double s) {
+        setScaleInternal(s);
+    }
+
+    /**
+     * Modify the scale parameter.
+     * @param s scale parameter for this distribution
+     * @throws IllegalArgumentException if <code>sd</code> is not positive.
+     */
+    private void setScaleInternal(double s) {
+        if (s <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_SCALE, s);
+        }
+        scale = s;
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        double ret;
+
+        if (p < .5) {
+            ret = -Double.MAX_VALUE;
+        } else {
+            ret = median;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        double ret;
+
+        if (p < .5) {
+            ret = median;
+        } else {
+            ret = Double.MAX_VALUE;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        double ret;
+
+        if (p < .5) {
+            ret = median - scale;
+        } else if (p > .5) {
+            ret = median + scale;
+        } else {
+            ret = median;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for this distribution.
+     * The lower bound of the support of the Cauchy distribution is always
+     * negative infinity, regardless of the parameters.
+     *
+     * @return lower bound of the support (always Double.NEGATIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return Double.NEGATIVE_INFINITY;
+    }
+
+    /**
+     * Returns the upper bound of the support for this distribution.
+     * The upper bound of the support of the Cauchy distribution is always
+     * positive infinity, regardless of the parameters.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * The mean is always undefined, regardless of the parameters.
+     *
+     * @return mean (always Double.NaN)
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        return Double.NaN;
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * The variance is always undefined, regardless of the parameters.
+     *
+     * @return variance (always Double.NaN)
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        return Double.NaN;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistribution.java b/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistribution.java
new file mode 100644
index 0000000..0478db1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistribution.java
@@ -0,0 +1,53 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Chi-Squared Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/Chi-SquaredDistribution.html">
+ * Chi-Squared Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface ChiSquaredDistribution extends ContinuousDistribution, HasDensity<Double> {
+    /**
+     * Modify the degrees of freedom.
+     * @param degreesOfFreedom the new degrees of freedom.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setDegreesOfFreedom(double degreesOfFreedom);
+
+    /**
+     * Access the degrees of freedom.
+     * @return the degrees of freedom.
+     */
+    double getDegreesOfFreedom();
+
+    /**
+     * Return the probability density for a particular point.
+     * @param x  The point at which the density should be computed.
+     * @return  The pdf at point x.
+     */
+    double density(Double x);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
new file mode 100644
index 0000000..f877792
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
@@ -0,0 +1,324 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * The default implementation of {@link ChiSquaredDistribution}
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class ChiSquaredDistributionImpl
+    extends AbstractContinuousDistribution
+    implements ChiSquaredDistribution, Serializable  {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -8352658048349159782L;
+
+    /** Internal Gamma distribution. */
+    private GammaDistribution gamma;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Create a Chi-Squared distribution with the given degrees of freedom.
+     * @param df degrees of freedom.
+     */
+    public ChiSquaredDistributionImpl(double df) {
+        this(df, new GammaDistributionImpl(df / 2.0, 2.0));
+    }
+
+    /**
+     * Create a Chi-Squared distribution with the given degrees of freedom.
+     * @param df degrees of freedom.
+     * @param g the underlying gamma distribution used to compute probabilities.
+     * @since 1.2
+     * @deprecated as of 2.1 (to avoid possibly inconsistent state, the
+     * "GammaDistribution" will be instantiated internally)
+     */
+    @Deprecated
+    public ChiSquaredDistributionImpl(double df, GammaDistribution g) {
+        super();
+        setGammaInternal(g);
+        setDegreesOfFreedomInternal(df);
+        solverAbsoluteAccuracy = DEFAULT_INVERSE_ABSOLUTE_ACCURACY;
+    }
+
+    /**
+     * Create a Chi-Squared distribution with the given degrees of freedom and
+     * inverse cumulative probability accuracy.
+     * @param df degrees of freedom.
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public ChiSquaredDistributionImpl(double df, double inverseCumAccuracy) {
+        super();
+        gamma = new GammaDistributionImpl(df / 2.0, 2.0);
+        setDegreesOfFreedomInternal(df);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * Modify the degrees of freedom.
+     * @param degreesOfFreedom the new degrees of freedom.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setDegreesOfFreedom(double degreesOfFreedom) {
+        setDegreesOfFreedomInternal(degreesOfFreedom);
+    }
+    /**
+     * Modify the degrees of freedom.
+     * @param degreesOfFreedom the new degrees of freedom.
+     */
+    private void setDegreesOfFreedomInternal(double degreesOfFreedom) {
+        gamma.setAlpha(degreesOfFreedom / 2.0);
+    }
+
+    /**
+     * Access the degrees of freedom.
+     * @return the degrees of freedom.
+     */
+    public double getDegreesOfFreedom() {
+        return gamma.getAlpha() * 2.0;
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @deprecated
+     */
+    @Deprecated
+    public double density(Double x) {
+        return density(x.doubleValue());
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        return gamma.density(x);
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; x).
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF for this distribution.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    public double cumulativeProbability(double x) throws MathException {
+        return gamma.cumulativeProbability(x);
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(final double p)
+        throws MathException {
+        if (p == 0) {
+            return 0d;
+        }
+        if (p == 1) {
+            return Double.POSITIVE_INFINITY;
+        }
+        return super.inverseCumulativeProbability(p);
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        return Double.MIN_VALUE * gamma.getBeta();
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        // NOTE: chi squared is skewed to the left
+        // NOTE: therefore, P(X < &mu;) > .5
+
+        double ret;
+
+        if (p < .5) {
+            // use mean
+            ret = getDegreesOfFreedom();
+        } else {
+            // use max
+            ret = Double.MAX_VALUE;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        // NOTE: chi squared is skewed to the left
+        // NOTE: therefore, P(X < &mu;) > .5
+
+        double ret;
+
+        if (p < .5) {
+            // use 1/2 mean
+            ret = getDegreesOfFreedom() * .5;
+        } else {
+            // use mean
+            ret = getDegreesOfFreedom();
+        }
+
+        return ret;
+    }
+
+    /**
+     * Modify the underlying gamma distribution.  The caller is responsible for
+     * insuring the gamma distribution has the proper parameter settings.
+     * @param g the new distribution.
+     * @since 1.2 made public
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setGamma(GammaDistribution g) {
+        setGammaInternal(g);
+    }
+    /**
+     * Modify the underlying gamma distribution.  The caller is responsible for
+     * insuring the gamma distribution has the proper parameter settings.
+     * @param g the new distribution.
+     * @since 1.2 made public
+     */
+    private void setGammaInternal(GammaDistribution g) {
+        this.gamma = g;
+
+    }
+
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0 no matter the
+     * degrees of freedom.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound for the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity no matter the
+     * degrees of freedom.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the mean of the distribution.
+     *
+     * For <code>k</code> degrees of freedom, the mean is
+     * <code>k</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        return getDegreesOfFreedom();
+    }
+
+    /**
+     * Returns the variance of the distribution.
+     *
+     * For <code>k</code> degrees of freedom, the variance is
+     * <code>2 * k</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        return 2*getDegreesOfFreedom();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ContinuousDistribution.java b/src/main/java/org/apache/commons/math/distribution/ContinuousDistribution.java
new file mode 100644
index 0000000..afcd4c3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ContinuousDistribution.java
@@ -0,0 +1,43 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * <p>Base interface for continuous distributions.</p>
+ *
+ * <p>Note: this interface will be extended in version 3.0 to include
+ * <br/><code>public double density(double x)</code><br/>
+ * that is, from version 3.0 forward, continuous distributions <strong>must</strong>
+ * include implementations of probability density functions. As of version
+ * 2.1, all continuous distribution implementations included in commons-math
+ * provide implementations of this method.</p>
+ *
+ * @version $Revision: 924362 $ $Date: 2010-03-17 17:45:31 +0100 (mer. 17 mars 2010) $
+ */
+public interface ContinuousDistribution extends Distribution {
+
+    /**
+     * For this distribution, X, this method returns x such that P(X &lt; x) = p.
+     * @param p the cumulative probability.
+     * @return x.
+     * @throws MathException if the inverse cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    double inverseCumulativeProbability(double p) throws MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/DiscreteDistribution.java b/src/main/java/org/apache/commons/math/distribution/DiscreteDistribution.java
new file mode 100644
index 0000000..d6ea444
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/DiscreteDistribution.java
@@ -0,0 +1,35 @@
+/*
+ * 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.distribution;
+
+
+/**
+ * Base interface for discrete distributions.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface DiscreteDistribution extends Distribution {
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X = x). In other words, this
+     * method represents the probability mass function, or PMF for the distribution.
+     *
+     * @param x the value at which the probability mass function is evaluated.
+     * @return the value of the probability mass function at x
+     */
+    double probability(double x);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/Distribution.java b/src/main/java/org/apache/commons/math/distribution/Distribution.java
new file mode 100644
index 0000000..221aeb7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/Distribution.java
@@ -0,0 +1,56 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Base interface for probability distributions.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public interface Distribution {
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X &le; x).  In other words,
+     * this method represents the  (cumulative) distribution function, or
+     * CDF, for this distribution.
+     *
+     * @param x the value at which the distribution function is evaluated.
+     * @return the probability that a random variable with this
+     * distribution takes a value less than or equal to <code>x</code>
+     * @throws MathException if the cumulative probability can not be
+     * computed due to convergence or other numerical errors.
+     */
+    double cumulativeProbability(double x) throws MathException;
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(x0 &le; X &le; x1).
+     *
+     * @param x0 the (inclusive) lower bound
+     * @param x1 the (inclusive) upper bound
+     * @return the probability that a random variable with this distribution
+     * will take a value between <code>x0</code> and <code>x1</code>,
+     * including the endpoints
+     * @throws MathException if the cumulative probability can not be
+     * computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>x0 > x1</code>
+     */
+    double cumulativeProbability(double x0, double x1) throws MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ExponentialDistribution.java b/src/main/java/org/apache/commons/math/distribution/ExponentialDistribution.java
new file mode 100644
index 0000000..6d3fbe2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ExponentialDistribution.java
@@ -0,0 +1,53 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Exponential Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/ExponentialDistribution.html">
+ * Exponential Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface ExponentialDistribution extends ContinuousDistribution, HasDensity<Double> {
+    /**
+     * Modify the mean.
+     * @param mean the new mean.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setMean(double mean);
+
+    /**
+     * Access the mean.
+     * @return the mean.
+     */
+    double getMean();
+
+    /**
+     * Return the probability density for a particular point.
+     * @param x  The point at which the density should be computed.
+     * @return  The pdf at point x.
+     */
+    double density(Double x);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
new file mode 100644
index 0000000..25d81f4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
@@ -0,0 +1,319 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * The default implementation of {@link ExponentialDistribution}.
+ *
+ * @version $Revision: 1055914 $ $Date: 2011-01-06 16:34:34 +0100 (jeu. 06 janv. 2011) $
+ */
+public class ExponentialDistributionImpl extends AbstractContinuousDistribution
+    implements ExponentialDistribution, Serializable {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 2401296428283614780L;
+
+    /** The mean of this distribution. */
+    private double mean;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Create a exponential distribution with the given mean.
+     * @param mean mean of this distribution.
+     */
+    public ExponentialDistributionImpl(double mean) {
+        this(mean, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Create a exponential distribution with the given mean.
+     * @param mean mean of this distribution.
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public ExponentialDistributionImpl(double mean, double inverseCumAccuracy) {
+        super();
+        setMeanInternal(mean);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * Modify the mean.
+     * @param mean the new mean.
+     * @throws IllegalArgumentException if <code>mean</code> is not positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setMean(double mean) {
+        setMeanInternal(mean);
+    }
+    /**
+     * Modify the mean.
+     * @param newMean the new mean.
+     * @throws IllegalArgumentException if <code>newMean</code> is not positive.
+     */
+    private void setMeanInternal(double newMean) {
+        if (newMean <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_MEAN, newMean);
+        }
+        this.mean = newMean;
+    }
+
+    /**
+     * Access the mean.
+     * @return the mean.
+     */
+    public double getMean() {
+        return mean;
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @deprecated - use density(double)
+     */
+    @Deprecated
+    public double density(Double x) {
+        return density(x.doubleValue());
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        if (x < 0) {
+            return 0;
+        }
+        return FastMath.exp(-x / mean) / mean;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; x).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/ExponentialDistribution.html">
+     * Exponential Distribution</a>, equation (1).</li>
+     * </ul>
+     *
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF for this distribution.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    public double cumulativeProbability(double x) throws MathException{
+        double ret;
+        if (x <= 0.0) {
+            ret = 0.0;
+        } else {
+            ret = 1.0 - FastMath.exp(-x / mean);
+        }
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if p < 0 or p > 1.
+     */
+    @Override
+    public double inverseCumulativeProbability(double p) throws MathException {
+        double ret;
+
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        } else if (p == 1.0) {
+            ret = Double.POSITIVE_INFINITY;
+        } else {
+            ret = -mean * FastMath.log(1.0 - p);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Generates a random value sampled from this distribution.
+     *
+     * <p><strong>Algorithm Description</strong>: Uses the <a
+     * href="http://www.jesus.ox.ac.uk/~clifford/a5/chap1/node5.html"> Inversion
+     * Method</a> to generate exponentially distributed random values from
+     * uniform deviates. </p>
+     *
+     * @return random value
+     * @since 2.2
+     * @throws MathException if an error occurs generating the random value
+     */
+    @Override
+    public double sample() throws MathException {
+        return randomData.nextExponential(mean);
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        return 0;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        // NOTE: exponential is skewed to the left
+        // NOTE: therefore, P(X < &mu;) > .5
+
+        if (p < .5) {
+            // use mean
+            return mean;
+        } else {
+            // use max
+            return Double.MAX_VALUE;
+        }
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        // TODO: try to improve on this estimate
+        // TODO: what should really happen here is not derive from AbstractContinuousDistribution
+        // TODO: because the inverse cumulative distribution is simple.
+        // Exponential is skewed to the left, therefore, P(X < &mu;) > .5
+        if (p < .5) {
+            // use 1/2 mean
+            return mean * .5;
+        } else {
+            // use mean
+            return mean;
+        }
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0, regardless of the mean.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity,
+     * regardless of the mean.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the mean of the distribution.
+     *
+     * For mean parameter <code>k</code>, the mean is
+     * <code>k</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        return getMean();
+    }
+
+    /**
+     * Returns the variance of the distribution.
+     *
+     * For mean parameter <code>k</code>, the variance is
+     * <code>k^2</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double m = getMean();
+        return m * m;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/FDistribution.java b/src/main/java/org/apache/commons/math/distribution/FDistribution.java
new file mode 100644
index 0000000..51c33bf
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/FDistribution.java
@@ -0,0 +1,60 @@
+/*
+ * 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.distribution;
+
+/**
+ * F-Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/F-Distribution.html">
+ * F-Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface FDistribution extends ContinuousDistribution {
+    /**
+     * Modify the numerator degrees of freedom.
+     * @param degreesOfFreedom the new numerator degrees of freedom.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setNumeratorDegreesOfFreedom(double degreesOfFreedom);
+
+    /**
+     * Access the numerator degrees of freedom.
+     * @return the numerator degrees of freedom.
+     */
+    double getNumeratorDegreesOfFreedom();
+
+    /**
+     * Modify the denominator degrees of freedom.
+     * @param degreesOfFreedom the new denominator degrees of freedom.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setDenominatorDegreesOfFreedom(double degreesOfFreedom);
+
+    /**
+     * Access the denominator degrees of freedom.
+     * @return the denominator degrees of freedom.
+     */
+    double getDenominatorDegreesOfFreedom();
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java
new file mode 100644
index 0000000..5b4049e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/FDistributionImpl.java
@@ -0,0 +1,360 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Beta;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Default implementation of
+ * {@link org.apache.commons.math.distribution.FDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class FDistributionImpl
+    extends AbstractContinuousDistribution
+    implements FDistribution, Serializable  {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -8516354193418641566L;
+
+    /** The numerator degrees of freedom*/
+    private double numeratorDegreesOfFreedom;
+
+    /** The numerator degrees of freedom*/
+    private double denominatorDegreesOfFreedom;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Create a F distribution using the given degrees of freedom.
+     * @param numeratorDegreesOfFreedom the numerator degrees of freedom.
+     * @param denominatorDegreesOfFreedom the denominator degrees of freedom.
+     */
+    public FDistributionImpl(double numeratorDegreesOfFreedom,
+                             double denominatorDegreesOfFreedom) {
+        this(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Create a F distribution using the given degrees of freedom and inverse cumulative probability accuracy.
+     * @param numeratorDegreesOfFreedom the numerator degrees of freedom.
+     * @param denominatorDegreesOfFreedom the denominator degrees of freedom.
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public FDistributionImpl(double numeratorDegreesOfFreedom, double denominatorDegreesOfFreedom,
+            double inverseCumAccuracy) {
+        super();
+        setNumeratorDegreesOfFreedomInternal(numeratorDegreesOfFreedom);
+        setDenominatorDegreesOfFreedomInternal(denominatorDegreesOfFreedom);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * Returns the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        final double nhalf = numeratorDegreesOfFreedom / 2;
+        final double mhalf = denominatorDegreesOfFreedom / 2;
+        final double logx = FastMath.log(x);
+        final double logn = FastMath.log(numeratorDegreesOfFreedom);
+        final double logm = FastMath.log(denominatorDegreesOfFreedom);
+        final double lognxm = FastMath.log(numeratorDegreesOfFreedom * x + denominatorDegreesOfFreedom);
+        return FastMath.exp(nhalf*logn + nhalf*logx - logx + mhalf*logm - nhalf*lognxm -
+               mhalf*lognxm - Beta.logBeta(nhalf, mhalf));
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; x).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/F-Distribution.html">
+     * F-Distribution</a>, equation (4).</li>
+     * </ul>
+     *
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF for this distribution.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    public double cumulativeProbability(double x) throws MathException {
+        double ret;
+        if (x <= 0.0) {
+            ret = 0.0;
+        } else {
+            double n = numeratorDegreesOfFreedom;
+            double m = denominatorDegreesOfFreedom;
+
+            ret = Beta.regularizedBeta((n * x) / (m + n * x),
+                0.5 * n,
+                0.5 * m);
+        }
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(final double p)
+        throws MathException {
+        if (p == 0) {
+            return 0d;
+        }
+        if (p == 1) {
+            return Double.POSITIVE_INFINITY;
+        }
+        return super.inverseCumulativeProbability(p);
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        return 0.0;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        return Double.MAX_VALUE;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        double ret = 1.0;
+        double d = denominatorDegreesOfFreedom;
+        if (d > 2.0) {
+            // use mean
+            ret = d / (d - 2.0);
+        }
+        return ret;
+    }
+
+    /**
+     * Modify the numerator degrees of freedom.
+     * @param degreesOfFreedom the new numerator degrees of freedom.
+     * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not
+     *         positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) {
+        setNumeratorDegreesOfFreedomInternal(degreesOfFreedom);
+    }
+
+    /**
+     * Modify the numerator degrees of freedom.
+     * @param degreesOfFreedom the new numerator degrees of freedom.
+     * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not
+     *         positive.
+     */
+    private void setNumeratorDegreesOfFreedomInternal(double degreesOfFreedom) {
+        if (degreesOfFreedom <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_DEGREES_OF_FREEDOM, degreesOfFreedom);
+        }
+        this.numeratorDegreesOfFreedom = degreesOfFreedom;
+    }
+
+    /**
+     * Access the numerator degrees of freedom.
+     * @return the numerator degrees of freedom.
+     */
+    public double getNumeratorDegreesOfFreedom() {
+        return numeratorDegreesOfFreedom;
+    }
+
+    /**
+     * Modify the denominator degrees of freedom.
+     * @param degreesOfFreedom the new denominator degrees of freedom.
+     * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not
+     *         positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) {
+        setDenominatorDegreesOfFreedomInternal(degreesOfFreedom);
+    }
+
+    /**
+     * Modify the denominator degrees of freedom.
+     * @param degreesOfFreedom the new denominator degrees of freedom.
+     * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not
+     *         positive.
+     */
+    private void setDenominatorDegreesOfFreedomInternal(double degreesOfFreedom) {
+        if (degreesOfFreedom <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_DEGREES_OF_FREEDOM, degreesOfFreedom);
+        }
+        this.denominatorDegreesOfFreedom = degreesOfFreedom;
+    }
+
+    /**
+     * Access the denominator degrees of freedom.
+     * @return the denominator degrees of freedom.
+     */
+    public double getDenominatorDegreesOfFreedom() {
+        return denominatorDegreesOfFreedom;
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0, regardless of the parameters.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity,
+     * regardless of the parameters.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the mean of the distribution.
+     *
+     * For denominator degrees of freedom parameter <code>b</code>,
+     * the mean is
+     * <ul>
+     *  <li>if <code>b &gt; 2</code> then <code>b / (b - 2)</code></li>
+     *  <li>else <code>undefined</code>
+     * </ul>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        final double denominatorDF = getDenominatorDegreesOfFreedom();
+
+        if (denominatorDF > 2) {
+            return denominatorDF / (denominatorDF - 2);
+        }
+
+        return Double.NaN;
+    }
+
+    /**
+     * Returns the variance of the distribution.
+     *
+     * For numerator degrees of freedom parameter <code>a</code>
+     * and denominator degrees of freedom parameter <code>b</code>,
+     * the variance is
+     * <ul>
+     *  <li>
+     *    if <code>b &gt; 4</code> then
+     *    <code>[ 2 * b^2 * (a + b - 2) ] / [ a * (b - 2)^2 * (b - 4) ]</code>
+     *  </li>
+     *  <li>else <code>undefined</code>
+     * </ul>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double denominatorDF = getDenominatorDegreesOfFreedom();
+
+        if (denominatorDF > 4) {
+            final double numeratorDF = getNumeratorDegreesOfFreedom();
+            final double denomDFMinusTwo = denominatorDF - 2;
+
+            return ( 2 * (denominatorDF * denominatorDF) * (numeratorDF + denominatorDF - 2) ) /
+                    ( (numeratorDF * (denomDFMinusTwo * denomDFMinusTwo) * (denominatorDF - 4)) );
+        }
+
+        return Double.NaN;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/GammaDistribution.java b/src/main/java/org/apache/commons/math/distribution/GammaDistribution.java
new file mode 100644
index 0000000..71f8f78
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/GammaDistribution.java
@@ -0,0 +1,67 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Gamma Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/GammaDistribution.html">
+ * Gamma Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface GammaDistribution extends ContinuousDistribution, HasDensity<Double> {
+    /**
+     * Modify the shape parameter, alpha.
+     * @param alpha the new shape parameter.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setAlpha(double alpha);
+
+    /**
+     * Access the shape parameter, alpha
+     * @return alpha.
+     */
+    double getAlpha();
+
+    /**
+     * Modify the scale parameter, beta.
+     * @param beta the new scale parameter.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setBeta(double beta);
+
+    /**
+     * Access the scale parameter, beta
+     * @return beta.
+     */
+    double getBeta();
+
+    /**
+     * Return the probability density for a particular point.
+     * @param x  The point at which the density should be computed.
+     * @return  The pdf at point x.
+     */
+    double density(Double x);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/GammaDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/GammaDistributionImpl.java
new file mode 100644
index 0000000..a187892
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/GammaDistributionImpl.java
@@ -0,0 +1,355 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Gamma;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * The default implementation of {@link GammaDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class GammaDistributionImpl extends AbstractContinuousDistribution
+    implements GammaDistribution, Serializable  {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3239549463135430361L;
+
+    /** The shape parameter. */
+    private double alpha;
+
+    /** The scale parameter. */
+    private double beta;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Create a new gamma distribution with the given alpha and beta values.
+     * @param alpha the shape parameter.
+     * @param beta the scale parameter.
+     */
+    public GammaDistributionImpl(double alpha, double beta) {
+        this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Create a new gamma distribution with the given alpha and beta values.
+     * @param alpha the shape parameter.
+     * @param beta the scale parameter.
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public GammaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) {
+        super();
+        setAlphaInternal(alpha);
+        setBetaInternal(beta);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; x).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/Chi-SquaredDistribution.html">
+     * Chi-Squared Distribution</a>, equation (9).</li>
+     * <li>Casella, G., & Berger, R. (1990). <i>Statistical Inference</i>.
+     * Belmont, CA: Duxbury Press.</li>
+     * </ul>
+     *
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF for this distribution.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    public double cumulativeProbability(double x) throws MathException{
+        double ret;
+
+        if (x <= 0.0) {
+            ret = 0.0;
+        } else {
+            ret = Gamma.regularizedGammaP(alpha, x / beta);
+        }
+
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(final double p)
+    throws MathException {
+        if (p == 0) {
+            return 0d;
+        }
+        if (p == 1) {
+            return Double.POSITIVE_INFINITY;
+        }
+        return super.inverseCumulativeProbability(p);
+    }
+
+    /**
+     * Modify the shape parameter, alpha.
+     * @param alpha the new shape parameter.
+     * @throws IllegalArgumentException if <code>alpha</code> is not positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setAlpha(double alpha) {
+        setAlphaInternal(alpha);
+    }
+
+    /**
+     * Modify the shape parameter, alpha.
+     * @param newAlpha the new shape parameter.
+     * @throws IllegalArgumentException if <code>newAlpha</code> is not positive.
+     */
+    private void setAlphaInternal(double newAlpha) {
+        if (newAlpha <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_ALPHA,
+                  newAlpha);
+        }
+        this.alpha = newAlpha;
+    }
+
+    /**
+     * Access the shape parameter, alpha
+     * @return alpha.
+     */
+    public double getAlpha() {
+        return alpha;
+    }
+
+    /**
+     * Modify the scale parameter, beta.
+     * @param newBeta the new scale parameter.
+     * @throws IllegalArgumentException if <code>newBeta</code> is not positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setBeta(double newBeta) {
+        setBetaInternal(newBeta);
+    }
+
+    /**
+     * Modify the scale parameter, beta.
+     * @param newBeta the new scale parameter.
+     * @throws IllegalArgumentException if <code>newBeta</code> is not positive.
+     */
+    private void setBetaInternal(double newBeta) {
+        if (newBeta <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_BETA,
+                  newBeta);
+        }
+        this.beta = newBeta;
+    }
+
+    /**
+     * Access the scale parameter, beta
+     * @return beta.
+     */
+    public double getBeta() {
+        return beta;
+    }
+
+    /**
+     * Returns the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     */
+    @Override
+    public double density(double x) {
+        if (x < 0) return 0;
+        return FastMath.pow(x / beta, alpha - 1) / beta * FastMath.exp(-x / beta) / FastMath.exp(Gamma.logGamma(alpha));
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @deprecated
+     */
+    @Deprecated
+    public double density(Double x) {
+        return density(x.doubleValue());
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        // TODO: try to improve on this estimate
+        return Double.MIN_VALUE;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        // TODO: try to improve on this estimate
+        // NOTE: gamma is skewed to the left
+        // NOTE: therefore, P(X < &mu;) > .5
+
+        double ret;
+
+        if (p < .5) {
+            // use mean
+            ret = alpha * beta;
+        } else {
+            // use max value
+            ret = Double.MAX_VALUE;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        // TODO: try to improve on this estimate
+        // Gamma is skewed to the left, therefore, P(X < &mu;) > .5
+
+        double ret;
+
+        if (p < .5) {
+            // use 1/2 mean
+            ret = alpha * beta * .5;
+        } else {
+            // use mean
+            ret = alpha * beta;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0, regardless of the parameters.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity,
+     * regardless of the parameters.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For shape parameter <code>alpha</code> and scale
+     * parameter <code>beta</code>, the mean is
+     * <code>alpha * beta</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        return getAlpha() * getBeta();
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For shape parameter <code>alpha</code> and scale
+     * parameter <code>beta</code>, the variance is
+     * <code>alpha * beta^2</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double b = getBeta();
+        return getAlpha() * b * b;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/HasDensity.java b/src/main/java/org/apache/commons/math/distribution/HasDensity.java
new file mode 100644
index 0000000..0e15c6c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/HasDensity.java
@@ -0,0 +1,45 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * <p>Interface that signals that a distribution can compute the probability density function
+ * for a particular point.
+ * @param <P> the type of the point at which density is to be computed, this
+ * may be for example <code>Double.</code></p>
+ *
+ * <p>This interface is deprecated.  As of version 2.0, the {@link ContinuousDistribution}
+ * interface will be extended to include a <code>density(double)<code> method.</p>
+ *
+ * @deprecated to be removed in math 3.0
+ * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $
+ */
+@Deprecated
+public interface HasDensity<P> {
+
+    /**
+     * Compute the probability density function.
+     * @param x point for which the probability density is requested
+     * @return probability density at point x
+     * @throws MathException if probability density cannot be computed at specifed point
+     */
+    double density(P x) throws MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/HypergeometricDistribution.java b/src/main/java/org/apache/commons/math/distribution/HypergeometricDistribution.java
new file mode 100644
index 0000000..d3595e0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/HypergeometricDistribution.java
@@ -0,0 +1,76 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Hypergeometric Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/HypergeometricDistribution.html">
+ * Hypergeometric Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface HypergeometricDistribution extends IntegerDistribution {
+
+    /**
+     * Access the number of successes.
+     * @return the number of successes.
+     */
+    int getNumberOfSuccesses();
+
+    /**
+     * Access the population size.
+     * @return the population size.
+     */
+    int getPopulationSize();
+
+    /**
+     * Access the sample size.
+     * @return the sample size.
+     */
+    int getSampleSize();
+
+    /**
+     * Modify the number of successes.
+     * @param num the new number of successes.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setNumberOfSuccesses(int num);
+
+    /**
+     * Modify the population size.
+     * @param size the new population size.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setPopulationSize(int size);
+
+    /**
+     * Modify the sample size.
+     * @param size the new sample size.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setSampleSize(int size);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
new file mode 100644
index 0000000..f9dff2d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
@@ -0,0 +1,421 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * The default implementation of {@link HypergeometricDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
+        implements HypergeometricDistribution, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -436928820673516179L;
+
+    /** The number of successes in the population. */
+    private int numberOfSuccesses;
+
+    /** The population size. */
+    private int populationSize;
+
+    /** The sample size. */
+    private int sampleSize;
+
+    /**
+     * Construct a new hypergeometric distribution with the given the population
+     * size, the number of successes in the population, and the sample size.
+     *
+     * @param populationSize the population size.
+     * @param numberOfSuccesses number of successes in the population.
+     * @param sampleSize the sample size.
+     */
+    public HypergeometricDistributionImpl(int populationSize,
+            int numberOfSuccesses, int sampleSize) {
+        super();
+        if (numberOfSuccesses > populationSize) {
+            throw MathRuntimeException
+                    .createIllegalArgumentException(
+                            LocalizedFormats.NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE,
+                            numberOfSuccesses, populationSize);
+        }
+        if (sampleSize > populationSize) {
+            throw MathRuntimeException
+                    .createIllegalArgumentException(
+                            LocalizedFormats.SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE,
+                            sampleSize, populationSize);
+        }
+
+        setPopulationSizeInternal(populationSize);
+        setSampleSizeInternal(sampleSize);
+        setNumberOfSuccessesInternal(numberOfSuccesses);
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &le; x).
+     *
+     * @param x the value at which the PDF is evaluated.
+     * @return PDF for this distribution.
+     */
+    @Override
+    public double cumulativeProbability(int x) {
+        double ret;
+
+        int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize);
+        if (x < domain[0]) {
+            ret = 0.0;
+        } else if (x >= domain[1]) {
+            ret = 1.0;
+        } else {
+            ret = innerCumulativeProbability(domain[0], x, 1, populationSize,
+                                             numberOfSuccesses, sampleSize);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Return the domain for the given hypergeometric distribution parameters.
+     *
+     * @param n the population size.
+     * @param m number of successes in the population.
+     * @param k the sample size.
+     * @return a two element array containing the lower and upper bounds of the
+     *         hypergeometric distribution.
+     */
+    private int[] getDomain(int n, int m, int k) {
+        return new int[] { getLowerDomain(n, m, k), getUpperDomain(m, k) };
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e. P(X &lt; <i>lower bound</i>) &lt;
+     *         <code>p</code>
+     */
+    @Override
+    protected int getDomainLowerBound(double p) {
+        return getLowerDomain(populationSize, numberOfSuccesses, sampleSize);
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e. P(X &lt; <i>upper bound</i>) &gt;
+     *         <code>p</code>
+     */
+    @Override
+    protected int getDomainUpperBound(double p) {
+        return getUpperDomain(sampleSize, numberOfSuccesses);
+    }
+
+    /**
+     * Return the lowest domain value for the given hypergeometric distribution
+     * parameters.
+     *
+     * @param n the population size.
+     * @param m number of successes in the population.
+     * @param k the sample size.
+     * @return the lowest domain value of the hypergeometric distribution.
+     */
+    private int getLowerDomain(int n, int m, int k) {
+        return FastMath.max(0, m - (n - k));
+    }
+
+    /**
+     * Access the number of successes.
+     *
+     * @return the number of successes.
+     */
+    public int getNumberOfSuccesses() {
+        return numberOfSuccesses;
+    }
+
+    /**
+     * Access the population size.
+     *
+     * @return the population size.
+     */
+    public int getPopulationSize() {
+        return populationSize;
+    }
+
+    /**
+     * Access the sample size.
+     *
+     * @return the sample size.
+     */
+    public int getSampleSize() {
+        return sampleSize;
+    }
+
+    /**
+     * Return the highest domain value for the given hypergeometric distribution
+     * parameters.
+     *
+     * @param m number of successes in the population.
+     * @param k the sample size.
+     * @return the highest domain value of the hypergeometric distribution.
+     */
+    private int getUpperDomain(int m, int k) {
+        return FastMath.min(k, m);
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X = x).
+     *
+     * @param x the value at which the PMF is evaluated.
+     * @return PMF for this distribution.
+     */
+    public double probability(int x) {
+        double ret;
+
+        int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize);
+        if (x < domain[0] || x > domain[1]) {
+            ret = 0.0;
+        } else {
+            double p = (double) sampleSize / (double) populationSize;
+            double q = (double) (populationSize - sampleSize) / (double) populationSize;
+            double p1 = SaddlePointExpansion.logBinomialProbability(x,
+                    numberOfSuccesses, p, q);
+            double p2 =
+                SaddlePointExpansion.logBinomialProbability(sampleSize - x,
+                    populationSize - numberOfSuccesses, p, q);
+            double p3 =
+                SaddlePointExpansion.logBinomialProbability(sampleSize, populationSize, p, q);
+            ret = FastMath.exp(p1 + p2 - p3);
+        }
+
+        return ret;
+    }
+
+    /**
+     * For the distribution, X, defined by the given hypergeometric distribution
+     * parameters, this method returns P(X = x).
+     *
+     * @param n the population size.
+     * @param m number of successes in the population.
+     * @param k the sample size.
+     * @param x the value at which the PMF is evaluated.
+     * @return PMF for the distribution.
+     */
+    private double probability(int n, int m, int k, int x) {
+        return FastMath.exp(MathUtils.binomialCoefficientLog(m, x) +
+               MathUtils.binomialCoefficientLog(n - m, k - x) -
+               MathUtils.binomialCoefficientLog(n, k));
+    }
+
+    /**
+     * Modify the number of successes.
+     *
+     * @param num the new number of successes.
+     * @throws IllegalArgumentException if <code>num</code> is negative.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setNumberOfSuccesses(int num) {
+        setNumberOfSuccessesInternal(num);
+    }
+
+    /**
+     * Modify the number of successes.
+     *
+     * @param num the new number of successes.
+     * @throws IllegalArgumentException if <code>num</code> is negative.
+     */
+    private void setNumberOfSuccessesInternal(int num) {
+        if (num < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NEGATIVE_NUMBER_OF_SUCCESSES, num);
+        }
+        numberOfSuccesses = num;
+    }
+
+    /**
+     * Modify the population size.
+     *
+     * @param size the new population size.
+     * @throws IllegalArgumentException if <code>size</code> is not positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setPopulationSize(int size) {
+        setPopulationSizeInternal(size);
+    }
+
+    /**
+     * Modify the population size.
+     *
+     * @param size the new population size.
+     * @throws IllegalArgumentException if <code>size</code> is not positive.
+     */
+    private void setPopulationSizeInternal(int size) {
+        if (size <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POSITIVE_POPULATION_SIZE, size);
+        }
+        populationSize = size;
+    }
+
+    /**
+     * Modify the sample size.
+     *
+     * @param size the new sample size.
+     * @throws IllegalArgumentException if <code>size</code> is negative.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setSampleSize(int size) {
+        setSampleSizeInternal(size);
+    }
+    /**
+     * Modify the sample size.
+     *
+     * @param size the new sample size.
+     * @throws IllegalArgumentException if <code>size</code> is negative.
+     */
+    private void setSampleSizeInternal(int size) {
+        if (size < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, size);
+        }
+        sampleSize = size;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &ge; x).
+     *
+     * @param x the value at which the CDF is evaluated.
+     * @return upper tail CDF for this distribution.
+     * @since 1.1
+     */
+    public double upperCumulativeProbability(int x) {
+        double ret;
+
+        final int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize);
+        if (x < domain[0]) {
+            ret = 1.0;
+        } else if (x > domain[1]) {
+            ret = 0.0;
+        } else {
+            ret = innerCumulativeProbability(domain[1], x, -1, populationSize, numberOfSuccesses, sampleSize);
+        }
+
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(x0 &le; X &le; x1). This
+     * probability is computed by summing the point probabilities for the values
+     * x0, x0 + 1, x0 + 2, ..., x1, in the order directed by dx.
+     *
+     * @param x0 the inclusive, lower bound
+     * @param x1 the inclusive, upper bound
+     * @param dx the direction of summation. 1 indicates summing from x0 to x1.
+     *            0 indicates summing from x1 to x0.
+     * @param n the population size.
+     * @param m number of successes in the population.
+     * @param k the sample size.
+     * @return P(x0 &le; X &le; x1).
+     */
+    private double innerCumulativeProbability(int x0, int x1, int dx, int n,
+            int m, int k) {
+        double ret = probability(n, m, k, x0);
+        while (x0 != x1) {
+            x0 += dx;
+            ret += probability(n, m, k, x0);
+        }
+        return ret;
+    }
+
+    /**
+     * Returns the lower bound for the support for the distribution.
+     *
+     * For population size <code>N</code>,
+     * number of successes <code>m</code>, and
+     * sample size <code>n</code>,
+     * the lower bound of the support is
+     * <code>max(0, n + m - N)</code>
+     *
+     * @return lower bound of the support
+     * @since 2.2
+     */
+    public int getSupportLowerBound() {
+        return FastMath.max(0,
+                getSampleSize() + getNumberOfSuccesses() - getPopulationSize());
+    }
+
+    /**
+     * Returns the upper bound for the support of the distribution.
+     *
+     * For number of successes <code>m</code> and
+     * sample size <code>n</code>,
+     * the upper bound of the support is
+     * <code>min(m, n)</code>
+     *
+     * @return upper bound of the support
+     * @since 2.2
+     */
+    public int getSupportUpperBound() {
+        return FastMath.min(getNumberOfSuccesses(), getSampleSize());
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For population size <code>N</code>,
+     * number of successes <code>m</code>, and
+     * sample size <code>n</code>, the mean is
+     * <code>n * m / N</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    protected double getNumericalMean() {
+        return (double)(getSampleSize() * getNumberOfSuccesses()) / (double)getPopulationSize();
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For population size <code>N</code>,
+     * number of successes <code>m</code>, and
+     * sample size <code>n</code>, the variance is
+     * <code>[ n * m * (N - n) * (N - m) ] / [ N^2 * (N - 1) ]</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double N = getPopulationSize();
+        final double m = getNumberOfSuccesses();
+        final double n = getSampleSize();
+        return ( n * m * (N - n) * (N - m) ) / ( (N*N * (N - 1)) );
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/IntegerDistribution.java b/src/main/java/org/apache/commons/math/distribution/IntegerDistribution.java
new file mode 100644
index 0000000..096af17
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/IntegerDistribution.java
@@ -0,0 +1,84 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Interface for discrete distributions of integer-valued random variables.
+ *
+ * @version $Revision: 949535 $ $Date: 2010-05-30 19:00:15 +0200 (dim. 30 mai 2010) $
+ */
+public interface IntegerDistribution extends DiscreteDistribution {
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X = x). In other words, this
+     * method represents the probability mass function for the distribution.
+     *
+     * @param x the value at which the probability density function is evaluated.
+     * @return the value of the probability density function at x
+     */
+    double probability(int x);
+
+    /**
+     * For a random variable X whose values are distributed according
+     * to this distribution, this method returns P(X &le; x).  In other words,
+     * this method represents the probability distribution function, or PDF
+     * for the distribution.
+     *
+     * @param x the value at which the PDF is evaluated.
+     * @return PDF for this distribution.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    double cumulativeProbability(int x) throws MathException;
+
+    /**
+     * For this distribution, X, this method returns P(x0 &le; X &le; x1).
+     * @param x0 the inclusive, lower bound
+     * @param x1 the inclusive, upper bound
+     * @return the cumulative probability.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if x0 > x1
+     */
+    double cumulativeProbability(int x0, int x1) throws MathException;
+
+    /**
+     * For this distribution, X, this method returns the largest x such that
+     * P(X &le; x) <= p.
+     * <p>
+     * Note that this definition implies: <ul>
+     * <li> If there is a minimum value, <code>m</code>, with positive
+     * probability under (the density of) X, then <code>m - 1</code> is
+     * returned by <code>inverseCumulativeProbability(0).</code>  If there is
+     * no such value <code>m,  Integer.MIN_VALUE</code> is
+     * returned.</li>
+     * <li> If there is a maximum value, <code>M</code>, such that
+     * P(X &le; M) =1, then <code>M</code> is returned by
+     * <code>inverseCumulativeProbability(1).</code>
+     * If there is no such value, <code>M, Integer.MAX_VALUE</code> is
+     * returned.</li></ul></p>
+     *
+     * @param p the cumulative probability.
+     * @return the largest x such that P(X &le; x) <= p
+     * @throws MathException if the inverse cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if p is not between 0 and 1 (inclusive)
+     */
+    int inverseCumulativeProbability(double p) throws MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/NormalDistribution.java b/src/main/java/org/apache/commons/math/distribution/NormalDistribution.java
new file mode 100644
index 0000000..67f5d5c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/NormalDistribution.java
@@ -0,0 +1,65 @@
+/*
+ * 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.distribution;
+
+/**
+ * Normal (Gauss) Distribution.
+ *
+ * <p>
+ * References:</p><p>
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/NormalDistribution.html">
+ * Normal Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface NormalDistribution extends ContinuousDistribution, HasDensity<Double> {
+    /**
+     * Access the mean.
+     * @return mean for this distribution
+     */
+    double getMean();
+    /**
+     * Modify the mean.
+     * @param mean for this distribution
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setMean(double mean);
+    /**
+     * Access the standard deviation.
+     * @return standard deviation for this distribution
+     */
+    double getStandardDeviation();
+    /**
+     * Modify the standard deviation.
+     * @param sd standard deviation for this distribution
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setStandardDeviation(double sd);
+
+    /**
+     * Return the probability density for a particular point.
+     * @param x  The point at which the density should be computed.
+     * @return  The pdf at point x.
+     */
+    double density(Double x);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java
new file mode 100644
index 0000000..1164649
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/NormalDistributionImpl.java
@@ -0,0 +1,349 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Erf;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Default implementation of
+ * {@link org.apache.commons.math.distribution.NormalDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class NormalDistributionImpl extends AbstractContinuousDistribution
+        implements NormalDistribution, Serializable {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 8589540077390120676L;
+
+    /** &sqrt;(2 &pi;) */
+    private static final double SQRT2PI = FastMath.sqrt(2 * FastMath.PI);
+
+    /** The mean of this distribution. */
+    private double mean = 0;
+
+    /** The standard deviation of this distribution. */
+    private double standardDeviation = 1;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Create a normal distribution using the given mean and standard deviation.
+     * @param mean mean for this distribution
+     * @param sd standard deviation for this distribution
+     */
+    public NormalDistributionImpl(double mean, double sd){
+        this(mean, sd, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Create a normal distribution using the given mean, standard deviation and
+     * inverse cumulative distribution accuracy.
+     *
+     * @param mean mean for this distribution
+     * @param sd standard deviation for this distribution
+     * @param inverseCumAccuracy inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public NormalDistributionImpl(double mean, double sd, double inverseCumAccuracy) {
+        super();
+        setMeanInternal(mean);
+        setStandardDeviationInternal(sd);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * Creates normal distribution with the mean equal to zero and standard
+     * deviation equal to one.
+     */
+    public NormalDistributionImpl(){
+        this(0.0, 1.0);
+    }
+
+    /**
+     * Access the mean.
+     * @return mean for this distribution
+     */
+    public double getMean() {
+        return mean;
+    }
+
+    /**
+     * Modify the mean.
+     * @param mean for this distribution
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setMean(double mean) {
+        setMeanInternal(mean);
+    }
+
+    /**
+     * Modify the mean.
+     * @param newMean for this distribution
+     */
+    private void setMeanInternal(double newMean) {
+        this.mean = newMean;
+    }
+
+    /**
+     * Access the standard deviation.
+     * @return standard deviation for this distribution
+     */
+    public double getStandardDeviation() {
+        return standardDeviation;
+    }
+
+    /**
+     * Modify the standard deviation.
+     * @param sd standard deviation for this distribution
+     * @throws IllegalArgumentException if <code>sd</code> is not positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setStandardDeviation(double sd) {
+        setStandardDeviationInternal(sd);
+    }
+
+    /**
+     * Modify the standard deviation.
+     * @param sd standard deviation for this distribution
+     * @throws IllegalArgumentException if <code>sd</code> is not positive.
+     */
+    private void setStandardDeviationInternal(double sd) {
+        if (sd <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_STANDARD_DEVIATION,
+                  sd);
+        }
+        standardDeviation = sd;
+    }
+
+    /**
+     * Return the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @deprecated
+     */
+    @Deprecated
+    public double density(Double x) {
+        return density(x.doubleValue());
+    }
+
+    /**
+     * Returns the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        double x0 = x - mean;
+        return FastMath.exp(-x0 * x0 / (2 * standardDeviation * standardDeviation)) / (standardDeviation * SQRT2PI);
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; <code>x</code>).
+     * If <code>x</code>is more than 40 standard deviations from the mean, 0 or 1 is returned,
+     * as in these cases the actual value is within <code>Double.MIN_VALUE</code> of 0 or 1.
+     *
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF evaluated at <code>x</code>.
+     * @throws MathException if the algorithm fails to converge
+     */
+    public double cumulativeProbability(double x) throws MathException {
+        final double dev = x - mean;
+        if (FastMath.abs(dev) > 40 * standardDeviation) {
+            return dev < 0 ? 0.0d : 1.0d;
+        }
+        return 0.5 * (1.0 + Erf.erf(dev /
+                    (standardDeviation * FastMath.sqrt(2.0))));
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
+     * <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(final double p)
+    throws MathException {
+        if (p == 0) {
+            return Double.NEGATIVE_INFINITY;
+        }
+        if (p == 1) {
+            return Double.POSITIVE_INFINITY;
+        }
+        return super.inverseCumulativeProbability(p);
+    }
+
+    /**
+     * Generates a random value sampled from this distribution.
+     *
+     * @return random value
+     * @since 2.2
+     * @throws MathException if an error occurs generating the random value
+     */
+    @Override
+    public double sample() throws MathException {
+        return randomData.nextGaussian(mean, standardDeviation);
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        double ret;
+
+        if (p < .5) {
+            ret = -Double.MAX_VALUE;
+        } else {
+            ret = mean;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        double ret;
+
+        if (p < .5) {
+            ret = mean;
+        } else {
+            ret = Double.MAX_VALUE;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        double ret;
+
+        if (p < .5) {
+            ret = mean - standardDeviation;
+        } else if (p > .5) {
+            ret = mean + standardDeviation;
+        } else {
+            ret = mean;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always negative infinity
+     * no matter the parameters.
+     *
+     * @return lower bound of the support (always Double.NEGATIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return Double.NEGATIVE_INFINITY;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity
+     * no matter the parameters.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For standard deviation parameter <code>s</code>,
+     * the variance is <code>s^2</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double s = getStandardDeviation();
+        return s * s;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/PascalDistribution.java b/src/main/java/org/apache/commons/math/distribution/PascalDistribution.java
new file mode 100644
index 0000000..88c5924
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/PascalDistribution.java
@@ -0,0 +1,73 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Pascal distribution.  The Pascal distribution is a special case of the
+ * Negative Binomial distribution where the number of successes parameter is an
+ * integer.
+ *
+ * There are various ways to express the probability mass and distribution
+ * functions for the Pascal distribution.  The convention employed by the
+ * library is to express these functions in terms of the number of failures in
+ * a Bernoulli experiment [2].
+ *
+ * <p>
+ * References:
+ * <ol>
+ * <li><a href="http://mathworld.wolfram.com/NegativeBinomialDistribution.html">
+ * Negative Binomial Distribution</a></li>
+ * <oi><a href="http://en.wikipedia.org/wiki/Negative_binomial_distribution#Waiting_time_in_a_Bernoulli_process">Waiting Time in a Bernoulli Process</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ * @since 1.2
+ */
+public interface PascalDistribution extends IntegerDistribution {
+    /**
+     * Access the number of successes for this distribution.
+     *
+     * @return the number of successes
+     */
+    int getNumberOfSuccesses();
+
+    /**
+     * Access the probability of success for this distribution.
+     *
+     * @return the probability of success
+     */
+    double getProbabilityOfSuccess();
+
+    /**
+     * Change the number of successes for this distribution.
+     *
+     * @param successes the new number of successes
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setNumberOfSuccesses(int successes);
+
+    /**
+     * Change the probability of success for this distribution.
+     *
+     * @param p the new probability of success
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setProbabilityOfSuccess(double p);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java
new file mode 100644
index 0000000..437cbc7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/PascalDistributionImpl.java
@@ -0,0 +1,276 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Beta;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * The default implementation of {@link PascalDistribution}.
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ * @since 1.2
+ */
+public class PascalDistributionImpl extends AbstractIntegerDistribution
+    implements PascalDistribution, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 6751309484392813623L;
+
+    /** The number of successes */
+    private int numberOfSuccesses;
+
+    /** The probability of success */
+    private double probabilityOfSuccess;
+
+    /**
+     * Create a Pascal distribution with the given number of trials and
+     * probability of success.
+     * @param r the number of successes
+     * @param p the probability of success
+     */
+    public PascalDistributionImpl(int r, double p) {
+        super();
+        setNumberOfSuccessesInternal(r);
+        setProbabilityOfSuccessInternal(p);
+    }
+
+    /**
+     * Access the number of successes for this distribution.
+     * @return the number of successes
+     */
+    public int getNumberOfSuccesses() {
+        return numberOfSuccesses;
+    }
+
+    /**
+     * Access the probability of success for this distribution.
+     * @return the probability of success
+     */
+    public double getProbabilityOfSuccess() {
+        return probabilityOfSuccess;
+    }
+
+    /**
+     * Change the number of successes for this distribution.
+     * @param successes the new number of successes
+     * @throws IllegalArgumentException if <code>successes</code> is not
+     *         positive.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setNumberOfSuccesses(int successes) {
+        setNumberOfSuccessesInternal(successes);
+    }
+
+    /**
+     * Change the number of successes for this distribution.
+     * @param successes the new number of successes
+     * @throws IllegalArgumentException if <code>successes</code> is not
+     *         positive.
+     */
+    private void setNumberOfSuccessesInternal(int successes) {
+        if (successes < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NEGATIVE_NUMBER_OF_SUCCESSES,
+                  successes);
+        }
+        numberOfSuccesses = successes;
+    }
+
+    /**
+     * Change the probability of success for this distribution.
+     * @param p the new probability of success
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setProbabilityOfSuccess(double p) {
+        setProbabilityOfSuccessInternal(p);
+    }
+
+    /**
+     * Change the probability of success for this distribution.
+     * @param p the new probability of success
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    private void setProbabilityOfSuccessInternal(double p) {
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        }
+        probabilityOfSuccess = p;
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e. P(X &lt; <i>lower bound</i>) &lt;
+     *         <code>p</code>
+     */
+    @Override
+    protected int getDomainLowerBound(double p) {
+        return -1;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e. P(X &lt; <i>upper bound</i>) &gt;
+     *         <code>p</code>
+     */
+    @Override
+    protected int getDomainUpperBound(double p) {
+        // use MAX - 1 because MAX causes loop
+        return Integer.MAX_VALUE - 1;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &le; x).
+     * @param x the value at which the PDF is evaluated
+     * @return PDF for this distribution
+     * @throws MathException if the cumulative probability can not be computed
+     *         due to convergence or other numerical errors
+     */
+    @Override
+    public double cumulativeProbability(int x) throws MathException {
+        double ret;
+        if (x < 0) {
+            ret = 0.0;
+        } else {
+            ret = Beta.regularizedBeta(probabilityOfSuccess,
+                numberOfSuccesses, x + 1);
+        }
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X = x).
+     * @param x the value at which the PMF is evaluated
+     * @return PMF for this distribution
+     */
+    public double probability(int x) {
+        double ret;
+        if (x < 0) {
+            ret = 0.0;
+        } else {
+            ret = MathUtils.binomialCoefficientDouble(x +
+                  numberOfSuccesses - 1, numberOfSuccesses - 1) *
+                  FastMath.pow(probabilityOfSuccess, numberOfSuccesses) *
+                  FastMath.pow(1.0 - probabilityOfSuccess, x);
+        }
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns the largest x, such that
+     * P(X &le; x) &le; <code>p</code>.
+     * <p>
+     * Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code>
+     * for p=1.</p>
+     * @param p the desired probability
+     * @return the largest x such that P(X &le; x) <= p
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if p < 0 or p > 1
+     */
+    @Override
+    public int inverseCumulativeProbability(final double p)
+        throws MathException {
+        int ret;
+
+        // handle extreme values explicitly
+        if (p == 0) {
+            ret = -1;
+        } else if (p == 1) {
+            ret = Integer.MAX_VALUE;
+        } else {
+            ret = super.inverseCumulativeProbability(p);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0 no matter the parameters.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public int getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity
+     * no matter the parameters. Positive infinity is represented
+     * by <code>Integer.MAX_VALUE</code> together with
+     * {@link #isSupportUpperBoundInclusive()} being <code>false</code>
+     *
+     * @return upper bound of the support (always <code>Integer.MAX_VALUE</code> for positive infinity)
+     * @since 2.2
+     */
+    public int getSupportUpperBound() {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For number of successes <code>r</code> and
+     * probability of success <code>p</code>, the mean is
+     * <code>( r * p ) / ( 1 - p )</code>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        final double p = getProbabilityOfSuccess();
+        final double r = getNumberOfSuccesses();
+        return ( r * p ) / ( 1 - p );
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For number of successes <code>r</code> and
+     * probability of success <code>p</code>, the mean is
+     * <code>( r * p ) / ( 1 - p )^2</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double p = getProbabilityOfSuccess();
+        final double r = getNumberOfSuccesses();
+        final double pInv = 1 - p;
+        return ( r * p ) / (pInv * pInv);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/PoissonDistribution.java b/src/main/java/org/apache/commons/math/distribution/PoissonDistribution.java
new file mode 100644
index 0000000..b3a2f12
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/PoissonDistribution.java
@@ -0,0 +1,64 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Interface representing the Poisson Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/PoissonDistribution.html">
+ * Poisson distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface PoissonDistribution extends IntegerDistribution {
+
+    /**
+     * Get the mean for the distribution.
+     *
+     * @return the mean for the distribution.
+     */
+    double getMean();
+
+    /**
+     * Set the mean for the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgument</code> is thrown.
+     *
+     * @param p the mean
+     * @throws IllegalArgumentException if p &le; 0
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setMean(double p);
+
+    /**
+     * Calculates the Poisson distribution function using a normal approximation.
+     *
+     * @param x the upper bound, inclusive
+     * @return the distribution function value calculated using a normal approximation
+     * @throws MathException if an error occurs computing the normal approximation
+     */
+    double normalApproximateProbability(int x) throws MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java
new file mode 100644
index 0000000..85623d4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/PoissonDistributionImpl.java
@@ -0,0 +1,343 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Gamma;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implementation for the {@link PoissonDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class PoissonDistributionImpl extends AbstractIntegerDistribution
+        implements PoissonDistribution, Serializable {
+
+    /**
+     * Default maximum number of iterations for cumulative probability calculations.
+     * @since 2.1
+     */
+    public static final int DEFAULT_MAX_ITERATIONS = 10000000;
+
+    /**
+     * Default convergence criterion.
+     * @since 2.1
+     */
+    public static final double DEFAULT_EPSILON = 1E-12;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3349935121172596109L;
+
+    /** Distribution used to compute normal approximation. */
+    private NormalDistribution normal;
+
+    /**
+     * Holds the Poisson mean for the distribution.
+     */
+    private double mean;
+
+    /**
+     * Maximum number of iterations for cumulative probability.
+     *
+     * Cumulative probabilities are estimated using either Lanczos series approximation of
+     * Gamma#regularizedGammaP or continued fraction approximation of Gamma#regularizedGammaQ.
+     */
+    private int maxIterations = DEFAULT_MAX_ITERATIONS;
+
+    /**
+     * Convergence criterion for cumulative probability.
+     */
+    private double epsilon = DEFAULT_EPSILON;
+
+    /**
+     * Create a new Poisson distribution with the given the mean. The mean value
+     * must be positive; otherwise an <code>IllegalArgument</code> is thrown.
+     *
+     * @param p the Poisson mean
+     * @throws IllegalArgumentException if p &le; 0
+     */
+    public PoissonDistributionImpl(double p) {
+        this(p, new NormalDistributionImpl());
+    }
+
+    /**
+     * Create a new Poisson distribution with the given mean, convergence criterion
+     * and maximum number of iterations.
+     *
+     * @param p the Poisson mean
+     * @param epsilon the convergence criteria for cumulative probabilites
+     * @param maxIterations the maximum number of iterations for cumulative probabilites
+     * @since 2.1
+     */
+    public PoissonDistributionImpl(double p, double epsilon, int maxIterations) {
+        setMean(p);
+        this.epsilon = epsilon;
+        this.maxIterations = maxIterations;
+    }
+
+    /**
+     * Create a new Poisson distribution with the given mean and convergence criterion.
+     *
+     * @param p the Poisson mean
+     * @param epsilon the convergence criteria for cumulative probabilites
+     * @since 2.1
+     */
+    public PoissonDistributionImpl(double p, double epsilon) {
+        setMean(p);
+        this.epsilon = epsilon;
+    }
+
+    /**
+     * Create a new Poisson distribution with the given mean and maximum number of iterations.
+     *
+     * @param p the Poisson mean
+     * @param maxIterations the maximum number of iterations for cumulative probabilites
+     * @since 2.1
+     */
+    public PoissonDistributionImpl(double p, int maxIterations) {
+        setMean(p);
+        this.maxIterations = maxIterations;
+    }
+
+
+    /**
+     * Create a new Poisson distribution with the given the mean. The mean value
+     * must be positive; otherwise an <code>IllegalArgument</code> is thrown.
+     *
+     * @param p the Poisson mean
+     * @param z a normal distribution used to compute normal approximations.
+     * @throws IllegalArgumentException if p &le; 0
+     * @since 1.2
+     * @deprecated as of 2.1 (to avoid possibly inconsistent state, the
+     * "NormalDistribution" will be instantiated internally)
+     */
+    @Deprecated
+    public PoissonDistributionImpl(double p, NormalDistribution z) {
+        super();
+        setNormalAndMeanInternal(z, p);
+    }
+
+    /**
+     * Get the Poisson mean for the distribution.
+     *
+     * @return the Poisson mean for the distribution.
+     */
+    public double getMean() {
+        return mean;
+    }
+
+    /**
+     * Set the Poisson mean for the distribution. The mean value must be
+     * positive; otherwise an <code>IllegalArgument</code> is thrown.
+     *
+     * @param p the Poisson mean value
+     * @throws IllegalArgumentException if p &le; 0
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setMean(double p) {
+        setNormalAndMeanInternal(normal, p);
+    }
+    /**
+     * Set the Poisson mean for the distribution. The mean value must be
+     * positive; otherwise an <code>IllegalArgument</code> is thrown.
+     *
+     * @param z the new distribution
+     * @param p the Poisson mean value
+     * @throws IllegalArgumentException if p &le; 0
+     */
+    private void setNormalAndMeanInternal(NormalDistribution z,
+                                          double p) {
+        if (p <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POSITIVE_POISSON_MEAN, p);
+        }
+        mean = p;
+        normal = z;
+        normal.setMean(p);
+        normal.setStandardDeviation(FastMath.sqrt(p));
+    }
+
+    /**
+     * The probability mass function P(X = x) for a Poisson distribution.
+     *
+     * @param x the value at which the probability density function is
+     *            evaluated.
+     * @return the value of the probability mass function at x
+     */
+    public double probability(int x) {
+        double ret;
+        if (x < 0 || x == Integer.MAX_VALUE) {
+            ret = 0.0;
+        } else if (x == 0) {
+            ret = FastMath.exp(-mean);
+        } else {
+            ret = FastMath.exp(-SaddlePointExpansion.getStirlingError(x) -
+                  SaddlePointExpansion.getDeviancePart(x, mean)) /
+                  FastMath.sqrt(MathUtils.TWO_PI * x);
+        }
+        return ret;
+    }
+
+    /**
+     * The probability distribution function P(X <= x) for a Poisson
+     * distribution.
+     *
+     * @param x the value at which the PDF is evaluated.
+     * @return Poisson distribution function evaluated at x
+     * @throws MathException if the cumulative probability can not be computed
+     *             due to convergence or other numerical errors.
+     */
+    @Override
+    public double cumulativeProbability(int x) throws MathException {
+        if (x < 0) {
+            return 0;
+        }
+        if (x == Integer.MAX_VALUE) {
+            return 1;
+        }
+        return Gamma.regularizedGammaQ((double) x + 1, mean, epsilon, maxIterations);
+    }
+
+    /**
+     * Calculates the Poisson distribution function using a normal
+     * approximation. The <code>N(mean, sqrt(mean))</code> distribution is used
+     * to approximate the Poisson distribution.
+     * <p>
+     * The computation uses "half-correction" -- evaluating the normal
+     * distribution function at <code>x + 0.5</code>
+     * </p>
+     *
+     * @param x the upper bound, inclusive
+     * @return the distribution function value calculated using a normal
+     *         approximation
+     * @throws MathException if an error occurs computing the normal
+     *             approximation
+     */
+    public double normalApproximateProbability(int x) throws MathException {
+        // calculate the probability using half-correction
+        return normal.cumulativeProbability(x + 0.5);
+    }
+
+    /**
+     * Generates a random value sampled from this distribution.
+     *
+     * <p><strong>Algorithm Description</strong>:
+     * <ul><li> For small means, uses simulation of a Poisson process
+     * using Uniform deviates, as described
+     * <a href="http://irmi.epfl.ch/cmos/Pmmi/interactive/rng7.htm"> here.</a>
+     * The Poisson process (and hence value returned) is bounded by 1000 * mean.</li><
+     *
+     * <li> For large means, uses the rejection algorithm described in <br/>
+     * Devroye, Luc. (1981).<i>The Computer Generation of Poisson Random Variables</i>
+     * <strong>Computing</strong> vol. 26 pp. 197-207.</li></ul></p>
+     *
+     * @return random value
+     * @since 2.2
+     * @throws MathException if an error occurs generating the random value
+     */
+    @Override
+    public int sample() throws MathException {
+        return (int) FastMath.min(randomData.nextPoisson(mean), Integer.MAX_VALUE);
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root. This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain lower bound
+     */
+    @Override
+    protected int getDomainLowerBound(double p) {
+        return 0;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root. This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain upper bound
+     */
+    @Override
+    protected int getDomainUpperBound(double p) {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * Modify the normal distribution used to compute normal approximations. The
+     * caller is responsible for insuring the normal distribution has the proper
+     * parameter settings.
+     *
+     * @param value the new distribution
+     * @since 1.2
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setNormal(NormalDistribution value) {
+        setNormalAndMeanInternal(value, mean);
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0 no matter the mean parameter.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public int getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is positive infinity,
+     * regardless of the parameter values. There is no integer infinity,
+     * so this method returns <code>Integer.MAX_VALUE</code> and
+     * {@link #isSupportUpperBoundInclusive()} returns <code>true</code>.
+     *
+     * @return upper bound of the support (always <code>Integer.MAX_VALUE</code> for positive infinity)
+     * @since 2.2
+     */
+    public int getSupportUpperBound() {
+        return Integer.MAX_VALUE;
+    }
+
+    /**
+     * Returns the variance of the distribution.
+     *
+     * For mean parameter <code>p</code>, the variance is <code>p</code>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        return getMean();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/SaddlePointExpansion.java b/src/main/java/org/apache/commons/math/distribution/SaddlePointExpansion.java
new file mode 100644
index 0000000..a936123
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/SaddlePointExpansion.java
@@ -0,0 +1,201 @@
+/*
+ * 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.distribution;
+
+import org.apache.commons.math.special.Gamma;
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * <p>
+ * Utility class used by various distributions to accurately compute their
+ * respective probability mass functions. The implementation for this class is
+ * based on the Catherine Loader's <a target="_blank"
+ * href="http://www.herine.net/stat/software/dbinom.html">dbinom</a> routines.
+ * </p>
+ * <p>
+ * This class is not intended to be called directly.
+ * </p>
+ * <p>
+ * References:
+ * <ol>
+ * <li>Catherine Loader (2000). "Fast and Accurate Computation of Binomial
+ * Probabilities.". <a target="_blank"
+ * href="http://www.herine.net/stat/papers/dbinom.pdf">
+ * http://www.herine.net/stat/papers/dbinom.pdf</a></li>
+ * </ol>
+ * </p>
+ *
+ * @since 2.1
+ * @version $Revision$ $Date$
+ */
+final class SaddlePointExpansion {
+
+    /** 1/2 * log(2 &#960;). */
+    private static final double HALF_LOG_2_PI = 0.5 * FastMath.log(MathUtils.TWO_PI);
+
+    /** exact Stirling expansion error for certain values. */
+    private static final double[] EXACT_STIRLING_ERRORS = { 0.0, /* 0.0 */
+    0.1534264097200273452913848, /* 0.5 */
+    0.0810614667953272582196702, /* 1.0 */
+    0.0548141210519176538961390, /* 1.5 */
+    0.0413406959554092940938221, /* 2.0 */
+    0.03316287351993628748511048, /* 2.5 */
+    0.02767792568499833914878929, /* 3.0 */
+    0.02374616365629749597132920, /* 3.5 */
+    0.02079067210376509311152277, /* 4.0 */
+    0.01848845053267318523077934, /* 4.5 */
+    0.01664469118982119216319487, /* 5.0 */
+    0.01513497322191737887351255, /* 5.5 */
+    0.01387612882307074799874573, /* 6.0 */
+    0.01281046524292022692424986, /* 6.5 */
+    0.01189670994589177009505572, /* 7.0 */
+    0.01110455975820691732662991, /* 7.5 */
+    0.010411265261972096497478567, /* 8.0 */
+    0.009799416126158803298389475, /* 8.5 */
+    0.009255462182712732917728637, /* 9.0 */
+    0.008768700134139385462952823, /* 9.5 */
+    0.008330563433362871256469318, /* 10.0 */
+    0.007934114564314020547248100, /* 10.5 */
+    0.007573675487951840794972024, /* 11.0 */
+    0.007244554301320383179543912, /* 11.5 */
+    0.006942840107209529865664152, /* 12.0 */
+    0.006665247032707682442354394, /* 12.5 */
+    0.006408994188004207068439631, /* 13.0 */
+    0.006171712263039457647532867, /* 13.5 */
+    0.005951370112758847735624416, /* 14.0 */
+    0.005746216513010115682023589, /* 14.5 */
+    0.005554733551962801371038690 /* 15.0 */
+    };
+
+    /**
+     * Default constructor.
+     */
+    private SaddlePointExpansion() {
+        super();
+    }
+
+    /**
+     * Compute the error of Stirling's series at the given value.
+     * <p>
+     * References:
+     * <ol>
+     * <li>Eric W. Weisstein. "Stirling's Series." From MathWorld--A Wolfram Web
+     * Resource. <a target="_blank"
+     * href="http://mathworld.wolfram.com/StirlingsSeries.html">
+     * http://mathworld.wolfram.com/StirlingsSeries.html</a></li>
+     * </ol>
+     * </p>
+     *
+     * @param z the value.
+     * @return the Striling's series error.
+     */
+    static double getStirlingError(double z) {
+        double ret;
+        if (z < 15.0) {
+            double z2 = 2.0 * z;
+            if (FastMath.floor(z2) == z2) {
+                ret = EXACT_STIRLING_ERRORS[(int) z2];
+            } else {
+                ret = Gamma.logGamma(z + 1.0) - (z + 0.5) * FastMath.log(z) +
+                      z - HALF_LOG_2_PI;
+            }
+        } else {
+            double z2 = z * z;
+            ret = (0.083333333333333333333 -
+                    (0.00277777777777777777778 -
+                            (0.00079365079365079365079365 -
+                                    (0.000595238095238095238095238 -
+                                            0.0008417508417508417508417508 /
+                                            z2) / z2) / z2) / z2) / z;
+        }
+        return ret;
+    }
+
+    /**
+     * A part of the deviance portion of the saddle point approximation.
+     * <p>
+     * References:
+     * <ol>
+     * <li>Catherine Loader (2000). "Fast and Accurate Computation of Binomial
+     * Probabilities.". <a target="_blank"
+     * href="http://www.herine.net/stat/papers/dbinom.pdf">
+     * http://www.herine.net/stat/papers/dbinom.pdf</a></li>
+     * </ol>
+     * </p>
+     *
+     * @param x the x value.
+     * @param mu the average.
+     * @return a part of the deviance.
+     */
+    static double getDeviancePart(double x, double mu) {
+        double ret;
+        if (FastMath.abs(x - mu) < 0.1 * (x + mu)) {
+            double d = x - mu;
+            double v = d / (x + mu);
+            double s1 = v * d;
+            double s = Double.NaN;
+            double ej = 2.0 * x * v;
+            v = v * v;
+            int j = 1;
+            while (s1 != s) {
+                s = s1;
+                ej *= v;
+                s1 = s + ej / ((j * 2) + 1);
+                ++j;
+            }
+            ret = s1;
+        } else {
+            ret = x * FastMath.log(x / mu) + mu - x;
+        }
+        return ret;
+    }
+
+    /**
+     * Compute the PMF for a binomial distribution using the saddle point
+     * expansion.
+     *
+     * @param x the value at which the probability is evaluated.
+     * @param n the number of trials.
+     * @param p the probability of success.
+     * @param q the probability of failure (1 - p).
+     * @return log(p(x)).
+     */
+    static double logBinomialProbability(int x, int n, double p, double q) {
+        double ret;
+        if (x == 0) {
+            if (p < 0.1) {
+                ret = -getDeviancePart(n, n * q) - n * p;
+            } else {
+                ret = n * FastMath.log(q);
+            }
+        } else if (x == n) {
+            if (q < 0.1) {
+                ret = -getDeviancePart(n, n * p) - n * q;
+            } else {
+                ret = n * FastMath.log(p);
+            }
+        } else {
+            ret = getStirlingError(n) - getStirlingError(x) -
+                  getStirlingError(n - x) - getDeviancePart(x, n * p) -
+                  getDeviancePart(n - x, n * q);
+            double f = (MathUtils.TWO_PI * x * (n - x)) / n;
+            ret = -0.5 * FastMath.log(f) + ret;
+        }
+        return ret;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/TDistribution.java b/src/main/java/org/apache/commons/math/distribution/TDistribution.java
new file mode 100644
index 0000000..034c0d8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/TDistribution.java
@@ -0,0 +1,46 @@
+/*
+ * 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.distribution;
+
+/**
+ * Student's t-Distribution.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/Studentst-Distribution.html">
+ * Student's t-Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface TDistribution extends ContinuousDistribution {
+    /**
+     * Modify the degrees of freedom.
+     * @param degreesOfFreedom the new degrees of freedom.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setDegreesOfFreedom(double degreesOfFreedom);
+
+    /**
+     * Access the degrees of freedom.
+     * @return the degrees of freedom.
+     */
+    double getDegreesOfFreedom();
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java
new file mode 100644
index 0000000..35b72cf
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/TDistributionImpl.java
@@ -0,0 +1,303 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Beta;
+import org.apache.commons.math.special.Gamma;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Default implementation of
+ * {@link org.apache.commons.math.distribution.TDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class TDistributionImpl
+    extends AbstractContinuousDistribution
+    implements TDistribution, Serializable  {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+    */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -5852615386664158222L;
+
+    /** The degrees of freedom*/
+    private double degreesOfFreedom;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /**
+     * Create a t distribution using the given degrees of freedom and the
+     * specified inverse cumulative probability absolute accuracy.
+     *
+     * @param degreesOfFreedom the degrees of freedom.
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public TDistributionImpl(double degreesOfFreedom, double inverseCumAccuracy) {
+        super();
+        setDegreesOfFreedomInternal(degreesOfFreedom);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * Create a t distribution using the given degrees of freedom.
+     * @param degreesOfFreedom the degrees of freedom.
+     */
+    public TDistributionImpl(double degreesOfFreedom) {
+        this(degreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Modify the degrees of freedom.
+     * @param degreesOfFreedom the new degrees of freedom.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setDegreesOfFreedom(double degreesOfFreedom) {
+        setDegreesOfFreedomInternal(degreesOfFreedom);
+    }
+
+    /**
+     * Modify the degrees of freedom.
+     * @param newDegreesOfFreedom the new degrees of freedom.
+     */
+    private void setDegreesOfFreedomInternal(double newDegreesOfFreedom) {
+        if (newDegreesOfFreedom <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_DEGREES_OF_FREEDOM,
+                  newDegreesOfFreedom);
+        }
+        this.degreesOfFreedom = newDegreesOfFreedom;
+    }
+
+    /**
+     * Access the degrees of freedom.
+     * @return the degrees of freedom.
+     */
+    public double getDegreesOfFreedom() {
+        return degreesOfFreedom;
+    }
+
+    /**
+     * Returns the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        final double n = degreesOfFreedom;
+        final double nPlus1Over2 = (n + 1) / 2;
+        return FastMath.exp(Gamma.logGamma(nPlus1Over2) - 0.5 * (FastMath.log(FastMath.PI) + FastMath.log(n)) -
+                Gamma.logGamma(n/2) - nPlus1Over2 * FastMath.log(1 + x * x /n));
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; <code>x</code>).
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF evaluated at <code>x</code>.
+     * @throws MathException if the cumulative probability can not be
+     *            computed due to convergence or other numerical errors.
+     */
+    public double cumulativeProbability(double x) throws MathException{
+        double ret;
+        if (x == 0.0) {
+            ret = 0.5;
+        } else {
+            double t =
+                Beta.regularizedBeta(
+                    degreesOfFreedom / (degreesOfFreedom + (x * x)),
+                    0.5 * degreesOfFreedom,
+                    0.5);
+            if (x < 0.0) {
+                ret = 0.5 * t;
+            } else {
+                ret = 1.0 - 0.5 * t;
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
+     * <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws MathException if the inverse cumulative probability can not be
+     *         computed due to convergence or other numerical errors.
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(final double p)
+    throws MathException {
+        if (p == 0) {
+            return Double.NEGATIVE_INFINITY;
+        }
+        if (p == 1) {
+            return Double.POSITIVE_INFINITY;
+        }
+        return super.inverseCumulativeProbability(p);
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        return -Double.MAX_VALUE;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        return Double.MAX_VALUE;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        return 0.0;
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always negative infinity
+     * no matter the parameters.
+     *
+     * @return lower bound of the support (always Double.NEGATIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return Double.NEGATIVE_INFINITY;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity
+     * no matter the parameters.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For degrees of freedom parameter df, the mean is
+     * <ul>
+     *  <li>if <code>df &gt; 1</code> then <code>0</code></li>
+     * <li>else <code>undefined</code></li>
+     * </ul>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        final double df = getDegreesOfFreedom();
+
+        if (df > 1) {
+            return 0;
+        }
+
+        return Double.NaN;
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For degrees of freedom parameter df, the variance is
+     * <ul>
+     *  <li>if <code>df &gt; 2</code> then <code>df / (df - 2)</code> </li>
+     *  <li>if <code>1 &lt; df &lt;= 2</code> then <code>positive infinity</code></li>
+     *  <li>else <code>undefined</code></li>
+     * </ul>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        final double df = getDegreesOfFreedom();
+
+        if (df > 2) {
+            return df / (df - 2);
+        }
+
+        if (df > 1 && df <= 2) {
+            return Double.POSITIVE_INFINITY;
+        }
+
+        return Double.NaN;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/WeibullDistribution.java b/src/main/java/org/apache/commons/math/distribution/WeibullDistribution.java
new file mode 100644
index 0000000..bd1df5e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/WeibullDistribution.java
@@ -0,0 +1,66 @@
+/*
+ * 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.distribution;
+
+/**
+ * Weibull Distribution.  This interface defines the two parameter form of the
+ * distribution as defined by
+ * <a href="http://mathworld.wolfram.com/WeibullDistribution.html">
+ * Weibull Distribution</a>, equations (1) and (2).
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/WeibullDistribution.html">
+ * Weibull Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @since 1.1
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface WeibullDistribution extends ContinuousDistribution {
+
+    /**
+     * Access the shape parameter.
+     * @return the shape parameter.
+     */
+    double getShape();
+
+    /**
+     * Access the scale parameter.
+     * @return the scale parameter.
+     */
+    double getScale();
+
+    /**
+     * Modify the shape parameter.
+     * @param alpha The new shape parameter value.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setShape(double alpha);
+
+    /**
+     * Modify the scale parameter.
+     * @param beta The new scale parameter value.
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setScale(double beta);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/WeibullDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/WeibullDistributionImpl.java
new file mode 100644
index 0000000..c52caac
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/WeibullDistributionImpl.java
@@ -0,0 +1,378 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.special.Gamma;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Default implementation of
+ * {@link org.apache.commons.math.distribution.WeibullDistribution}.
+ *
+ * @since 1.1
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class WeibullDistributionImpl extends AbstractContinuousDistribution
+        implements WeibullDistribution, Serializable {
+
+    /**
+     * Default inverse cumulative probability accuracy
+     * @since 2.1
+     */
+    public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 8589540077390120676L;
+
+    /** The shape parameter. */
+    private double shape;
+
+    /** The scale parameter. */
+    private double scale;
+
+    /** Inverse cumulative probability accuracy */
+    private final double solverAbsoluteAccuracy;
+
+    /** Cached numerical mean */
+    private double numericalMean = Double.NaN;
+
+    /** Whether or not the numerical mean has been calculated */
+    private boolean numericalMeanIsCalculated = false;
+
+    /** Cached numerical variance */
+    private double numericalVariance = Double.NaN;
+
+    /** Whether or not the numerical variance has been calculated */
+    private boolean numericalVarianceIsCalculated = false;
+
+    /**
+     * Creates weibull distribution with the given shape and scale and a
+     * location equal to zero.
+     * @param alpha the shape parameter.
+     * @param beta the scale parameter.
+     */
+    public WeibullDistributionImpl(double alpha, double beta){
+        this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
+    }
+
+    /**
+     * Creates weibull distribution with the given shape, scale and inverse
+     * cumulative probability accuracy and a location equal to zero.
+     * @param alpha the shape parameter.
+     * @param beta the scale parameter.
+     * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates
+     * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY})
+     * @since 2.1
+     */
+    public WeibullDistributionImpl(double alpha, double beta, double inverseCumAccuracy){
+        super();
+        setShapeInternal(alpha);
+        setScaleInternal(beta);
+        solverAbsoluteAccuracy = inverseCumAccuracy;
+    }
+
+    /**
+     * For this distribution, X, this method returns P(X &lt; <code>x</code>).
+     * @param x the value at which the CDF is evaluated.
+     * @return CDF evaluated at <code>x</code>.
+     */
+    public double cumulativeProbability(double x) {
+        double ret;
+        if (x <= 0.0) {
+            ret = 0.0;
+        } else {
+            ret = 1.0 - FastMath.exp(-FastMath.pow(x / scale, shape));
+        }
+        return ret;
+    }
+
+    /**
+     * Access the shape parameter.
+     * @return the shape parameter.
+     */
+    public double getShape() {
+        return shape;
+    }
+
+    /**
+     * Access the scale parameter.
+     * @return the scale parameter.
+     */
+    public double getScale() {
+        return scale;
+    }
+
+    /**
+     * Returns the probability density for a particular point.
+     *
+     * @param x The point at which the density should be computed.
+     * @return The pdf at point x.
+     * @since 2.1
+     */
+    @Override
+    public double density(double x) {
+        if (x < 0) {
+            return 0;
+        }
+
+        final double xscale = x / scale;
+        final double xscalepow = FastMath.pow(xscale, shape - 1);
+
+        /*
+         * FastMath.pow(x / scale, shape) =
+         * FastMath.pow(xscale, shape) =
+         * FastMath.pow(xscale, shape - 1) * xscale
+         */
+        final double xscalepowshape = xscalepow * xscale;
+
+        return (shape / scale) * xscalepow * FastMath.exp(-xscalepowshape);
+    }
+
+    /**
+     * For this distribution, X, this method returns the critical point x, such
+     * that P(X &lt; x) = <code>p</code>.
+     * <p>
+     * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
+     * <code>Double.POSITIVE_INFINITY</code> for p=1.</p>
+     *
+     * @param p the desired probability
+     * @return x, such that P(X &lt; x) = <code>p</code>
+     * @throws IllegalArgumentException if <code>p</code> is not a valid
+     *         probability.
+     */
+    @Override
+    public double inverseCumulativeProbability(double p) {
+        double ret;
+        if (p < 0.0 || p > 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0);
+        } else if (p == 0) {
+            ret = 0.0;
+        } else  if (p == 1) {
+            ret = Double.POSITIVE_INFINITY;
+        } else {
+            ret = scale * FastMath.pow(-FastMath.log(1.0 - p), 1.0 / shape);
+        }
+        return ret;
+    }
+
+    /**
+     * Modify the shape parameter.
+     * @param alpha the new shape parameter value.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setShape(double alpha) {
+        setShapeInternal(alpha);
+        invalidateParameterDependentMoments();
+    }
+    /**
+     * Modify the shape parameter.
+     * @param alpha the new shape parameter value.
+     */
+    private void setShapeInternal(double alpha) {
+        if (alpha <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_SHAPE,
+                  alpha);
+        }
+        this.shape = alpha;
+    }
+
+    /**
+     * Modify the scale parameter.
+     * @param beta the new scale parameter value.
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setScale(double beta) {
+        setScaleInternal(beta);
+        invalidateParameterDependentMoments();
+    }
+    /**
+     * Modify the scale parameter.
+     * @param beta the new scale parameter value.
+     */
+    private void setScaleInternal(double beta) {
+        if (beta <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_POSITIVE_SCALE,
+                  beta);
+        }
+        this.scale = beta;
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected double getDomainLowerBound(double p) {
+        return 0.0;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected double getDomainUpperBound(double p) {
+        return Double.MAX_VALUE;
+    }
+
+    /**
+     * Access the initial domain value, based on <code>p</code>, used to
+     * bracket a CDF root.  This method is used by
+     * {@link #inverseCumulativeProbability(double)} to find critical values.
+     *
+     * @param p the desired probability for the critical value
+     * @return initial domain value
+     */
+    @Override
+    protected double getInitialDomain(double p) {
+        // use median
+        return FastMath.pow(scale * FastMath.log(2.0), 1.0 / shape);
+    }
+
+    /**
+     * Return the absolute accuracy setting of the solver used to estimate
+     * inverse cumulative probabilities.
+     *
+     * @return the solver absolute accuracy
+     * @since 2.1
+     */
+    @Override
+    protected double getSolverAbsoluteAccuracy() {
+        return solverAbsoluteAccuracy;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 0 no matter the parameters.
+     *
+     * @return lower bound of the support (always 0)
+     * @since 2.2
+     */
+    public double getSupportLowerBound() {
+        return 0;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is always positive infinity
+     * no matter the parameters.
+     *
+     * @return upper bound of the support (always Double.POSITIVE_INFINITY)
+     * @since 2.2
+     */
+    public double getSupportUpperBound() {
+        return Double.POSITIVE_INFINITY;
+    }
+
+    /**
+     * Calculates the mean.
+     *
+     * The mean is <code>scale * Gamma(1 + (1 / shape))</code>
+     * where <code>Gamma(...)</code> is the Gamma-function
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    protected double calculateNumericalMean() {
+        final double sh = getShape();
+        final double sc = getScale();
+
+        return sc * FastMath.exp(Gamma.logGamma(1 + (1 / sh)));
+    }
+
+    /**
+     * Calculates the variance.
+     *
+     * The variance is
+     * <code>scale^2 * Gamma(1 + (2 / shape)) - mean^2</code>
+     * where <code>Gamma(...)</code> is the Gamma-function
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    private double calculateNumericalVariance() {
+        final double sh = getShape();
+        final double sc = getScale();
+        final double mn = getNumericalMean();
+
+        return (sc * sc) *
+            FastMath.exp(Gamma.logGamma(1 + (2 / sh))) -
+            (mn * mn);
+    }
+
+    /**
+     * Returns the mean of the distribution.
+     *
+     * @return the mean or Double.NaN if it's not defined
+     * @since 2.2
+     */
+    public double getNumericalMean() {
+        if (!numericalMeanIsCalculated) {
+            numericalMean = calculateNumericalMean();
+            numericalMeanIsCalculated = true;
+        }
+
+        return numericalMean;
+    }
+
+    /**
+     * Returns the variance of the distribution.
+     *
+     * @return the variance (possibly Double.POSITIVE_INFINITY as
+     * for certain cases in {@link TDistributionImpl}) or
+     * Double.NaN if it's not defined
+     * @since 2.2
+     */
+    public double getNumericalVariance() {
+        if (!numericalVarianceIsCalculated) {
+            numericalVariance = calculateNumericalVariance();
+            numericalVarianceIsCalculated = true;
+        }
+
+        return numericalVariance;
+    }
+
+    /**
+     * Invalidates the cached mean and variance.
+     */
+    private void invalidateParameterDependentMoments() {
+        numericalMeanIsCalculated = false;
+        numericalVarianceIsCalculated = false;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ZipfDistribution.java b/src/main/java/org/apache/commons/math/distribution/ZipfDistribution.java
new file mode 100644
index 0000000..885adac
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ZipfDistribution.java
@@ -0,0 +1,71 @@
+/*
+ * 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.distribution;
+
+/**
+ * The Zipf (or zeta) Distribution.
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/ZipfDistribution.html">Zipf
+ * Distribution</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 920852 $ $Date: 2010-03-09 13:53:44 +0100 (mar. 09 mars 2010) $
+ */
+public interface ZipfDistribution extends IntegerDistribution {
+
+    /**
+     * Get the number of elements (e.g. corpus size) for the distribution.
+     *
+     * @return the number of elements
+     */
+    int getNumberOfElements();
+
+    /**
+     * Set the number of elements (e.g. corpus size) for the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param n the number of elements
+     * @throws IllegalArgumentException if n &le; 0
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setNumberOfElements(int n);
+
+    /**
+     * Get the exponent characterising the distribution.
+     *
+     * @return the exponent
+     */
+    double getExponent();
+
+    /**
+     * Set the exponent characterising the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param s the exponent
+     * @throws IllegalArgumentException if s &le; 0.0
+     * @deprecated as of v2.1
+     */
+    @Deprecated
+    void setExponent(double s);
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java b/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java
new file mode 100644
index 0000000..9f19528
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/ZipfDistributionImpl.java
@@ -0,0 +1,286 @@
+/*
+ * 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.distribution;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implementation for the {@link ZipfDistribution}.
+ *
+ * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $
+ */
+public class ZipfDistributionImpl extends AbstractIntegerDistribution
+    implements ZipfDistribution, Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -140627372283420404L;
+
+    /** Number of elements. */
+    private int numberOfElements;
+
+    /** Exponent parameter of the distribution. */
+    private double exponent;
+
+    /**
+     * Create a new Zipf distribution with the given number of elements and
+     * exponent. Both values must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param numberOfElements the number of elements
+     * @param exponent the exponent
+     * @exception IllegalArgumentException if n &le; 0 or s &le; 0.0
+     */
+    public ZipfDistributionImpl(final int numberOfElements, final double exponent)
+        throws IllegalArgumentException {
+        setNumberOfElementsInternal(numberOfElements);
+        setExponentInternal(exponent);
+    }
+
+    /**
+     * Get the number of elements (e.g. corpus size) for the distribution.
+     *
+     * @return the number of elements
+     */
+    public int getNumberOfElements() {
+        return numberOfElements;
+    }
+
+    /**
+     * Set the number of elements (e.g. corpus size) for the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param n the number of elements
+     * @exception IllegalArgumentException if n &le; 0
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setNumberOfElements(final int n) {
+        setNumberOfElementsInternal(n);
+    }
+    /**
+     * Set the number of elements (e.g. corpus size) for the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param n the number of elements
+     * @exception IllegalArgumentException if n &le; 0
+     */
+    private void setNumberOfElementsInternal(final int n)
+        throws IllegalArgumentException {
+        if (n <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, n, 0);
+        }
+        this.numberOfElements = n;
+    }
+
+    /**
+     * Get the exponent characterising the distribution.
+     *
+     * @return the exponent
+     */
+    public double getExponent() {
+        return exponent;
+    }
+
+    /**
+     * Set the exponent characterising the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param s the exponent
+     * @exception IllegalArgumentException if s &le; 0.0
+     * @deprecated as of 2.1 (class will become immutable in 3.0)
+     */
+    @Deprecated
+    public void setExponent(final double s) {
+        setExponentInternal(s);
+    }
+
+    /**
+     * Set the exponent characterising the distribution.
+     * The parameter value must be positive; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param s the exponent
+     * @exception IllegalArgumentException if s &le; 0.0
+     */
+    private void setExponentInternal(final double s)
+        throws IllegalArgumentException {
+        if (s <= 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POSITIVE_EXPONENT,
+                    s);
+        }
+        this.exponent = s;
+    }
+
+    /**
+     * The probability mass function P(X = x) for a Zipf distribution.
+     *
+     * @param x the value at which the probability density function is evaluated.
+     * @return the value of the probability mass function at x
+     */
+    public double probability(final int x) {
+        if (x <= 0 || x > numberOfElements) {
+            return 0.0;
+        }
+
+        return (1.0 / FastMath.pow(x, exponent)) / generalizedHarmonic(numberOfElements, exponent);
+
+    }
+
+    /**
+     * The probability distribution function P(X <= x) for a Zipf distribution.
+     *
+     * @param x the value at which the PDF is evaluated.
+     * @return Zipf distribution function evaluated at x
+     */
+    @Override
+    public double cumulativeProbability(final int x) {
+        if (x <= 0) {
+            return 0.0;
+        } else if (x >= numberOfElements) {
+            return 1.0;
+        }
+
+        return generalizedHarmonic(x, exponent) / generalizedHarmonic(numberOfElements, exponent);
+
+    }
+
+    /**
+     * Access the domain value lower bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value lower bound, i.e.
+     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
+     */
+    @Override
+    protected int getDomainLowerBound(final double p) {
+        return 0;
+    }
+
+    /**
+     * Access the domain value upper bound, based on <code>p</code>, used to
+     * bracket a PDF root.
+     *
+     * @param p the desired probability for the critical value
+     * @return domain value upper bound, i.e.
+     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
+     */
+    @Override
+    protected int getDomainUpperBound(final double p) {
+        return numberOfElements;
+    }
+
+
+    /**
+     * Calculates the Nth generalized harmonic number. See
+     * <a href="http://mathworld.wolfram.com/HarmonicSeries.html">Harmonic
+     * Series</a>.
+     *
+     * @param n the term in the series to calculate (must be &ge; 1)
+     * @param m the exponent; special case m == 1.0 is the harmonic series
+     * @return the nth generalized harmonic number
+     */
+    private double generalizedHarmonic(final int n, final double m) {
+        double value = 0;
+        for (int k = n; k > 0; --k) {
+            value += 1.0 / FastMath.pow(k, m);
+        }
+        return value;
+    }
+
+    /**
+     * Returns the lower bound of the support for the distribution.
+     *
+     * The lower bound of the support is always 1 no matter the parameters.
+     *
+     * @return lower bound of the support (always 1)
+     * @since 2.2
+     */
+    public int getSupportLowerBound() {
+        return 1;
+    }
+
+    /**
+     * Returns the upper bound of the support for the distribution.
+     *
+     * The upper bound of the support is the number of elements
+     *
+     * @return upper bound of the support
+     * @since 2.2
+     */
+    public int getSupportUpperBound() {
+        return getNumberOfElements();
+    }
+
+    /**
+     * Returns the mean.
+     *
+     * For number of elements N and exponent s, the mean is
+     * <code>Hs1 / Hs</code> where
+     * <ul>
+     *  <li><code>Hs1 = generalizedHarmonic(N, s - 1)</code></li>
+     *  <li><code>Hs = generalizedHarmonic(N, s)</code></li>
+     * </ul>
+     *
+     * @return the mean
+     * @since 2.2
+     */
+    protected double getNumericalMean() {
+        final int N = getNumberOfElements();
+        final double s = getExponent();
+
+        final double Hs1 = generalizedHarmonic(N, s - 1);
+        final double Hs = generalizedHarmonic(N, s);
+
+        return Hs1 / Hs;
+    }
+
+    /**
+     * Returns the variance.
+     *
+     * For number of elements N and exponent s, the mean is
+     * <code>(Hs2 / Hs) - (Hs1^2 / Hs^2)</code> where
+     * <ul>
+     *  <li><code>Hs2 = generalizedHarmonic(N, s - 2)</code></li>
+     *  <li><code>Hs1 = generalizedHarmonic(N, s - 1)</code></li>
+     *  <li><code>Hs = generalizedHarmonic(N, s)</code></li>
+     * </ul>
+     *
+     * @return the variance
+     * @since 2.2
+     */
+    protected double getNumericalVariance() {
+        final int N = getNumberOfElements();
+        final double s = getExponent();
+
+        final double Hs2 = generalizedHarmonic(N, s - 2);
+        final double Hs1 = generalizedHarmonic(N, s - 1);
+        final double Hs = generalizedHarmonic(N, s);
+
+        return (Hs2 / Hs) - ((Hs1 * Hs1) / (Hs * Hs));
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/distribution/package.html b/src/main/java/org/apache/commons/math/distribution/package.html
new file mode 100644
index 0000000..c89e8d8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/distribution/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Implementations of common discrete and continuous distributions.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/estimation/AbstractEstimator.java b/src/main/java/org/apache/commons/math/estimation/AbstractEstimator.java
new file mode 100644
index 0000000..7a52b55
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/AbstractEstimator.java
@@ -0,0 +1,318 @@
+/*
+ * 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.estimation;
+
+import java.util.Arrays;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.InvalidMatrixException;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Base class for implementing estimators.
+ * <p>This base class handles the boilerplates methods associated to thresholds
+ * settings, jacobian and error estimation.</p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public abstract class AbstractEstimator implements Estimator {
+
+    /** Default maximal number of cost evaluations allowed. */
+    public static final int DEFAULT_MAX_COST_EVALUATIONS = 100;
+
+    /** Array of measurements. */
+    protected WeightedMeasurement[] measurements;
+
+    /** Array of parameters. */
+    protected EstimatedParameter[] parameters;
+
+    /**
+     * Jacobian matrix.
+     * <p>This matrix is in canonical form just after the calls to
+     * {@link #updateJacobian()}, but may be modified by the solver
+     * in the derived class (the {@link LevenbergMarquardtEstimator
+     * Levenberg-Marquardt estimator} does this).</p>
+     */
+    protected double[] jacobian;
+
+    /** Number of columns of the jacobian matrix. */
+    protected int cols;
+
+    /** Number of rows of the jacobian matrix. */
+    protected int rows;
+
+    /** Residuals array.
+     * <p>This array is in canonical form just after the calls to
+     * {@link #updateJacobian()}, but may be modified by the solver
+     * in the derived class (the {@link LevenbergMarquardtEstimator
+     * Levenberg-Marquardt estimator} does this).</p>
+     */
+    protected double[] residuals;
+
+    /** Cost value (square root of the sum of the residuals). */
+    protected double cost;
+
+    /** Maximal allowed number of cost evaluations. */
+    private int maxCostEval;
+
+    /** Number of cost evaluations. */
+    private int costEvaluations;
+
+    /** Number of jacobian evaluations. */
+    private int jacobianEvaluations;
+
+    /**
+     * Build an abstract estimator for least squares problems.
+     * <p>The maximal number of cost evaluations allowed is set
+     * to its default value {@link #DEFAULT_MAX_COST_EVALUATIONS}.</p>
+     */
+    protected AbstractEstimator() {
+        setMaxCostEval(DEFAULT_MAX_COST_EVALUATIONS);
+    }
+
+    /**
+     * Set the maximal number of cost evaluations allowed.
+     *
+     * @param maxCostEval maximal number of cost evaluations allowed
+     * @see #estimate
+     */
+    public final void setMaxCostEval(int maxCostEval) {
+        this.maxCostEval = maxCostEval;
+    }
+
+    /**
+     * Get the number of cost evaluations.
+     *
+     * @return number of cost evaluations
+     * */
+    public final int getCostEvaluations() {
+        return costEvaluations;
+    }
+
+    /**
+     * Get the number of jacobian evaluations.
+     *
+     * @return number of jacobian evaluations
+     * */
+    public final int getJacobianEvaluations() {
+        return jacobianEvaluations;
+    }
+
+    /**
+     * Update the jacobian matrix.
+     */
+    protected void updateJacobian() {
+        incrementJacobianEvaluationsCounter();
+        Arrays.fill(jacobian, 0);
+        int index = 0;
+        for (int i = 0; i < rows; i++) {
+            WeightedMeasurement wm = measurements[i];
+            double factor = -FastMath.sqrt(wm.getWeight());
+            for (int j = 0; j < cols; ++j) {
+                jacobian[index++] = factor * wm.getPartial(parameters[j]);
+            }
+        }
+    }
+
+    /**
+     * Increment the jacobian evaluations counter.
+     */
+    protected final void incrementJacobianEvaluationsCounter() {
+      ++jacobianEvaluations;
+    }
+
+    /**
+     * Update the residuals array and cost function value.
+     * @exception EstimationException if the number of cost evaluations
+     * exceeds the maximum allowed
+     */
+    protected void updateResidualsAndCost()
+    throws EstimationException {
+
+        if (++costEvaluations > maxCostEval) {
+            throw new EstimationException(LocalizedFormats.MAX_EVALUATIONS_EXCEEDED,
+                                          maxCostEval);
+        }
+
+        cost = 0;
+        int index = 0;
+        for (int i = 0; i < rows; i++, index += cols) {
+            WeightedMeasurement wm = measurements[i];
+            double residual = wm.getResidual();
+            residuals[i] = FastMath.sqrt(wm.getWeight()) * residual;
+            cost += wm.getWeight() * residual * residual;
+        }
+        cost = FastMath.sqrt(cost);
+
+    }
+
+    /**
+     * Get the Root Mean Square value.
+     * Get the Root Mean Square value, i.e. the root of the arithmetic
+     * mean of the square of all weighted residuals. This is related to the
+     * criterion that is minimized by the estimator as follows: if
+     * <em>c</em> if the criterion, and <em>n</em> is the number of
+     * measurements, then the RMS is <em>sqrt (c/n)</em>.
+     *
+     * @param problem estimation problem
+     * @return RMS value
+     */
+    public double getRMS(EstimationProblem problem) {
+        WeightedMeasurement[] wm = problem.getMeasurements();
+        double criterion = 0;
+        for (int i = 0; i < wm.length; ++i) {
+            double residual = wm[i].getResidual();
+            criterion += wm[i].getWeight() * residual * residual;
+        }
+        return FastMath.sqrt(criterion / wm.length);
+    }
+
+    /**
+     * Get the Chi-Square value.
+     * @param problem estimation problem
+     * @return chi-square value
+     */
+    public double getChiSquare(EstimationProblem problem) {
+        WeightedMeasurement[] wm = problem.getMeasurements();
+        double chiSquare = 0;
+        for (int i = 0; i < wm.length; ++i) {
+            double residual = wm[i].getResidual();
+            chiSquare += residual * residual / wm[i].getWeight();
+        }
+        return chiSquare;
+    }
+
+    /**
+     * Get the covariance matrix of unbound estimated parameters.
+     * @param problem estimation problem
+     * @return covariance matrix
+     * @exception EstimationException if the covariance matrix
+     * cannot be computed (singular problem)
+     */
+    public double[][] getCovariances(EstimationProblem problem)
+      throws EstimationException {
+
+        // set up the jacobian
+        updateJacobian();
+
+        // compute transpose(J).J, avoiding building big intermediate matrices
+        final int n = problem.getMeasurements().length;
+        final int m = problem.getUnboundParameters().length;
+        final int max  = m * n;
+        double[][] jTj = new double[m][m];
+        for (int i = 0; i < m; ++i) {
+            for (int j = i; j < m; ++j) {
+                double sum = 0;
+                for (int k = 0; k < max; k += m) {
+                    sum += jacobian[k + i] * jacobian[k + j];
+                }
+                jTj[i][j] = sum;
+                jTj[j][i] = sum;
+            }
+        }
+
+        try {
+            // compute the covariances matrix
+            RealMatrix inverse =
+                new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse();
+            return inverse.getData();
+        } catch (InvalidMatrixException ime) {
+            throw new EstimationException(LocalizedFormats.UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM);
+        }
+
+    }
+
+    /**
+     * Guess the errors in unbound estimated parameters.
+     * <p>Guessing is covariance-based, it only gives rough order of magnitude.</p>
+     * @param problem estimation problem
+     * @return errors in estimated parameters
+     * @exception EstimationException if the covariances matrix cannot be computed
+     * or the number of degrees of freedom is not positive (number of measurements
+     * lesser or equal to number of parameters)
+     */
+    public double[] guessParametersErrors(EstimationProblem problem)
+      throws EstimationException {
+        int m = problem.getMeasurements().length;
+        int p = problem.getUnboundParameters().length;
+        if (m <= p) {
+            throw new EstimationException(
+                    LocalizedFormats.NO_DEGREES_OF_FREEDOM,
+                    m, p);
+        }
+        double[] errors = new double[problem.getUnboundParameters().length];
+        final double c = FastMath.sqrt(getChiSquare(problem) / (m - p));
+        double[][] covar = getCovariances(problem);
+        for (int i = 0; i < errors.length; ++i) {
+            errors[i] = FastMath.sqrt(covar[i][i]) * c;
+        }
+        return errors;
+    }
+
+    /**
+     * Initialization of the common parts of the estimation.
+     * <p>This method <em>must</em> be called at the start
+     * of the {@link #estimate(EstimationProblem) estimate}
+     * method.</p>
+     * @param problem estimation problem to solve
+     */
+    protected void initializeEstimate(EstimationProblem problem) {
+
+        // reset counters
+        costEvaluations     = 0;
+        jacobianEvaluations = 0;
+
+        // retrieve the equations and the parameters
+        measurements = problem.getMeasurements();
+        parameters   = problem.getUnboundParameters();
+
+        // arrays shared with the other private methods
+        rows      = measurements.length;
+        cols      = parameters.length;
+        jacobian  = new double[rows * cols];
+        residuals = new double[rows];
+
+        cost = Double.POSITIVE_INFINITY;
+
+    }
+
+    /**
+     * Solve an estimation problem.
+     *
+     * <p>The method should set the parameters of the problem to several
+     * trial values until it reaches convergence. If this method returns
+     * normally (i.e. without throwing an exception), then the best
+     * estimate of the parameters can be retrieved from the problem
+     * itself, through the {@link EstimationProblem#getAllParameters
+     * EstimationProblem.getAllParameters} method.</p>
+     *
+     * @param problem estimation problem to solve
+     * @exception EstimationException if the problem cannot be solved
+     *
+     */
+    public abstract void estimate(EstimationProblem problem)
+    throws EstimationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/EstimatedParameter.java b/src/main/java/org/apache/commons/math/estimation/EstimatedParameter.java
new file mode 100644
index 0000000..e0047bb
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/EstimatedParameter.java
@@ -0,0 +1,126 @@
+/*
+ * 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.estimation;
+
+import java.io.Serializable;
+
+/** This class represents the estimated parameters of an estimation problem.
+ *
+ * <p>The parameters of an estimation problem have a name, a value and
+ * a bound flag. The value of bound parameters is considered trusted
+ * and the solvers should not adjust them. On the other hand, the
+ * solvers should adjust the value of unbounds parameters until they
+ * satisfy convergence criterions specific to each solver.</p>
+ *
+ * @version $Revision: 922710 $ $Date: 2010-03-14 02:20:56 +0100 (dim. 14 mars 2010) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public class EstimatedParameter
+  implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -555440800213416949L;
+
+    /** Current value of the parameter */
+    protected double  estimate;
+
+    /** Name of the parameter */
+    private final String  name;
+
+    /** Indicator for bound parameters
+     * (ie parameters that should not be estimated)
+     */
+    private   boolean bound;
+
+    /** Simple constructor.
+     * Build an instance from a first estimate of the parameter,
+     * initially considered unbound.
+     * @param name name of the parameter
+     * @param firstEstimate first estimate of the parameter
+     */
+    public EstimatedParameter(String name, double firstEstimate) {
+        this.name = name;
+        estimate  = firstEstimate;
+        bound     = false;
+    }
+
+    /** Simple constructor.
+     * Build an instance from a first estimate of the parameter and a
+     * bound flag
+     * @param name name of the parameter
+     * @param firstEstimate first estimate of the parameter
+     * @param bound flag, should be true if the parameter is bound
+     */
+    public EstimatedParameter(String name,
+                              double firstEstimate,
+                              boolean bound) {
+        this.name  = name;
+        estimate   = firstEstimate;
+        this.bound = bound;
+    }
+
+    /** Copy constructor.
+     * Build a copy of a parameter
+     * @param parameter instance to copy
+     */
+    public EstimatedParameter(EstimatedParameter parameter) {
+        name     = parameter.name;
+        estimate = parameter.estimate;
+        bound    = parameter.bound;
+    }
+
+    /** Set a new estimated value for the parameter.
+     * @param estimate new estimate for the parameter
+     */
+    public void setEstimate(double estimate) {
+        this.estimate = estimate;
+    }
+
+    /** Get the current estimate of the parameter
+     * @return current estimate
+     */
+    public double getEstimate() {
+        return estimate;
+    }
+
+    /** get the name of the parameter
+     * @return parameter name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /** Set the bound flag of the parameter
+     * @param bound this flag should be set to true if the parameter is
+     * bound (i.e. if it should not be adjusted by the solver).
+     */
+    public void setBound(boolean bound) {
+        this.bound = bound;
+    }
+
+    /** Check if the parameter is bound
+     * @return true if the parameter is bound */
+    public boolean isBound() {
+        return bound;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/EstimationException.java b/src/main/java/org/apache/commons/math/estimation/EstimationException.java
new file mode 100644
index 0000000..463ea49
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/EstimationException.java
@@ -0,0 +1,61 @@
+/*
+ * 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.estimation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * This class represents exceptions thrown by the estimation solvers.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public class EstimationException
+extends MathException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -573038581493881337L;
+
+    /**
+     * Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     */
+    public EstimationException(String specifier, Object ... parts) {
+        this(new DummyLocalizable(specifier), parts);
+    }
+
+    /**
+     * Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @since 2.2
+     */
+    public EstimationException(Localizable specifier, Object ... parts) {
+        super(specifier, parts);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/EstimationProblem.java b/src/main/java/org/apache/commons/math/estimation/EstimationProblem.java
new file mode 100644
index 0000000..a0d660b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/EstimationProblem.java
@@ -0,0 +1,68 @@
+/*
+ * 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.estimation;
+
+/**
+ * This interface represents an estimation problem.
+ *
+ * <p>This interface should be implemented by all real estimation
+ * problems before they can be handled by the estimators through the
+ * {@link Estimator#estimate Estimator.estimate} method.</p>
+ *
+ * <p>An estimation problem, as seen by a solver is a set of
+ * parameters and a set of measurements. The parameters are adjusted
+ * during the estimation through the {@link #getUnboundParameters
+ * getUnboundParameters} and {@link EstimatedParameter#setEstimate
+ * EstimatedParameter.setEstimate} methods. The measurements both have
+ * a measured value which is generally fixed at construction and a
+ * theoretical value which depends on the model and hence varies as
+ * the parameters are adjusted. The purpose of the solver is to reduce
+ * the residual between these values, it can retrieve the measurements
+ * through the {@link #getMeasurements getMeasurements} method.</p>
+ *
+ * @see Estimator
+ * @see WeightedMeasurement
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public interface EstimationProblem {
+
+    /**
+     * Get the measurements of an estimation problem.
+     * @return measurements
+     */
+    WeightedMeasurement[] getMeasurements();
+
+    /**
+     * Get the unbound parameters of the problem.
+     * @return unbound parameters
+     */
+    EstimatedParameter[] getUnboundParameters();
+
+    /**
+     * Get all the parameters of the problem.
+     * @return parameters
+     */
+    EstimatedParameter[] getAllParameters();
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/Estimator.java b/src/main/java/org/apache/commons/math/estimation/Estimator.java
new file mode 100644
index 0000000..5d6d85a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/Estimator.java
@@ -0,0 +1,90 @@
+/*
+ * 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.estimation;
+
+/**
+ * This interface represents solvers for estimation problems.
+ *
+ * <p>The classes which are devoted to solve estimation problems
+ * should implement this interface. The problems which can be handled
+ * should implement the {@link EstimationProblem} interface which
+ * gather all the information needed by the solver.</p>
+ *
+ * <p>The interface is composed only of the {@link #estimate estimate}
+ * method.</p>
+ *
+ * @see EstimationProblem
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public interface Estimator {
+
+  /**
+   * Solve an estimation problem.
+   *
+   * <p>The method should set the parameters of the problem to several
+   * trial values until it reaches convergence. If this method returns
+   * normally (i.e. without throwing an exception), then the best
+   * estimate of the parameters can be retrieved from the problem
+   * itself, through the {@link EstimationProblem#getAllParameters
+   * EstimationProblem.getAllParameters} method.</p>
+   *
+   * @param problem estimation problem to solve
+   * @exception EstimationException if the problem cannot be solved
+   *
+   */
+  void estimate(EstimationProblem problem) throws EstimationException;
+
+  /**
+   * Get the Root Mean Square value.
+   * Get the Root Mean Square value, i.e. the root of the arithmetic
+   * mean of the square of all weighted residuals. This is related to the
+   * criterion that is minimized by the estimator as follows: if
+   * <em>c</em> is the criterion, and <em>n</em> is the number of
+   * measurements, then the RMS is <em>sqrt (c/n)</em>.
+   * @see #guessParametersErrors(EstimationProblem)
+   *
+   * @param problem estimation problem
+   * @return RMS value
+   */
+  double getRMS(EstimationProblem problem);
+
+  /**
+   * Get the covariance matrix of estimated parameters.
+   * @param problem estimation problem
+   * @return covariance matrix
+   * @exception EstimationException if the covariance matrix
+   * cannot be computed (singular problem)
+   */
+  double[][] getCovariances(EstimationProblem problem) throws EstimationException;
+
+  /**
+   * Guess the errors in estimated parameters.
+   * @see #getRMS(EstimationProblem)
+   * @param problem estimation problem
+   * @return errors in estimated parameters
+     * @exception EstimationException if the error cannot be guessed
+   */
+  double[] guessParametersErrors(EstimationProblem problem) throws EstimationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java b/src/main/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java
new file mode 100644
index 0000000..c5d0dd3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/GaussNewtonEstimator.java
@@ -0,0 +1,231 @@
+/*
+ * 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.estimation;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.InvalidMatrixException;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.linear.ArrayRealVector;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements a solver for estimation problems.
+ *
+ * <p>This class solves estimation problems using a weighted least
+ * squares criterion on the measurement residuals. It uses a
+ * Gauss-Newton algorithm.</p>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public class GaussNewtonEstimator extends AbstractEstimator implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 5485001826076289109L;
+
+    /** Default threshold for cost steady state detection. */
+    private static final double DEFAULT_STEADY_STATE_THRESHOLD = 1.0e-6;
+
+    /** Default threshold for cost convergence. */
+    private static final double DEFAULT_CONVERGENCE = 1.0e-6;
+
+    /** Threshold for cost steady state detection. */
+    private double steadyStateThreshold;
+
+    /** Threshold for cost convergence. */
+    private double convergence;
+
+    /** Simple constructor with default settings.
+     * <p>
+     * The estimator is built with default values for all settings.
+     * </p>
+     * @see #DEFAULT_STEADY_STATE_THRESHOLD
+     * @see #DEFAULT_CONVERGENCE
+     * @see AbstractEstimator#DEFAULT_MAX_COST_EVALUATIONS
+     */
+    public GaussNewtonEstimator() {
+        this.steadyStateThreshold = DEFAULT_STEADY_STATE_THRESHOLD;
+        this.convergence          = DEFAULT_CONVERGENCE;
+    }
+
+    /**
+     * Simple constructor.
+     *
+     * <p>This constructor builds an estimator and stores its convergence
+     * characteristics.</p>
+     *
+     * <p>An estimator is considered to have converged whenever either
+     * the criterion goes below a physical threshold under which
+     * improvements are considered useless or when the algorithm is
+     * unable to improve it (even if it is still high). The first
+     * condition that is met stops the iterations.</p>
+     *
+     * <p>The fact an estimator has converged does not mean that the
+     * model accurately fits the measurements. It only means no better
+     * solution can be found, it does not mean this one is good. Such an
+     * analysis is left to the caller.</p>
+     *
+     * <p>If neither conditions are fulfilled before a given number of
+     * iterations, the algorithm is considered to have failed and an
+     * {@link EstimationException} is thrown.</p>
+     *
+     * @param maxCostEval maximal number of cost evaluations allowed
+     * @param convergence criterion threshold below which we do not need
+     * to improve the criterion anymore
+     * @param steadyStateThreshold steady state detection threshold, the
+     * problem has converged has reached a steady state if
+     * <code>FastMath.abs(J<sub>n</sub> - J<sub>n-1</sub>) &lt;
+     * J<sub>n</sub> &times convergence</code>, where <code>J<sub>n</sub></code>
+     * and <code>J<sub>n-1</sub></code> are the current and preceding criterion
+     * values (square sum of the weighted residuals of considered measurements).
+     */
+    public GaussNewtonEstimator(final int maxCostEval, final double convergence,
+                                final double steadyStateThreshold) {
+        setMaxCostEval(maxCostEval);
+        this.steadyStateThreshold = steadyStateThreshold;
+        this.convergence          = convergence;
+    }
+
+    /**
+     * Set the convergence criterion threshold.
+     * @param convergence criterion threshold below which we do not need
+     * to improve the criterion anymore
+     */
+    public void setConvergence(final double convergence) {
+        this.convergence = convergence;
+    }
+
+    /**
+     * Set the steady state detection threshold.
+     * <p>
+     * The problem has converged has reached a steady state if
+     * <code>FastMath.abs(J<sub>n</sub> - J<sub>n-1</sub>) &lt;
+     * J<sub>n</sub> &times convergence</code>, where <code>J<sub>n</sub></code>
+     * and <code>J<sub>n-1</sub></code> are the current and preceding criterion
+     * values (square sum of the weighted residuals of considered measurements).
+     * </p>
+     * @param steadyStateThreshold steady state detection threshold
+     */
+    public void setSteadyStateThreshold(final double steadyStateThreshold) {
+        this.steadyStateThreshold = steadyStateThreshold;
+    }
+
+    /**
+     * Solve an estimation problem using a least squares criterion.
+     *
+     * <p>This method set the unbound parameters of the given problem
+     * starting from their current values through several iterations. At
+     * each step, the unbound parameters are changed in order to
+     * minimize a weighted least square criterion based on the
+     * measurements of the problem.</p>
+     *
+     * <p>The iterations are stopped either when the criterion goes
+     * below a physical threshold under which improvement are considered
+     * useless or when the algorithm is unable to improve it (even if it
+     * is still high). The first condition that is met stops the
+     * iterations. If the convergence it not reached before the maximum
+     * number of iterations, an {@link EstimationException} is
+     * thrown.</p>
+     *
+     * @param problem estimation problem to solve
+     * @exception EstimationException if the problem cannot be solved
+     *
+     * @see EstimationProblem
+     *
+     */
+    @Override
+    public void estimate(EstimationProblem problem)
+    throws EstimationException {
+
+        initializeEstimate(problem);
+
+        // work matrices
+        double[] grad             = new double[parameters.length];
+        ArrayRealVector bDecrement = new ArrayRealVector(parameters.length);
+        double[] bDecrementData   = bDecrement.getDataRef();
+        RealMatrix wGradGradT     = MatrixUtils.createRealMatrix(parameters.length, parameters.length);
+
+        // iterate until convergence is reached
+        double previous = Double.POSITIVE_INFINITY;
+        do {
+
+            // build the linear problem
+            incrementJacobianEvaluationsCounter();
+            RealVector b = new ArrayRealVector(parameters.length);
+            RealMatrix a = MatrixUtils.createRealMatrix(parameters.length, parameters.length);
+            for (int i = 0; i < measurements.length; ++i) {
+                if (! measurements [i].isIgnored()) {
+
+                    double weight   = measurements[i].getWeight();
+                    double residual = measurements[i].getResidual();
+
+                    // compute the normal equation
+                    for (int j = 0; j < parameters.length; ++j) {
+                        grad[j] = measurements[i].getPartial(parameters[j]);
+                        bDecrementData[j] = weight * residual * grad[j];
+                    }
+
+                    // build the contribution matrix for measurement i
+                    for (int k = 0; k < parameters.length; ++k) {
+                        double gk = grad[k];
+                        for (int l = 0; l < parameters.length; ++l) {
+                            wGradGradT.setEntry(k, l, weight * gk * grad[l]);
+                        }
+                    }
+
+                    // update the matrices
+                    a = a.add(wGradGradT);
+                    b = b.add(bDecrement);
+
+                }
+            }
+
+            try {
+
+                // solve the linearized least squares problem
+                RealVector dX = new LUDecompositionImpl(a).getSolver().solve(b);
+
+                // update the estimated parameters
+                for (int i = 0; i < parameters.length; ++i) {
+                    parameters[i].setEstimate(parameters[i].getEstimate() + dX.getEntry(i));
+                }
+
+            } catch(InvalidMatrixException e) {
+                throw new EstimationException(LocalizedFormats.UNABLE_TO_SOLVE_SINGULAR_PROBLEM);
+            }
+
+
+            previous = cost;
+            updateResidualsAndCost();
+
+        } while ((getCostEvaluations() < 2) ||
+                 (FastMath.abs(previous - cost) > (cost * steadyStateThreshold) &&
+                  (FastMath.abs(cost) > convergence)));
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.java b/src/main/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.java
new file mode 100644
index 0000000..78a4661
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.java
@@ -0,0 +1,897 @@
+/*
+ * 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.estimation;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class solves a least squares problem.
+ *
+ * <p>This implementation <em>should</em> work even for over-determined systems
+ * (i.e. systems having more variables than equations). Over-determined systems
+ * are solved by ignoring the variables which have the smallest impact according
+ * to their jacobian column norm. Only the rank of the matrix and some loop bounds
+ * are changed to implement this.</p>
+ *
+ * <p>The resolution engine is a simple translation of the MINPACK <a
+ * href="http://www.netlib.org/minpack/lmder.f">lmder</a> routine with minor
+ * changes. The changes include the over-determined resolution and the Q.R.
+ * decomposition which has been rewritten following the algorithm described in the
+ * P. Lascaux and R. Theodor book <i>Analyse num&eacute;rique matricielle
+ * appliqu&eacute;e &agrave; l'art de l'ing&eacute;nieur</i>, Masson 1986.</p>
+ * <p>The authors of the original fortran version are:
+ * <ul>
+ * <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+ * <li>Burton S. Garbow</li>
+ * <li>Kenneth E. Hillstrom</li>
+ * <li>Jorge J. More</li>
+ * </ul>
+ * The redistribution policy for MINPACK is available <a
+ * href="http://www.netlib.org/minpack/disclaimer">here</a>, for convenience, it
+ * is reproduced below.</p>
+ *
+ * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+ * <tr><td>
+ *    Minpack Copyright Notice (1999) University of Chicago.
+ *    All rights reserved
+ * </td></tr>
+ * <tr><td>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * <ol>
+ *  <li>Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.</li>
+ * <li>Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.</li>
+ * <li>The end-user documentation included with the redistribution, if any,
+ *     must include the following acknowledgment:
+ *     <code>This product includes software developed by the University of
+ *           Chicago, as Operator of Argonne National Laboratory.</code>
+ *     Alternately, this acknowledgment may appear in the software itself,
+ *     if and wherever such third-party acknowledgments normally appear.</li>
+ * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
+ *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
+ *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
+ *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
+ *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
+ *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
+ *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
+ *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
+ *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
+ *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
+ *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
+ *     BE CORRECTED.</strong></li>
+ * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
+ *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
+ *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
+ *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
+ *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
+ *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
+ *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
+ *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
+ *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
+ *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
+ * <ol></td></tr>
+ * </table>
+
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ *
+ */
+@Deprecated
+public class LevenbergMarquardtEstimator extends AbstractEstimator implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -5705952631533171019L;
+
+    /** Number of solved variables. */
+    private int solvedCols;
+
+    /** Diagonal elements of the R matrix in the Q.R. decomposition. */
+    private double[] diagR;
+
+    /** Norms of the columns of the jacobian matrix. */
+    private double[] jacNorm;
+
+    /** Coefficients of the Householder transforms vectors. */
+    private double[] beta;
+
+    /** Columns permutation array. */
+    private int[] permutation;
+
+    /** Rank of the jacobian matrix. */
+    private int rank;
+
+    /** Levenberg-Marquardt parameter. */
+    private double lmPar;
+
+    /** Parameters evolution direction associated with lmPar. */
+    private double[] lmDir;
+
+    /** Positive input variable used in determining the initial step bound. */
+    private double initialStepBoundFactor;
+
+    /** Desired relative error in the sum of squares. */
+    private double costRelativeTolerance;
+
+    /**  Desired relative error in the approximate solution parameters. */
+    private double parRelativeTolerance;
+
+    /** Desired max cosine on the orthogonality between the function vector
+     * and the columns of the jacobian. */
+    private double orthoTolerance;
+
+  /**
+   * Build an estimator for least squares problems.
+   * <p>The default values for the algorithm settings are:
+   *   <ul>
+   *    <li>{@link #setInitialStepBoundFactor initial step bound factor}: 100.0</li>
+   *    <li>{@link #setMaxCostEval maximal cost evaluations}: 1000</li>
+   *    <li>{@link #setCostRelativeTolerance cost relative tolerance}: 1.0e-10</li>
+   *    <li>{@link #setParRelativeTolerance parameters relative tolerance}: 1.0e-10</li>
+   *    <li>{@link #setOrthoTolerance orthogonality tolerance}: 1.0e-10</li>
+   *   </ul>
+   * </p>
+   */
+  public LevenbergMarquardtEstimator() {
+
+    // set up the superclass with a default  max cost evaluations setting
+    setMaxCostEval(1000);
+
+    // default values for the tuning parameters
+    setInitialStepBoundFactor(100.0);
+    setCostRelativeTolerance(1.0e-10);
+    setParRelativeTolerance(1.0e-10);
+    setOrthoTolerance(1.0e-10);
+
+  }
+
+  /**
+   * Set the positive input variable used in determining the initial step bound.
+   * This bound is set to the product of initialStepBoundFactor and the euclidean norm of diag*x if nonzero,
+   * or else to initialStepBoundFactor itself. In most cases factor should lie
+   * in the interval (0.1, 100.0). 100.0 is a generally recommended value
+   *
+   * @param initialStepBoundFactor initial step bound factor
+   * @see #estimate
+   */
+  public void setInitialStepBoundFactor(double initialStepBoundFactor) {
+    this.initialStepBoundFactor = initialStepBoundFactor;
+  }
+
+  /**
+   * Set the desired relative error in the sum of squares.
+   *
+   * @param costRelativeTolerance desired relative error in the sum of squares
+   * @see #estimate
+   */
+  public void setCostRelativeTolerance(double costRelativeTolerance) {
+    this.costRelativeTolerance = costRelativeTolerance;
+  }
+
+  /**
+   * Set the desired relative error in the approximate solution parameters.
+   *
+   * @param parRelativeTolerance desired relative error
+   * in the approximate solution parameters
+   * @see #estimate
+   */
+  public void setParRelativeTolerance(double parRelativeTolerance) {
+    this.parRelativeTolerance = parRelativeTolerance;
+  }
+
+  /**
+   * Set the desired max cosine on the orthogonality.
+   *
+   * @param orthoTolerance desired max cosine on the orthogonality
+   * between the function vector and the columns of the jacobian
+   * @see #estimate
+   */
+  public void setOrthoTolerance(double orthoTolerance) {
+    this.orthoTolerance = orthoTolerance;
+  }
+
+  /**
+   * Solve an estimation problem using the Levenberg-Marquardt algorithm.
+   * <p>The algorithm used is a modified Levenberg-Marquardt one, based
+   * on the MINPACK <a href="http://www.netlib.org/minpack/lmder.f">lmder</a>
+   * routine. The algorithm settings must have been set up before this method
+   * is called with the {@link #setInitialStepBoundFactor},
+   * {@link #setMaxCostEval}, {@link #setCostRelativeTolerance},
+   * {@link #setParRelativeTolerance} and {@link #setOrthoTolerance} methods.
+   * If these methods have not been called, the default values set up by the
+   * {@link #LevenbergMarquardtEstimator() constructor} will be used.</p>
+   * <p>The authors of the original fortran function are:</p>
+   * <ul>
+   *   <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+   *   <li>Burton  S. Garbow</li>
+   *   <li>Kenneth E. Hillstrom</li>
+   *   <li>Jorge   J. More</li>
+   *   </ul>
+   * <p>Luc Maisonobe did the Java translation.</p>
+   *
+   * @param problem estimation problem to solve
+   * @exception EstimationException if convergence cannot be
+   * reached with the specified algorithm settings or if there are more variables
+   * than equations
+   * @see #setInitialStepBoundFactor
+   * @see #setCostRelativeTolerance
+   * @see #setParRelativeTolerance
+   * @see #setOrthoTolerance
+   */
+  @Override
+  public void estimate(EstimationProblem problem)
+    throws EstimationException {
+
+    initializeEstimate(problem);
+
+    // arrays shared with the other private methods
+    solvedCols  = FastMath.min(rows, cols);
+    diagR       = new double[cols];
+    jacNorm     = new double[cols];
+    beta        = new double[cols];
+    permutation = new int[cols];
+    lmDir       = new double[cols];
+
+    // local variables
+    double   delta   = 0;
+    double   xNorm = 0;
+    double[] diag    = new double[cols];
+    double[] oldX    = new double[cols];
+    double[] oldRes  = new double[rows];
+    double[] work1   = new double[cols];
+    double[] work2   = new double[cols];
+    double[] work3   = new double[cols];
+
+    // evaluate the function at the starting point and calculate its norm
+    updateResidualsAndCost();
+
+    // outer loop
+    lmPar = 0;
+    boolean firstIteration = true;
+    while (true) {
+
+      // compute the Q.R. decomposition of the jacobian matrix
+      updateJacobian();
+      qrDecomposition();
+
+      // compute Qt.res
+      qTy(residuals);
+
+      // now we don't need Q anymore,
+      // so let jacobian contain the R matrix with its diagonal elements
+      for (int k = 0; k < solvedCols; ++k) {
+        int pk = permutation[k];
+        jacobian[k * cols + pk] = diagR[pk];
+      }
+
+      if (firstIteration) {
+
+        // scale the variables according to the norms of the columns
+        // of the initial jacobian
+        xNorm = 0;
+        for (int k = 0; k < cols; ++k) {
+          double dk = jacNorm[k];
+          if (dk == 0) {
+            dk = 1.0;
+          }
+          double xk = dk * parameters[k].getEstimate();
+          xNorm  += xk * xk;
+          diag[k] = dk;
+        }
+        xNorm = FastMath.sqrt(xNorm);
+
+        // initialize the step bound delta
+        delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm);
+
+      }
+
+      // check orthogonality between function vector and jacobian columns
+      double maxCosine = 0;
+      if (cost != 0) {
+        for (int j = 0; j < solvedCols; ++j) {
+          int    pj = permutation[j];
+          double s  = jacNorm[pj];
+          if (s != 0) {
+            double sum = 0;
+            int index = pj;
+            for (int i = 0; i <= j; ++i) {
+              sum += jacobian[index] * residuals[i];
+              index += cols;
+            }
+            maxCosine = FastMath.max(maxCosine, FastMath.abs(sum) / (s * cost));
+          }
+        }
+      }
+      if (maxCosine <= orthoTolerance) {
+        return;
+      }
+
+      // rescale if necessary
+      for (int j = 0; j < cols; ++j) {
+        diag[j] = FastMath.max(diag[j], jacNorm[j]);
+      }
+
+      // inner loop
+      for (double ratio = 0; ratio < 1.0e-4;) {
+
+        // save the state
+        for (int j = 0; j < solvedCols; ++j) {
+          int pj = permutation[j];
+          oldX[pj] = parameters[pj].getEstimate();
+        }
+        double previousCost = cost;
+        double[] tmpVec = residuals;
+        residuals = oldRes;
+        oldRes    = tmpVec;
+
+        // determine the Levenberg-Marquardt parameter
+        determineLMParameter(oldRes, delta, diag, work1, work2, work3);
+
+        // compute the new point and the norm of the evolution direction
+        double lmNorm = 0;
+        for (int j = 0; j < solvedCols; ++j) {
+          int pj = permutation[j];
+          lmDir[pj] = -lmDir[pj];
+          parameters[pj].setEstimate(oldX[pj] + lmDir[pj]);
+          double s = diag[pj] * lmDir[pj];
+          lmNorm  += s * s;
+        }
+        lmNorm = FastMath.sqrt(lmNorm);
+
+        // on the first iteration, adjust the initial step bound.
+        if (firstIteration) {
+          delta = FastMath.min(delta, lmNorm);
+        }
+
+        // evaluate the function at x + p and calculate its norm
+        updateResidualsAndCost();
+
+        // compute the scaled actual reduction
+        double actRed = -1.0;
+        if (0.1 * cost < previousCost) {
+          double r = cost / previousCost;
+          actRed = 1.0 - r * r;
+        }
+
+        // compute the scaled predicted reduction
+        // and the scaled directional derivative
+        for (int j = 0; j < solvedCols; ++j) {
+          int pj = permutation[j];
+          double dirJ = lmDir[pj];
+          work1[j] = 0;
+          int index = pj;
+          for (int i = 0; i <= j; ++i) {
+            work1[i] += jacobian[index] * dirJ;
+            index += cols;
+          }
+        }
+        double coeff1 = 0;
+        for (int j = 0; j < solvedCols; ++j) {
+         coeff1 += work1[j] * work1[j];
+        }
+        double pc2 = previousCost * previousCost;
+        coeff1 = coeff1 / pc2;
+        double coeff2 = lmPar * lmNorm * lmNorm / pc2;
+        double preRed = coeff1 + 2 * coeff2;
+        double dirDer = -(coeff1 + coeff2);
+
+        // ratio of the actual to the predicted reduction
+        ratio = (preRed == 0) ? 0 : (actRed / preRed);
+
+        // update the step bound
+        if (ratio <= 0.25) {
+          double tmp =
+            (actRed < 0) ? (0.5 * dirDer / (dirDer + 0.5 * actRed)) : 0.5;
+          if ((0.1 * cost >= previousCost) || (tmp < 0.1)) {
+            tmp = 0.1;
+          }
+          delta = tmp * FastMath.min(delta, 10.0 * lmNorm);
+          lmPar /= tmp;
+        } else if ((lmPar == 0) || (ratio >= 0.75)) {
+          delta = 2 * lmNorm;
+          lmPar *= 0.5;
+        }
+
+        // test for successful iteration.
+        if (ratio >= 1.0e-4) {
+          // successful iteration, update the norm
+          firstIteration = false;
+          xNorm = 0;
+          for (int k = 0; k < cols; ++k) {
+            double xK = diag[k] * parameters[k].getEstimate();
+            xNorm    += xK * xK;
+          }
+          xNorm = FastMath.sqrt(xNorm);
+        } else {
+          // failed iteration, reset the previous values
+          cost = previousCost;
+          for (int j = 0; j < solvedCols; ++j) {
+            int pj = permutation[j];
+            parameters[pj].setEstimate(oldX[pj]);
+          }
+          tmpVec    = residuals;
+          residuals = oldRes;
+          oldRes    = tmpVec;
+        }
+
+        // tests for convergence.
+        if (((FastMath.abs(actRed) <= costRelativeTolerance) &&
+             (preRed <= costRelativeTolerance) &&
+             (ratio <= 2.0)) ||
+             (delta <= parRelativeTolerance * xNorm)) {
+          return;
+        }
+
+        // tests for termination and stringent tolerances
+        // (2.2204e-16 is the machine epsilon for IEEE754)
+        if ((FastMath.abs(actRed) <= 2.2204e-16) && (preRed <= 2.2204e-16) && (ratio <= 2.0)) {
+          throw new EstimationException("cost relative tolerance is too small ({0})," +
+                                        " no further reduction in the" +
+                                        " sum of squares is possible",
+                                        costRelativeTolerance);
+        } else if (delta <= 2.2204e-16 * xNorm) {
+          throw new EstimationException("parameters relative tolerance is too small" +
+                                        " ({0}), no further improvement in" +
+                                        " the approximate solution is possible",
+                                        parRelativeTolerance);
+        } else if (maxCosine <= 2.2204e-16)  {
+          throw new EstimationException("orthogonality tolerance is too small ({0})," +
+                                        " solution is orthogonal to the jacobian",
+                                        orthoTolerance);
+        }
+
+      }
+
+    }
+
+  }
+
+  /**
+   * Determine the Levenberg-Marquardt parameter.
+   * <p>This implementation is a translation in Java of the MINPACK
+   * <a href="http://www.netlib.org/minpack/lmpar.f">lmpar</a>
+   * routine.</p>
+   * <p>This method sets the lmPar and lmDir attributes.</p>
+   * <p>The authors of the original fortran function are:</p>
+   * <ul>
+   *   <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+   *   <li>Burton  S. Garbow</li>
+   *   <li>Kenneth E. Hillstrom</li>
+   *   <li>Jorge   J. More</li>
+   * </ul>
+   * <p>Luc Maisonobe did the Java translation.</p>
+   *
+   * @param qy array containing qTy
+   * @param delta upper bound on the euclidean norm of diagR * lmDir
+   * @param diag diagonal matrix
+   * @param work1 work array
+   * @param work2 work array
+   * @param work3 work array
+   */
+  private void determineLMParameter(double[] qy, double delta, double[] diag,
+                                    double[] work1, double[] work2, double[] work3) {
+
+    // compute and store in x the gauss-newton direction, if the
+    // jacobian is rank-deficient, obtain a least squares solution
+    for (int j = 0; j < rank; ++j) {
+      lmDir[permutation[j]] = qy[j];
+    }
+    for (int j = rank; j < cols; ++j) {
+      lmDir[permutation[j]] = 0;
+    }
+    for (int k = rank - 1; k >= 0; --k) {
+      int pk = permutation[k];
+      double ypk = lmDir[pk] / diagR[pk];
+      int index = pk;
+      for (int i = 0; i < k; ++i) {
+        lmDir[permutation[i]] -= ypk * jacobian[index];
+        index += cols;
+      }
+      lmDir[pk] = ypk;
+    }
+
+    // evaluate the function at the origin, and test
+    // for acceptance of the Gauss-Newton direction
+    double dxNorm = 0;
+    for (int j = 0; j < solvedCols; ++j) {
+      int pj = permutation[j];
+      double s = diag[pj] * lmDir[pj];
+      work1[pj] = s;
+      dxNorm += s * s;
+    }
+    dxNorm = FastMath.sqrt(dxNorm);
+    double fp = dxNorm - delta;
+    if (fp <= 0.1 * delta) {
+      lmPar = 0;
+      return;
+    }
+
+    // if the jacobian is not rank deficient, the Newton step provides
+    // a lower bound, parl, for the zero of the function,
+    // otherwise set this bound to zero
+    double sum2;
+    double parl = 0;
+    if (rank == solvedCols) {
+      for (int j = 0; j < solvedCols; ++j) {
+        int pj = permutation[j];
+        work1[pj] *= diag[pj] / dxNorm;
+      }
+      sum2 = 0;
+      for (int j = 0; j < solvedCols; ++j) {
+        int pj = permutation[j];
+        double sum = 0;
+        int index = pj;
+        for (int i = 0; i < j; ++i) {
+          sum += jacobian[index] * work1[permutation[i]];
+          index += cols;
+        }
+        double s = (work1[pj] - sum) / diagR[pj];
+        work1[pj] = s;
+        sum2 += s * s;
+      }
+      parl = fp / (delta * sum2);
+    }
+
+    // calculate an upper bound, paru, for the zero of the function
+    sum2 = 0;
+    for (int j = 0; j < solvedCols; ++j) {
+      int pj = permutation[j];
+      double sum = 0;
+      int index = pj;
+      for (int i = 0; i <= j; ++i) {
+        sum += jacobian[index] * qy[i];
+        index += cols;
+      }
+      sum /= diag[pj];
+      sum2 += sum * sum;
+    }
+    double gNorm = FastMath.sqrt(sum2);
+    double paru = gNorm / delta;
+    if (paru == 0) {
+      // 2.2251e-308 is the smallest positive real for IEE754
+      paru = 2.2251e-308 / FastMath.min(delta, 0.1);
+    }
+
+    // if the input par lies outside of the interval (parl,paru),
+    // set par to the closer endpoint
+    lmPar = FastMath.min(paru, FastMath.max(lmPar, parl));
+    if (lmPar == 0) {
+      lmPar = gNorm / dxNorm;
+    }
+
+    for (int countdown = 10; countdown >= 0; --countdown) {
+
+      // evaluate the function at the current value of lmPar
+      if (lmPar == 0) {
+        lmPar = FastMath.max(2.2251e-308, 0.001 * paru);
+      }
+      double sPar = FastMath.sqrt(lmPar);
+      for (int j = 0; j < solvedCols; ++j) {
+        int pj = permutation[j];
+        work1[pj] = sPar * diag[pj];
+      }
+      determineLMDirection(qy, work1, work2, work3);
+
+      dxNorm = 0;
+      for (int j = 0; j < solvedCols; ++j) {
+        int pj = permutation[j];
+        double s = diag[pj] * lmDir[pj];
+        work3[pj] = s;
+        dxNorm += s * s;
+      }
+      dxNorm = FastMath.sqrt(dxNorm);
+      double previousFP = fp;
+      fp = dxNorm - delta;
+
+      // if the function is small enough, accept the current value
+      // of lmPar, also test for the exceptional cases where parl is zero
+      if ((FastMath.abs(fp) <= 0.1 * delta) ||
+          ((parl == 0) && (fp <= previousFP) && (previousFP < 0))) {
+        return;
+      }
+
+      // compute the Newton correction
+      for (int j = 0; j < solvedCols; ++j) {
+       int pj = permutation[j];
+        work1[pj] = work3[pj] * diag[pj] / dxNorm;
+      }
+      for (int j = 0; j < solvedCols; ++j) {
+        int pj = permutation[j];
+        work1[pj] /= work2[j];
+        double tmp = work1[pj];
+        for (int i = j + 1; i < solvedCols; ++i) {
+          work1[permutation[i]] -= jacobian[i * cols + pj] * tmp;
+        }
+      }
+      sum2 = 0;
+      for (int j = 0; j < solvedCols; ++j) {
+        double s = work1[permutation[j]];
+        sum2 += s * s;
+      }
+      double correction = fp / (delta * sum2);
+
+      // depending on the sign of the function, update parl or paru.
+      if (fp > 0) {
+        parl = FastMath.max(parl, lmPar);
+      } else if (fp < 0) {
+        paru = FastMath.min(paru, lmPar);
+      }
+
+      // compute an improved estimate for lmPar
+      lmPar = FastMath.max(parl, lmPar + correction);
+
+    }
+  }
+
+  /**
+   * Solve a*x = b and d*x = 0 in the least squares sense.
+   * <p>This implementation is a translation in Java of the MINPACK
+   * <a href="http://www.netlib.org/minpack/qrsolv.f">qrsolv</a>
+   * routine.</p>
+   * <p>This method sets the lmDir and lmDiag attributes.</p>
+   * <p>The authors of the original fortran function are:</p>
+   * <ul>
+   *   <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+   *   <li>Burton  S. Garbow</li>
+   *   <li>Kenneth E. Hillstrom</li>
+   *   <li>Jorge   J. More</li>
+   * </ul>
+   * <p>Luc Maisonobe did the Java translation.</p>
+   *
+   * @param qy array containing qTy
+   * @param diag diagonal matrix
+   * @param lmDiag diagonal elements associated with lmDir
+   * @param work work array
+   */
+  private void determineLMDirection(double[] qy, double[] diag,
+                                    double[] lmDiag, double[] work) {
+
+    // copy R and Qty to preserve input and initialize s
+    //  in particular, save the diagonal elements of R in lmDir
+    for (int j = 0; j < solvedCols; ++j) {
+      int pj = permutation[j];
+      for (int i = j + 1; i < solvedCols; ++i) {
+        jacobian[i * cols + pj] = jacobian[j * cols + permutation[i]];
+      }
+      lmDir[j] = diagR[pj];
+      work[j]  = qy[j];
+    }
+
+    // eliminate the diagonal matrix d using a Givens rotation
+    for (int j = 0; j < solvedCols; ++j) {
+
+      // prepare the row of d to be eliminated, locating the
+      // diagonal element using p from the Q.R. factorization
+      int pj = permutation[j];
+      double dpj = diag[pj];
+      if (dpj != 0) {
+        Arrays.fill(lmDiag, j + 1, lmDiag.length, 0);
+      }
+      lmDiag[j] = dpj;
+
+      //  the transformations to eliminate the row of d
+      // modify only a single element of Qty
+      // beyond the first n, which is initially zero.
+      double qtbpj = 0;
+      for (int k = j; k < solvedCols; ++k) {
+        int pk = permutation[k];
+
+        // determine a Givens rotation which eliminates the
+        // appropriate element in the current row of d
+        if (lmDiag[k] != 0) {
+
+          final double sin;
+          final double cos;
+          double rkk = jacobian[k * cols + pk];
+          if (FastMath.abs(rkk) < FastMath.abs(lmDiag[k])) {
+            final double cotan = rkk / lmDiag[k];
+            sin   = 1.0 / FastMath.sqrt(1.0 + cotan * cotan);
+            cos   = sin * cotan;
+          } else {
+            final double tan = lmDiag[k] / rkk;
+            cos = 1.0 / FastMath.sqrt(1.0 + tan * tan);
+            sin = cos * tan;
+          }
+
+          // compute the modified diagonal element of R and
+          // the modified element of (Qty,0)
+          jacobian[k * cols + pk] = cos * rkk + sin * lmDiag[k];
+          final double temp = cos * work[k] + sin * qtbpj;
+          qtbpj = -sin * work[k] + cos * qtbpj;
+          work[k] = temp;
+
+          // accumulate the tranformation in the row of s
+          for (int i = k + 1; i < solvedCols; ++i) {
+            double rik = jacobian[i * cols + pk];
+            final double temp2 = cos * rik + sin * lmDiag[i];
+            lmDiag[i] = -sin * rik + cos * lmDiag[i];
+            jacobian[i * cols + pk] = temp2;
+          }
+
+        }
+      }
+
+      // store the diagonal element of s and restore
+      // the corresponding diagonal element of R
+      int index = j * cols + permutation[j];
+      lmDiag[j]       = jacobian[index];
+      jacobian[index] = lmDir[j];
+
+    }
+
+    // solve the triangular system for z, if the system is
+    // singular, then obtain a least squares solution
+    int nSing = solvedCols;
+    for (int j = 0; j < solvedCols; ++j) {
+      if ((lmDiag[j] == 0) && (nSing == solvedCols)) {
+        nSing = j;
+      }
+      if (nSing < solvedCols) {
+        work[j] = 0;
+      }
+    }
+    if (nSing > 0) {
+      for (int j = nSing - 1; j >= 0; --j) {
+        int pj = permutation[j];
+        double sum = 0;
+        for (int i = j + 1; i < nSing; ++i) {
+          sum += jacobian[i * cols + pj] * work[i];
+        }
+        work[j] = (work[j] - sum) / lmDiag[j];
+      }
+    }
+
+    // permute the components of z back to components of lmDir
+    for (int j = 0; j < lmDir.length; ++j) {
+      lmDir[permutation[j]] = work[j];
+    }
+
+  }
+
+  /**
+   * Decompose a matrix A as A.P = Q.R using Householder transforms.
+   * <p>As suggested in the P. Lascaux and R. Theodor book
+   * <i>Analyse num&eacute;rique matricielle appliqu&eacute;e &agrave;
+   * l'art de l'ing&eacute;nieur</i> (Masson, 1986), instead of representing
+   * the Householder transforms with u<sub>k</sub> unit vectors such that:
+   * <pre>
+   * H<sub>k</sub> = I - 2u<sub>k</sub>.u<sub>k</sub><sup>t</sup>
+   * </pre>
+   * we use <sub>k</sub> non-unit vectors such that:
+   * <pre>
+   * H<sub>k</sub> = I - beta<sub>k</sub>v<sub>k</sub>.v<sub>k</sub><sup>t</sup>
+   * </pre>
+   * where v<sub>k</sub> = a<sub>k</sub> - alpha<sub>k</sub> e<sub>k</sub>.
+   * The beta<sub>k</sub> coefficients are provided upon exit as recomputing
+   * them from the v<sub>k</sub> vectors would be costly.</p>
+   * <p>This decomposition handles rank deficient cases since the tranformations
+   * are performed in non-increasing columns norms order thanks to columns
+   * pivoting. The diagonal elements of the R matrix are therefore also in
+   * non-increasing absolute values order.</p>
+   * @exception EstimationException if the decomposition cannot be performed
+   */
+  private void qrDecomposition() throws EstimationException {
+
+    // initializations
+    for (int k = 0; k < cols; ++k) {
+      permutation[k] = k;
+      double norm2 = 0;
+      for (int index = k; index < jacobian.length; index += cols) {
+        double akk = jacobian[index];
+        norm2 += akk * akk;
+      }
+      jacNorm[k] = FastMath.sqrt(norm2);
+    }
+
+    // transform the matrix column after column
+    for (int k = 0; k < cols; ++k) {
+
+      // select the column with the greatest norm on active components
+      int nextColumn = -1;
+      double ak2 = Double.NEGATIVE_INFINITY;
+      for (int i = k; i < cols; ++i) {
+        double norm2 = 0;
+        int iDiag = k * cols + permutation[i];
+        for (int index = iDiag; index < jacobian.length; index += cols) {
+          double aki = jacobian[index];
+          norm2 += aki * aki;
+        }
+        if (Double.isInfinite(norm2) || Double.isNaN(norm2)) {
+            throw new EstimationException(
+                    LocalizedFormats.UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN,
+                    rows, cols);
+        }
+        if (norm2 > ak2) {
+          nextColumn = i;
+          ak2        = norm2;
+        }
+      }
+      if (ak2 == 0) {
+        rank = k;
+        return;
+      }
+      int pk                  = permutation[nextColumn];
+      permutation[nextColumn] = permutation[k];
+      permutation[k]          = pk;
+
+      // choose alpha such that Hk.u = alpha ek
+      int    kDiag = k * cols + pk;
+      double akk   = jacobian[kDiag];
+      double alpha = (akk > 0) ? -FastMath.sqrt(ak2) : FastMath.sqrt(ak2);
+      double betak = 1.0 / (ak2 - akk * alpha);
+      beta[pk]     = betak;
+
+      // transform the current column
+      diagR[pk]        = alpha;
+      jacobian[kDiag] -= alpha;
+
+      // transform the remaining columns
+      for (int dk = cols - 1 - k; dk > 0; --dk) {
+        int dkp = permutation[k + dk] - pk;
+        double gamma = 0;
+        for (int index = kDiag; index < jacobian.length; index += cols) {
+          gamma += jacobian[index] * jacobian[index + dkp];
+        }
+        gamma *= betak;
+        for (int index = kDiag; index < jacobian.length; index += cols) {
+          jacobian[index + dkp] -= gamma * jacobian[index];
+        }
+      }
+
+    }
+
+    rank = solvedCols;
+
+  }
+
+  /**
+   * Compute the product Qt.y for some Q.R. decomposition.
+   *
+   * @param y vector to multiply (will be overwritten with the result)
+   */
+  private void qTy(double[] y) {
+    for (int k = 0; k < cols; ++k) {
+      int pk = permutation[k];
+      int kDiag = k * cols + pk;
+      double gamma = 0;
+      int index = kDiag;
+      for (int i = k; i < rows; ++i) {
+        gamma += jacobian[index] * y[i];
+        index += cols;
+      }
+      gamma *= beta[pk];
+      index = kDiag;
+      for (int i = k; i < rows; ++i) {
+        y[i] -= gamma * jacobian[index];
+        index += cols;
+      }
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/SimpleEstimationProblem.java b/src/main/java/org/apache/commons/math/estimation/SimpleEstimationProblem.java
new file mode 100644
index 0000000..d9449d0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/SimpleEstimationProblem.java
@@ -0,0 +1,111 @@
+/*
+ * 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.estimation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple implementation of the {@link EstimationProblem
+ * EstimationProblem} interface for boilerplate data handling.
+ * <p>This class <em>only</em> handles parameters and measurements
+ * storage and unbound parameters filtering. It does not compute
+ * anything by itself. It should either be used with measurements
+ * implementation that are smart enough to know about the
+ * various parameters in order to compute the partial derivatives
+ * appropriately. Since the problem-specific logic is mainly related to
+ * the various measurements models, the simplest way to use this class
+ * is by extending it and using one internal class extending
+ * {@link WeightedMeasurement WeightedMeasurement} for each measurement
+ * type. The instances of the internal classes would have access to the
+ * various parameters and their current estimate.</p>
+
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+
+ */
+@Deprecated
+public class SimpleEstimationProblem implements EstimationProblem {
+
+    /** Estimated parameters. */
+    private final List<EstimatedParameter> parameters;
+
+    /** Measurements. */
+    private final List<WeightedMeasurement> measurements;
+
+    /**
+     * Build an empty instance without parameters nor measurements.
+     */
+    public SimpleEstimationProblem() {
+        parameters   = new ArrayList<EstimatedParameter>();
+        measurements = new ArrayList<WeightedMeasurement>();
+    }
+
+    /**
+     * Get all the parameters of the problem.
+     * @return parameters
+     */
+    public EstimatedParameter[] getAllParameters() {
+        return parameters.toArray(new EstimatedParameter[parameters.size()]);
+    }
+
+    /**
+     * Get the unbound parameters of the problem.
+     * @return unbound parameters
+     */
+    public EstimatedParameter[] getUnboundParameters() {
+
+        // filter the unbound parameters
+        List<EstimatedParameter> unbound = new ArrayList<EstimatedParameter>(parameters.size());
+        for (EstimatedParameter p : parameters) {
+            if (! p.isBound()) {
+                unbound.add(p);
+            }
+        }
+
+        // convert to an array
+        return unbound.toArray(new EstimatedParameter[unbound.size()]);
+
+    }
+
+    /**
+     * Get the measurements of an estimation problem.
+     * @return measurements
+     */
+    public WeightedMeasurement[] getMeasurements() {
+        return measurements.toArray(new WeightedMeasurement[measurements.size()]);
+    }
+
+    /** Add a parameter to the problem.
+     * @param p parameter to add
+     */
+    protected void addParameter(EstimatedParameter p) {
+        parameters.add(p);
+    }
+
+    /**
+     * Add a new measurement to the set.
+     * @param m measurement to add
+     */
+    protected void addMeasurement(WeightedMeasurement m) {
+        measurements.add(m);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/WeightedMeasurement.java b/src/main/java/org/apache/commons/math/estimation/WeightedMeasurement.java
new file mode 100644
index 0000000..cc6ac9f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/WeightedMeasurement.java
@@ -0,0 +1,172 @@
+/*
+ * 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.estimation;
+
+import java.io.Serializable;
+
+/**
+ * This class represents measurements in estimation problems.
+ *
+ * <p>This abstract class implements all the methods needed to handle
+ * measurements in a general way. It defines neither the {@link
+ * #getTheoreticalValue getTheoreticalValue} nor the {@link
+ * #getPartial getPartial} methods, which should be defined by
+ * sub-classes according to the specific problem.</p>
+ *
+ * <p>The {@link #getTheoreticalValue getTheoreticalValue} and {@link
+ * #getPartial getPartial} methods must always use the current
+ * estimate of the parameters set by the solver in the problem. These
+ * parameters can be retrieved through the {@link
+ * EstimationProblem#getAllParameters
+ * EstimationProblem.getAllParameters} method if the measurements are
+ * independent of the problem, or directly if they are implemented as
+ * inner classes of the problem.</p>
+ *
+ * <p>The instances for which the <code>ignored</code> flag is set
+ * through the {@link #setIgnored setIgnored} method are ignored by the
+ * solvers. This can be used to reject wrong measurements at some
+ * steps of the estimation.</p>
+ *
+ * @see EstimationProblem
+ *
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
+ * been deprecated and replaced by package org.apache.commons.math.optimization.general
+ */
+
+@Deprecated
+public abstract class WeightedMeasurement implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 4360046376796901941L;
+
+    /** Measurement weight. */
+    private final double  weight;
+
+    /** Value of the measurements. */
+    private final double  measuredValue;
+
+    /** Ignore measurement indicator. */
+    private boolean ignored;
+
+  /**
+   * Simple constructor.
+   * Build a measurement with the given parameters, and set its ignore
+   * flag to false.
+   * @param weight weight of the measurement in the least squares problem
+   * (two common choices are either to use 1.0 for all measurements, or to
+   * use a value proportional to the inverse of the variance of the measurement
+   * type)
+   *
+   * @param measuredValue measured value
+   */
+  public WeightedMeasurement(double weight, double measuredValue) {
+    this.weight        = weight;
+    this.measuredValue = measuredValue;
+    ignored            = false;
+  }
+
+  /** Simple constructor.
+   *
+   * Build a measurement with the given parameters
+   *
+   * @param weight weight of the measurement in the least squares problem
+   * @param measuredValue measured value
+   * @param ignored true if the measurement should be ignored
+   */
+  public WeightedMeasurement(double weight, double measuredValue,
+                             boolean ignored) {
+    this.weight        = weight;
+    this.measuredValue = measuredValue;
+    this.ignored       = ignored;
+  }
+
+  /**
+   * Get the weight of the measurement in the least squares problem
+   *
+   * @return weight
+   */
+  public double getWeight() {
+    return weight;
+  }
+
+  /**
+   * Get the measured value
+   *
+   * @return measured value
+   */
+  public double getMeasuredValue() {
+    return measuredValue;
+  }
+
+  /**
+   * Get the residual for this measurement
+   * The residual is the measured value minus the theoretical value.
+   *
+   * @return residual
+   */
+  public double getResidual() {
+    return measuredValue - getTheoreticalValue();
+  }
+
+  /**
+   * Get the theoretical value expected for this measurement
+   * <p>The theoretical value is the value expected for this measurement
+   * if the model and its parameter were all perfectly known.</p>
+   * <p>The value must be computed using the current estimate of the parameters
+   * set by the solver in the problem.</p>
+   *
+   * @return theoretical value
+   */
+  public abstract double getTheoreticalValue();
+
+  /**
+   * Get the partial derivative of the {@link #getTheoreticalValue
+   * theoretical value} according to the parameter.
+   * <p>The value must be computed using the current estimate of the parameters
+   * set by the solver in the problem.</p>
+   *
+   * @param parameter parameter against which the partial derivative
+   * should be computed
+   * @return partial derivative of the {@link #getTheoreticalValue
+   * theoretical value}
+   */
+  public abstract double getPartial(EstimatedParameter parameter);
+
+  /**
+   * Set the ignore flag to the specified value
+   * Setting the ignore flag to true allow to reject wrong
+   * measurements, which sometimes can be detected only rather late.
+   *
+   * @param ignored value for the ignore flag
+   */
+  public void setIgnored(boolean ignored) {
+    this.ignored = ignored;
+  }
+
+  /**
+   * Check if this measurement should be ignored
+   *
+   * @return true if the measurement should be ignored
+   */
+  public boolean isIgnored() {
+    return ignored;
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/estimation/package.html b/src/main/java/org/apache/commons/math/estimation/package.html
new file mode 100644
index 0000000..2f4dc05
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/estimation/package.html
@@ -0,0 +1,25 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 754732 $ -->
+<body>
+This package provided classes to solve estimation problems, it is deprecated since 2.0.
+
+<p>This package has been deprecated as of 2.0. It is replaced by the optimization.general package.</p>
+
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/exception/ConvergenceException.java b/src/main/java/org/apache/commons/math/exception/ConvergenceException.java
new file mode 100644
index 0000000..0e1a976
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/ConvergenceException.java
@@ -0,0 +1,61 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when a numerical computation can not be performed because the
+ * numerical result failed to converge to a finite value.
+ *
+ * @since 2.2
+ * @version $Revision: 1026666 $ $Date: 2010-10-23 21:30:48 +0200 (sam. 23 oct. 2010) $
+ */
+public class ConvergenceException extends MathIllegalStateException {
+    /** Serializable version Id. */
+    private static final long serialVersionUID = 4330003017885151975L;
+
+    /**
+     * Construct the exception.
+     */
+    public ConvergenceException() {
+        this(null);
+    }
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Specific contexte pattern.
+     */
+    public ConvergenceException(Localizable specific) {
+        this(specific,
+             LocalizedFormats.CONVERGENCE_FAILED,
+             null);
+    }
+    /**
+     * Construct the exception with a specific context and arguments.
+     *
+     * @param specific Specific contexte pattern.
+     * @param args Arguments.
+     */
+    public ConvergenceException(Localizable specific,
+                                Object ... args) {
+        super(specific,
+              LocalizedFormats.CONVERGENCE_FAILED,
+              args);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/DimensionMismatchException.java b/src/main/java/org/apache/commons/math/exception/DimensionMismatchException.java
new file mode 100644
index 0000000..d6a522d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/DimensionMismatchException.java
@@ -0,0 +1,53 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when two dimensions differ.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class DimensionMismatchException extends MathIllegalNumberException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -8415396756375798143L;
+
+    /** Correct dimension. */
+    private final int dimension;
+
+    /**
+     * Construct an exception from the mismatched dimensions.
+     *
+     * @param wrong Wrong dimension.
+     * @param expected Expected dimension.
+     */
+    public DimensionMismatchException(int wrong,
+                                      int expected) {
+        super(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, wrong, expected);
+        dimension = expected;
+    }
+
+    /**
+     * @return the expected dimension.
+     */
+    public int getDimension() {
+        return dimension;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java b/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java
new file mode 100644
index 0000000..fb0ed88
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java
@@ -0,0 +1,112 @@
+/*
+ * 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.exception;
+
+import java.util.Locale;
+
+import org.apache.commons.math.exception.util.ArgUtils;
+import org.apache.commons.math.exception.util.MessageFactory;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Base class for all preconditions violation exceptions.
+ * This class is not intended to be instantiated directly: it should serve
+ * as a base class to create all the exceptions that share the semantics of
+ * the standard {@link IllegalArgumentException}, but must also provide a
+ * localized message.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class MathIllegalArgumentException extends IllegalArgumentException implements MathThrowable {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -6024911025449780478L;
+
+    /**
+     * Pattern used to build the message (specific context).
+     */
+    private final Localizable specific;
+    /**
+     * Pattern used to build the message (general problem description).
+     */
+    private final Localizable general;
+    /**
+     * Arguments used to build the message.
+     */
+    private final Object[] arguments;
+
+    /**
+     * @param specific Message pattern providing the specific context of
+     * the error.
+     * @param general Message pattern explaining the cause of the error.
+     * @param args Arguments.
+     */
+    protected MathIllegalArgumentException(Localizable specific,
+                                           Localizable general,
+                                           Object ... args) {
+        this.specific = specific;
+        this.general = general;
+        arguments = ArgUtils.flatten(args);
+    }
+    /**
+     * @param general Message pattern explaining the cause of the error.
+     * @param args Arguments.
+     */
+    protected MathIllegalArgumentException(Localizable general,
+                                           Object ... args) {
+        this(null, general, args);
+    }
+
+    /** {@inheritDoc} */
+    public Localizable getSpecificPattern() {
+        return specific;
+    }
+
+    /** {@inheritDoc} */
+    public Localizable getGeneralPattern() {
+        return general;
+    }
+
+    /** {@inheritDoc} */
+    public Object[] getArguments() {
+        return arguments.clone();
+    }
+
+    /**
+     * Get the message in a specified locale.
+     *
+     * @param locale Locale in which the message should be translated.
+     *
+     * @return the localized message.
+     */
+    public String getMessage(final Locale locale) {
+        return MessageFactory.buildMessage(locale, specific, general, arguments);
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public String getMessage() {
+        return getMessage(Locale.US);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getLocalizedMessage() {
+        return getMessage(Locale.getDefault());
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/MathIllegalNumberException.java b/src/main/java/org/apache/commons/math/exception/MathIllegalNumberException.java
new file mode 100644
index 0000000..b96ce20
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/MathIllegalNumberException.java
@@ -0,0 +1,74 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Base class for exceptions raised by a wrong number.
+ * This class is not intended to be instantiated directly: it should serve
+ * as a base class to create all the exceptions that are raised because some
+ * precondition is violated by a number argument.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class MathIllegalNumberException extends MathIllegalArgumentException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -7447085893598031110L;
+
+    /** Requested. */
+    private final Number argument;
+
+    /**
+     * Construct an exception.
+     *
+     * @param specific Localizable pattern.
+     * @param general Localizable pattern.
+     * @param wrong wrong number
+     * @param arguments Arguments.
+     */
+    protected MathIllegalNumberException(Localizable specific,
+                                         Localizable general,
+                                         Number wrong,
+                                         Object ... arguments) {
+        super(specific, general, wrong, arguments);
+        argument = wrong;
+    }
+
+    /**
+     * Construct an exception.
+     *
+     * @param general Localizable pattern.
+     * @param wrong wrong number
+     * @param arguments Arguments.
+     */
+    protected MathIllegalNumberException(Localizable general,
+                                         Number wrong,
+                                         Object ... arguments) {
+        super(general, wrong, arguments);
+        argument = wrong;
+    }
+
+    /**
+     * @return the requested value.
+     */
+    public Number getArgument() {
+        return argument;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/MathIllegalStateException.java b/src/main/java/org/apache/commons/math/exception/MathIllegalStateException.java
new file mode 100644
index 0000000..d4e83d4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/MathIllegalStateException.java
@@ -0,0 +1,140 @@
+/*
+ * 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.exception;
+
+import java.util.Locale;
+
+import org.apache.commons.math.exception.util.ArgUtils;
+import org.apache.commons.math.exception.util.MessageFactory;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Base class for all exceptions that signal a mismatch between the
+ * current state and the user's expectations.
+ *
+ * @since 2.2
+ * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $
+ */
+public class MathIllegalStateException extends IllegalStateException implements MathThrowable {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -6024911025449780478L;
+
+    /**
+     * Pattern used to build the message (specific context).
+     */
+    private final Localizable specific;
+    /**
+     * Pattern used to build the message (general problem description).
+     */
+    private final Localizable general;
+    /**
+     * Arguments used to build the message.
+     */
+    private final Object[] arguments;
+
+    /**
+     * Simple constructor.
+     * @param specific Message pattern providing the specific context of
+     * the error.
+     * @param general Message pattern explaining the cause of the error.
+     * @param args Arguments.
+     */
+    public MathIllegalStateException(Localizable specific,
+                                     Localizable general,
+                                     Object ... args) {
+        this(null, specific, general, args);
+    }
+
+    /**
+     * Simple constructor.
+     * @param cause root cause
+     * @param specific Message pattern providing the specific context of
+     * the error.
+     * @param general Message pattern explaining the cause of the error.
+     * @param args Arguments.
+     */
+    public MathIllegalStateException(Throwable cause,
+                                     Localizable specific,
+                                     Localizable general,
+                                     Object ... args) {
+        super(cause);
+        this.specific = specific;
+        this.general = general;
+        arguments = ArgUtils.flatten(args);
+    }
+
+    /**
+     * @param general Message pattern explaining the cause of the error.
+     * @param args Arguments.
+     */
+    public MathIllegalStateException(Localizable general,
+                                     Object ... args) {
+        this(null, null, general, args);
+    }
+
+    /**
+     * Simple constructor.
+     * @param cause root cause
+     * @param general Message pattern explaining the cause of the error.
+     * @param args Arguments.
+     */
+    public MathIllegalStateException(Throwable cause,
+                                     Localizable general,
+                                     Object ... args) {
+        this(cause, null, general, args);
+    }
+
+    /** {@inheritDoc} */
+    public Localizable getSpecificPattern() {
+        return specific;
+    }
+
+    /** {@inheritDoc} */
+    public Localizable getGeneralPattern() {
+        return general;
+    }
+
+    /** {@inheritDoc} */
+    public Object[] getArguments() {
+        return arguments.clone();
+    }
+
+    /**
+     * Get the message in a specified locale.
+     *
+     * @param locale Locale in which the message should be translated.
+     *
+     * @return the localized message.
+     */
+    public String getMessage(final Locale locale) {
+        return MessageFactory.buildMessage(locale, specific, general, arguments);
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public String getMessage() {
+        return getMessage(Locale.US);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getLocalizedMessage() {
+        return getMessage(Locale.getDefault());
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/exception/MathInternalError.java b/src/main/java/org/apache/commons/math/exception/MathInternalError.java
new file mode 100644
index 0000000..623fe93
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/MathInternalError.java
@@ -0,0 +1,50 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception triggered when something that shouldn't happen does happen.
+ *
+ * @since 2.2
+ * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $
+ */
+public class MathInternalError extends MathIllegalStateException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -6276776513966934846L;
+
+    /** URL for reporting problems. */
+    private static final String REPORT_URL = "https://issues.apache.org/jira/browse/MATH";
+
+    /**
+     * Simple constructor.
+     */
+    public MathInternalError() {
+        super(LocalizedFormats.INTERNAL_ERROR, REPORT_URL);
+    }
+
+    /**
+     * Simple constructor.
+     * @param cause root cause
+     */
+    public MathInternalError(final Throwable cause) {
+        super(LocalizedFormats.INTERNAL_ERROR, REPORT_URL);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/exception/MathThrowable.java b/src/main/java/org/apache/commons/math/exception/MathThrowable.java
new file mode 100644
index 0000000..5f47d5c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/MathThrowable.java
@@ -0,0 +1,62 @@
+/*
+ * 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.exception;
+
+import java.util.Locale;
+
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+* Interface for commons-math throwables.
+*
+* @version $Revision: 1035475 $ $Date: 2010-11-15 23:39:25 +0100 (lun. 15 nov. 2010) $
+* @since 2.2
+*/
+public interface MathThrowable {
+
+    /** Gets the localizable pattern used to build the specific part of the message of this throwable.
+     * @return localizable pattern used to build the specific part of the message of this throwable
+     */
+    Localizable getSpecificPattern();
+
+    /** Gets the localizable pattern used to build the general part of the message of this throwable.
+     * @return localizable pattern used to build the general part of the message of this throwable
+     */
+    Localizable getGeneralPattern();
+
+    /** Gets the arguments used to build the message of this throwable.
+     * @return the arguments used to build the message of this throwable
+     */
+    Object[] getArguments();
+
+    /** Gets the message in a specified locale.
+     * @param locale Locale in which the message should be translated
+     * @return localized message
+     */
+    String getMessage(final Locale locale);
+
+    /** Gets the message in a conventional US locale.
+     * @return localized message
+     */
+    String getMessage();
+
+    /** Gets the message in the system default locale.
+     * @return localized message
+     */
+    String getLocalizedMessage();
+
+}
diff --git a/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java b/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java
new file mode 100644
index 0000000..592aa37
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java
@@ -0,0 +1,106 @@
+/*
+ * 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.exception;
+
+import java.util.Locale;
+
+import org.apache.commons.math.exception.util.ArgUtils;
+import org.apache.commons.math.exception.util.MessageFactory;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Base class for all unsupported features.
+ * It is used for all the exceptions that share the semantics of the standard
+ * {@link UnsupportedOperationException}, but must also provide a localized
+ * message.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class MathUnsupportedOperationException extends UnsupportedOperationException implements MathThrowable {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -6024911025449780478L;
+
+    /**
+     * Pattern used to build the message (specific context).
+     */
+    private final Localizable specific;
+    /**
+     * Arguments used to build the message.
+     */
+    private final Object[] arguments;
+
+    /**
+     * @param args Arguments.
+     */
+    public MathUnsupportedOperationException(Object ... args) {
+        this(null, args);
+    }
+    /**
+     * @param specific Message pattern providing the specific context of
+     * the error.
+     * @param args Arguments.
+     */
+    public MathUnsupportedOperationException(Localizable specific,
+                                             Object ... args) {
+        this.specific = specific;
+        arguments = ArgUtils.flatten(args);
+    }
+
+    /** {@inheritDoc} */
+    public Localizable getSpecificPattern() {
+        return specific;
+    }
+
+    /** {@inheritDoc} */
+    public Localizable getGeneralPattern() {
+        return LocalizedFormats.UNSUPPORTED_OPERATION;
+    }
+
+    /** {@inheritDoc} */
+    public Object[] getArguments() {
+        return arguments.clone();
+    }
+
+    /**
+     * Get the message in a specified locale.
+     *
+     * @param locale Locale in which the message should be translated.
+     *
+     * @return the localized message.
+     */
+    public String getMessage(final Locale locale) {
+        return MessageFactory.buildMessage(locale,
+                                           specific,
+                                           LocalizedFormats.UNSUPPORTED_OPERATION,
+                                           arguments);
+    }
+
+   /** {@inheritDoc} */
+    @Override
+    public String getMessage() {
+        return getMessage(Locale.US);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String getLocalizedMessage() {
+        return getMessage(Locale.getDefault());
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NoDataException.java b/src/main/java/org/apache/commons/math/exception/NoDataException.java
new file mode 100644
index 0000000..c1b4d56
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NoDataException.java
@@ -0,0 +1,47 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when the required data is missing.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NoDataException extends MathIllegalStateException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -3629324471511904459L;
+
+    /**
+     * Construct the exception.
+     */
+    public NoDataException() {
+        this(null);
+    }
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Contextual information on what caused the exception.
+     */
+    public NoDataException(Localizable specific) {
+        super(specific, LocalizedFormats.NO_DATA, (Object[]) null);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NonMonotonousSequenceException.java b/src/main/java/org/apache/commons/math/exception/NonMonotonousSequenceException.java
new file mode 100644
index 0000000..3ad11ec
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NonMonotonousSequenceException.java
@@ -0,0 +1,123 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when the a sequence of values is not monotonously
+ * increasing or decreasing.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NonMonotonousSequenceException extends MathIllegalNumberException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = 3596849179428944575L;
+
+    /**
+     * Direction (positive for increasing, negative for decreasing).
+     */
+    private final MathUtils.OrderDirection direction;
+    /**
+     * Whether the sequence must be strictly increasing or decreasing.
+     */
+    private final boolean strict;
+    /**
+     * Index of the wrong value.
+     */
+    private final int index;
+    /**
+     * Previous value.
+     */
+    private final Number previous;
+
+    /**
+     * Construct the exception.
+     * This constructor uses default values assuming that the sequence should
+     * have been strictly increasing.
+     *
+     * @param wrong Value that did not match the requirements.
+     * @param previous Previous value in the sequence.
+     * @param index Index of the value that did not match the requirements.
+     */
+    public NonMonotonousSequenceException(Number wrong,
+                                          Number previous,
+                                          int index) {
+        this(wrong, previous, index, MathUtils.OrderDirection.INCREASING, true);
+    }
+
+    /**
+     * Construct the exception.
+     *
+     * @param wrong Value that did not match the requirements.
+     * @param previous Previous value in the sequence.
+     * @param index Index of the value that did not match the requirements.
+     * @param direction Strictly positive for a sequence required to be
+     * increasing, negative (or zero) for a decreasing sequence.
+     * @param strict Whether the sequence must be strictly increasing or
+     * decreasing.
+     */
+    public NonMonotonousSequenceException(Number wrong,
+                                          Number previous,
+                                          int index,
+                                          MathUtils.OrderDirection direction,
+                                          boolean strict) {
+        super(direction == MathUtils.OrderDirection.INCREASING ?
+              (strict ?
+               LocalizedFormats.NOT_STRICTLY_INCREASING_SEQUENCE :
+               LocalizedFormats.NOT_INCREASING_SEQUENCE) :
+              (strict ?
+               LocalizedFormats.NOT_STRICTLY_DECREASING_SEQUENCE :
+               LocalizedFormats.NOT_DECREASING_SEQUENCE),
+              wrong, previous, index, index - 1);
+
+        this.direction = direction;
+        this.strict = strict;
+        this.index = index;
+        this.previous = previous;
+    }
+
+    /**
+     * @return the order direction.
+     **/
+    public MathUtils.OrderDirection getDirection() {
+        return direction;
+    }
+    /**
+     * @return {@code true} is the sequence should be strictly monotonous.
+     **/
+    public boolean getStrict() {
+        return strict;
+    }
+    /**
+     * Get the index of the wrong value.
+     *
+     * @return the current index.
+     */
+    public int getIndex() {
+        return index;
+    }
+    /**
+     * @return the previous value.
+     */
+    public Number getPrevious() {
+        return previous;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NotPositiveException.java b/src/main/java/org/apache/commons/math/exception/NotPositiveException.java
new file mode 100644
index 0000000..4af597a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NotPositiveException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Exception to be thrown when the argument is negative.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NotPositiveException extends NumberIsTooSmallException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -2250556892093726375L;
+
+    /**
+     * Construct the exception.
+     *
+     * @param value Argument.
+     */
+    public NotPositiveException(Number value) {
+        super(value, 0, true);
+    }
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Specific context where the error occurred.
+     * @param value Argument.
+     */
+    public NotPositiveException(Localizable specific,
+                                Number value) {
+        super(specific, value, 0, true);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java b/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java
new file mode 100644
index 0000000..4b96b1d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Exception to be thrown when the argument is negative.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NotStrictlyPositiveException extends NumberIsTooSmallException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -7824848630829852237L;
+
+    /**
+     * Construct the exception.
+     *
+     * @param value Argument.
+     */
+    public NotStrictlyPositiveException(Number value) {
+        super(value, 0, false);
+    }
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Specific context where the error occurred.
+     * @param value Argument.
+     */
+    public NotStrictlyPositiveException(Localizable specific,
+                                        Number value) {
+        super(specific, value, 0, false);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NullArgumentException.java b/src/main/java/org/apache/commons/math/exception/NullArgumentException.java
new file mode 100644
index 0000000..e06d25f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NullArgumentException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * All conditions checks that fail due to a {@code null} argument must throw
+ * this exception.
+ * This class is meant to signal a precondition violation ("null is an illegal
+ * argument") and so does not extend the standard {@code NullPointerException}.
+ * Proagation of {@code NullPointerException} from within Commons-Math is
+ * construed to be a bug.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NullArgumentException extends MathIllegalArgumentException {
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -6024911025449780478L;
+
+    /**
+     * Default constructor.
+     */
+    public NullArgumentException() {
+        super(LocalizedFormats.NULL_NOT_ALLOWED);
+    }
+    /**
+     * @param specific Message pattern providing the specific context of
+     * the error.
+     */
+    public NullArgumentException(Localizable specific) {
+        super(specific, LocalizedFormats.NULL_NOT_ALLOWED);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java b/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java
new file mode 100644
index 0000000..9e1559b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java
@@ -0,0 +1,89 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when a number is too large.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NumberIsTooLargeException extends MathIllegalNumberException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = 4330003017885151975L;
+
+    /**
+     * Higher bound.
+     */
+    private final Number max;
+    /**
+     * Whether the maximum is included in the allowed range.
+     */
+    private final boolean boundIsAllowed;
+
+    /**
+     * Construct the exception.
+     *
+     * @param wrong Value that is larger than the maximum.
+     * @param max maximum.
+     * @param boundIsAllowed if true the maximum is included in the allowed range.
+     */
+    public NumberIsTooLargeException(Number wrong,
+                                     Number max,
+                                     boolean boundIsAllowed) {
+        this(null, wrong, max, boundIsAllowed);
+    }
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Specific contexte pattern .
+     * @param wrong Value that is larger than the maximum.
+     * @param max maximum.
+     * @param boundIsAllowed if true the maximum is included in the allowed range.
+     */
+    public NumberIsTooLargeException(Localizable specific,
+                                     Number wrong,
+                                     Number max,
+                                     boolean boundIsAllowed) {
+        super(specific,
+              boundIsAllowed ?
+              LocalizedFormats.NUMBER_TOO_LARGE :
+              LocalizedFormats.NUMBER_TOO_LARGE_BOUND_EXCLUDED,
+              wrong, max);
+
+        this.max = max;
+        this.boundIsAllowed = boundIsAllowed;
+    }
+
+    /**
+     * @return {@code true} if the maximum is included in the allowed range.
+     **/
+    public boolean getBoundIsAllowed() {
+        return boundIsAllowed;
+    }
+
+    /**
+     * @return the maximum.
+     **/
+    public Number getMax() {
+        return max;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java b/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java
new file mode 100644
index 0000000..349ffd1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java
@@ -0,0 +1,90 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when a number is too small.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class NumberIsTooSmallException extends MathIllegalNumberException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -6100997100383932834L;
+
+    /**
+     * Higher bound.
+     */
+    private final Number min;
+    /**
+     * Whether the maximum is included in the allowed range.
+     */
+    private final boolean boundIsAllowed;
+
+    /**
+     * Construct the exception.
+     *
+     * @param wrong Value that is smaller than the minimum.
+     * @param min minimum.
+     * @param boundIsAllowed Whether {@code min} is included in the allowed range.
+     */
+    public NumberIsTooSmallException(Number wrong,
+                                     Number min,
+                                     boolean boundIsAllowed) {
+        this(null, wrong, min, boundIsAllowed);
+    }
+
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Specific contexte pattern .
+     * @param wrong Value that is smaller than the minimum.
+     * @param min minimum.
+     * @param boundIsAllowed Whether {@code min} is included in the allowed range.
+     */
+    public NumberIsTooSmallException(Localizable specific,
+                                     Number wrong,
+                                     Number min,
+                                     boolean boundIsAllowed) {
+        super(specific,
+              boundIsAllowed ?
+              LocalizedFormats.NUMBER_TOO_SMALL :
+              LocalizedFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED,
+              wrong, min);
+
+        this.min = min;
+        this.boundIsAllowed = boundIsAllowed;
+    }
+
+    /**
+     * @return {@code true} if the minimum is included in the allowed range.
+     **/
+    public boolean getBoundIsAllowed() {
+        return boundIsAllowed;
+    }
+
+    /**
+     * @return the minimum.
+     **/
+    public Number getMin() {
+        return min;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/OutOfRangeException.java b/src/main/java/org/apache/commons/math/exception/OutOfRangeException.java
new file mode 100644
index 0000000..268fcb5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/OutOfRangeException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when some argument is out of range.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class OutOfRangeException extends MathIllegalNumberException {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = 111601815794403609L;
+
+    /** Lower bound. */
+    private final Number lo;
+    /** Higher bound. */
+    private final Number hi;
+
+    /**
+     * Construct an exception from the mismatched dimensions.
+     *
+     * @param wrong Requested value.
+     * @param lo Lower bound.
+     * @param hi Higher bound.
+     */
+    public OutOfRangeException(Number wrong,
+                               Number lo,
+                               Number hi) {
+        super(LocalizedFormats.OUT_OF_RANGE_SIMPLE, wrong, lo, hi);
+        this.lo = lo;
+        this.hi = hi;
+    }
+    /**
+     * @return the lower bound.
+     */
+    public Number getLo() {
+        return lo;
+    }
+    /**
+     * @return the higher bound.
+     */
+    public Number getHi() {
+        return hi;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/ZeroException.java b/src/main/java/org/apache/commons/math/exception/ZeroException.java
new file mode 100644
index 0000000..bd14365
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/ZeroException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.exception;
+
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Exception to be thrown when zero is provided where it is not allowed.
+ *
+ * @since 2.2
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class ZeroException extends MathIllegalNumberException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1960874856936000015L;
+
+    /**
+     * Construct the exception.
+     */
+    public ZeroException() {
+        this(null);
+    }
+
+    /**
+     * Construct the exception with a specific context.
+     *
+     * @param specific Specific contexte pattern .
+     */
+    public ZeroException(Localizable specific) {
+        super(specific, LocalizedFormats.ZERO_NOT_ALLOWED, 0);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/package.html b/src/main/java/org/apache/commons/math/exception/package.html
new file mode 100644
index 0000000..301f866
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/package.html
@@ -0,0 +1,23 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 981404 $ $Date: 2010-08-02 10:10:39 +0200 (lun. 02 août 2010) $ -->
+    <body>
+     Specialized exceptions for algorithms errors. The exceptions can be localized
+     using simple java properties.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java b/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java
new file mode 100644
index 0000000..d91134c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java
@@ -0,0 +1,58 @@
+/*
+ * 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.exception.util;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Utility class for transforming the list of arguments passed to
+ * constructors of exceptions.
+ *
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class ArgUtils {
+    /**
+     * Private constructor
+     */
+    private ArgUtils() {
+    }
+
+    /**
+     * Transform a multidimensional array into a one-dimensional list.
+     *
+     * @param array Array (possibly multidimensional).
+     * @return a list of all the {@code Object} instances contained in
+     * {@code array}.
+     */
+    public static Object[] flatten(Object[] array) {
+        final List<Object> list = new ArrayList<Object>();
+        if (array != null) {
+            for (Object o : array) {
+                if (o instanceof Object[]) {
+                    for (Object oR : flatten((Object[]) o)) {
+                        list.add(oR);
+                    }
+                } else {
+                    list.add(o);
+                }
+            }
+        }
+        return list.toArray();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/util/DummyLocalizable.java b/src/main/java/org/apache/commons/math/exception/util/DummyLocalizable.java
new file mode 100644
index 0000000..449ae75
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/util/DummyLocalizable.java
@@ -0,0 +1,58 @@
+/*
+ * 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.exception.util;
+
+import java.util.Locale;
+
+/**
+ * Dummy implementation of the {@link Localizable} interface, without localization.
+ *
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+ */
+public class DummyLocalizable implements Localizable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 8843275624471387299L;
+
+    /** Source string. */
+    private final String source;
+
+    /** Simple constructor.
+     * @param source source text
+     */
+    public DummyLocalizable(final String source) {
+        this.source = source;
+    }
+
+    /** {@inheritDoc} */
+    public String getSourceString() {
+        return source;
+    }
+
+    /** {@inheritDoc} */
+    public String getLocalizedString(Locale locale) {
+        return source;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return source;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/exception/util/Localizable.java b/src/main/java/org/apache/commons/math/exception/util/Localizable.java
new file mode 100644
index 0000000..47efe91
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/util/Localizable.java
@@ -0,0 +1,43 @@
+/*
+ * 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.exception.util;
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * Interface for localizable strings.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.2
+ */
+public interface Localizable extends Serializable {
+
+    /**
+     * Get the source (non-localized) string.
+     * @return source string
+     */
+    String getSourceString();
+
+    /**
+     * Get the localized string.
+     * @param locale locale into which to get the string
+     * @return localized string or the source string if no localized version is available
+     */
+    String getLocalizedString(Locale locale);
+
+}
diff --git a/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java b/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java
new file mode 100644
index 0000000..5c417f3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/util/LocalizedFormats.java
@@ -0,0 +1,345 @@
+/*
+ * 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.exception.util;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Enumeration for localized messages formats used in exceptions messages.
+ * <p>
+ * The constants in this enumeration represent the available
+ * formats as localized strings. These formats are intended to be
+ * localized using simple properties files, using the constant
+ * name as the key and the property value as the message format.
+ * The source English format is provided in the constants themselves
+ * to serve both as a reminder for developers to understand the parameters
+ * needed by each format, as a basis for translators to create
+ * localized properties files, and as a default format if some
+ * translation is missing.
+ * </p>
+ * @since 2.2
+ * @version $Revision: 1073165 $ $Date: 2011-02-21 23:04:14 +0100 (lun. 21 févr. 2011) $
+ */
+public enum LocalizedFormats implements Localizable {
+
+    // CHECKSTYLE: stop MultipleVariableDeclarations
+    // CHECKSTYLE: stop JavadocVariable
+
+    ARGUMENT_OUTSIDE_DOMAIN("Argument {0} outside domain [{1} ; {2}]"),
+    ARRAY_SIZES_SHOULD_HAVE_DIFFERENCE_1("array sizes should have difference 1 ({0} != {1} + 1)"),
+    ARRAY_SUMS_TO_ZERO("array sums to zero"),
+    ASSYMETRIC_EIGEN_NOT_SUPPORTED("eigen decomposition of assymetric matrices not supported yet"),
+    AT_LEAST_ONE_COLUMN("matrix must have at least one column"),
+    AT_LEAST_ONE_ROW("matrix must have at least one row"),
+    BANDWIDTH_OUT_OF_INTERVAL("bandwidth must be in the interval [0,1], but got {0}"),
+    BINOMIAL_INVALID_PARAMETERS_ORDER("must have n >= k for binomial coefficient (n,k), got n = {0}, k = {1}"),
+    BINOMIAL_NEGATIVE_PARAMETER("must have n >= 0 for binomial coefficient (n,k), got n = {0}"),
+    CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be cleared"),
+    CANNOT_COMPUTE_0TH_ROOT_OF_UNITY("cannot compute 0-th root of unity, indefinite result"),
+    CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA("cannot compute beta density at 0 when alpha = {0,number}"),
+    CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA("cannot compute beta density at 1 when beta = %.3g"),
+    CANNOT_COMPUTE_NTH_ROOT_FOR_NEGATIVE_N("cannot compute nth root for null or negative n: {0}"),
+    CANNOT_CONVERT_OBJECT_TO_FRACTION("cannot convert given object to a fraction number: {0}"),
+    CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS("cannot discard a negative number of elements ({0})"),
+    CANNOT_FORMAT_INSTANCE_AS_3D_VECTOR("cannot format a {0} instance as a 3D vector"),
+    CANNOT_FORMAT_INSTANCE_AS_COMPLEX("cannot format a {0} instance as a complex number"),
+    CANNOT_FORMAT_INSTANCE_AS_REAL_VECTOR("cannot format a {0} instance as a real vector"),
+    CANNOT_FORMAT_OBJECT_TO_FRACTION("cannot format given object as a fraction number"),
+    CANNOT_INCREMENT_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be incremented"),
+    CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR("cannot normalize a zero norm vector"),
+    CANNOT_RETRIEVE_AT_NEGATIVE_INDEX("elements cannot be retrieved from a negative array index {0}"),
+    CANNOT_SET_AT_NEGATIVE_INDEX("cannot set an element at a negative index {0}"),
+    CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY("cannot substitute an element from an empty array"),
+    CANNOT_TRANSFORM_TO_DOUBLE("Conversion Exception in Transformation: {0}"),
+    CARDAN_ANGLES_SINGULARITY("Cardan angles singularity"),
+    CLASS_DOESNT_IMPLEMENT_COMPARABLE("class ({0}) does not implement Comparable"),
+    CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT("the closest orthogonal matrix has a negative determinant {0}"),
+    COLUMN_INDEX_OUT_OF_RANGE("column index {0} out of allowed range [{1}, {2}]"),
+    CONTINUED_FRACTION_INFINITY_DIVERGENCE("Continued fraction convergents diverged to +/- infinity for value {0}"),
+    CONTINUED_FRACTION_NAN_DIVERGENCE("Continued fraction diverged to NaN for value {0}"),
+    CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR("contraction criteria ({0}) smaller than the expansion factor ({1}).  This would lead to a never ending loop of expansion and contraction as a newly expanded internal storage array would immediately satisfy the criteria for contraction."),
+    CONTRACTION_CRITERIA_SMALLER_THAN_ONE("contraction criteria smaller than one ({0}).  This would lead to a never ending loop of expansion and contraction as an internal storage array length equal to the number of elements would satisfy the contraction criteria."),
+    CONVERGENCE_FAILED("convergence failed"),
+    CUMULATIVE_PROBABILITY_RETURNED_NAN("Cumulative probability function returned NaN for argument {0} p = {1}"),
+    DIFFERENT_ROWS_LENGTHS("some rows have length {0} while others have length {1}"),
+    DIGEST_NOT_INITIALIZED("digest not initialized"),
+    DIMENSIONS_MISMATCH_2x2("dimensions mismatch: got {0}x{1} but expected {2}x{3}"),
+    DIMENSIONS_MISMATCH_SIMPLE("dimensions mismatch {0} != {1}"), /* keep */
+    DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN("Discrete cumulative probability function returned NaN for argument {0}"),
+    DISTRIBUTION_NOT_LOADED("distribution not loaded"),
+    DUPLICATED_ABSCISSA("Abscissa {0} is duplicated at both indices {1} and {2}"),
+    EMPTY_CLUSTER_IN_K_MEANS("empty cluster in k-means"),
+    EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY("empty polynomials coefficients array"), /* keep */
+    EMPTY_SELECTED_COLUMN_INDEX_ARRAY("empty selected column index array"),
+    EMPTY_SELECTED_ROW_INDEX_ARRAY("empty selected row index array"),
+    EMPTY_STRING_FOR_IMAGINARY_CHARACTER("empty string for imaginary character"),
+    ENDPOINTS_NOT_AN_INTERVAL("endpoints do not specify an interval: [{0}, {1}]"),
+    EQUAL_VERTICES_IN_SIMPLEX("equal vertices {0} and {1} in simplex configuration"),
+    EULER_ANGLES_SINGULARITY("Euler angles singularity"),
+    EVALUATION_FAILED("evaluation failed for argument = {0}"),
+    EXPANSION_FACTOR_SMALLER_THAN_ONE("expansion factor smaller than one ({0})"),
+    FACTORIAL_NEGATIVE_PARAMETER("must have n >= 0 for n!, got n = {0}"),
+    FAILED_BRACKETING("number of iterations={0}, maximum iterations={1}, initial={2}, lower bound={3}, upper bound={4}, final a value={5}, final b value={6}, f(a)={7}, f(b)={8}"),
+    FAILED_FRACTION_CONVERSION("Unable to convert {0} to fraction after {1} iterations"),
+    FIRST_COLUMNS_NOT_INITIALIZED_YET("first {0} columns are not initialized yet"),
+    FIRST_ELEMENT_NOT_ZERO("first element is not 0: {0}"),
+    FIRST_ROWS_NOT_INITIALIZED_YET("first {0} rows are not initialized yet"),
+    FRACTION_CONVERSION_OVERFLOW("Overflow trying to convert {0} to fraction ({1}/{2})"),
+    FUNCTION_NOT_DIFFERENTIABLE("function is not differentiable"),
+    FUNCTION_NOT_POLYNOMIAL("function is not polynomial"),
+    GCD_OVERFLOW_32_BITS("overflow: gcd({0}, {1}) is 2^31"),
+    GCD_OVERFLOW_64_BITS("overflow: gcd({0}, {1}) is 2^63"),
+    HOLE_BETWEEN_MODELS_TIME_RANGES("{0} wide hole between models time ranges"),
+    IDENTICAL_ABSCISSAS_DIVISION_BY_ZERO("identical abscissas x[{0}] == x[{1}] == {2} cause division by zero"),
+    INDEX_LARGER_THAN_MAX("the index specified: {0} is larger than the current maximal index {1}"),
+    INDEX_NOT_POSITIVE("index ({0}) is not positive"),
+    INDEX_OUT_OF_RANGE("index {0} out of allowed range [{1}, {2}]"),
+    INFINITE_ARRAY_ELEMENT("Array contains an infinite element, {0} at index {1}"),
+    INFINITE_VALUE_CONVERSION("cannot convert infinite value"),
+    INITIAL_CAPACITY_NOT_POSITIVE("initial capacity ({0}) is not positive"),
+    INITIAL_COLUMN_AFTER_FINAL_COLUMN("initial column {0} after final column {1}"),
+    INITIAL_ROW_AFTER_FINAL_ROW("initial row {0} after final row {1}"),
+    INPUT_DATA_FROM_UNSUPPORTED_DATASOURCE("input data comes from unsupported datasource: {0}, supported sources: {1}, {2}"),
+    INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES("instance of class {0} not comparable to existing values"),
+    INSUFFICIENT_DATA_FOR_T_STATISTIC("insufficient data for t statistic, needs at least 2, got {0}"),
+    INSUFFICIENT_DIMENSION("insufficient dimension {0}, must be at least {1}"),
+    INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE("sample contains {0} observed points, at least {1} are required"),
+    INSUFFICIENT_ROWS_AND_COLUMNS("insufficient data: only {0} rows and {1} columns."),
+    INTEGRATION_METHOD_NEEDS_AT_LEAST_ONE_PREVIOUS_POINT("{0} method needs at least one previous point"),
+    INTERNAL_ERROR("internal error, please fill a bug report at {0}"),
+    INVALID_BRACKETING_PARAMETERS("invalid bracketing parameters:  lower bound={0},  initial={1}, upper bound={2}"),
+    INVALID_INTERVAL_INITIAL_VALUE_PARAMETERS("invalid interval, initial value parameters:  lower={0}, initial={1}, upper={2}"),
+    INVALID_ITERATIONS_LIMITS("invalid iteration limits: min={0}, max={1}"),
+    INVALID_MAX_ITERATIONS("bad value for maximum iterations number: {0}"),
+    INVALID_REGRESSION_ARRAY("input data array length = {0} does not match the number of observations = {1} and the number of regressors = {2}"),
+    INVALID_ROUNDING_METHOD("invalid rounding method {0}, valid methods: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})"),
+    ITERATOR_EXHAUSTED("iterator exhausted"),
+    LCM_OVERFLOW_32_BITS("overflow: lcm({0}, {1}) is 2^31"),
+    LCM_OVERFLOW_64_BITS("overflow: lcm({0}, {1}) is 2^63"),
+    LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE("list of chromosomes bigger than maxPopulationSize"),
+    LOESS_EXPECTS_AT_LEAST_ONE_POINT("Loess expects at least 1 point"),
+    LOWER_BOUND_NOT_BELOW_UPPER_BOUND("lower bound ({0}) must be strictly less than upper bound ({1})"), /* keep */
+    LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT("lower endpoint ({0}) must be less than or equal to upper endpoint ({1})"),
+    MAP_MODIFIED_WHILE_ITERATING("map has been modified while iterating"),
+    MAX_EVALUATIONS_EXCEEDED("maximal number of evaluations ({0}) exceeded"),
+    MAX_ITERATIONS_EXCEEDED("maximal number of iterations ({0}) exceeded"),
+    MINIMAL_STEPSIZE_REACHED_DURING_INTEGRATION("minimal step size ({0,number,0.00E00}) reached, integration needs {1,number,0.00E00}"),
+    MISMATCHED_LOESS_ABSCISSA_ORDINATE_ARRAYS("Loess expects the abscissa and ordinate arrays to be of the same size, but got {0} abscissae and {1} ordinatae"),
+    NAN_ELEMENT_AT_INDEX("element {0} is NaN"),
+    NAN_VALUE_CONVERSION("cannot convert NaN value"),
+    NEGATIVE_BRIGHTNESS_EXPONENT("brightness exponent should be positive or null, but got {0}"),
+    NEGATIVE_COMPLEX_MODULE("negative complex module {0}"),
+    NEGATIVE_ELEMENT_AT_2D_INDEX("element ({0}, {1}) is negative: {2}"),
+    NEGATIVE_ELEMENT_AT_INDEX("element {0} is negative: {1}"),
+    NEGATIVE_NUMBER_OF_SUCCESSES("number of successes must be non-negative ({0})"),
+    NEGATIVE_NUMBER_OF_TRIALS("number of trials must be non-negative ({0})"),
+    NEGATIVE_ROBUSTNESS_ITERATIONS("the number of robustness iterations must be non-negative, but got {0}"),
+    START_POSITION("start position ({0})"), /* keep */
+    NON_CONVERGENT_CONTINUED_FRACTION("Continued fraction convergents failed to converge for value {0}"),
+    NON_POSITIVE_MICROSPHERE_ELEMENTS("number of microsphere elements must be positive, but got {0}"),
+    NON_POSITIVE_POLYNOMIAL_DEGREE("polynomial degree must be positive: degree={0}"),
+    NON_REAL_FINITE_ABSCISSA("all abscissae must be finite real numbers, but {0}-th is {1}"),
+    NON_REAL_FINITE_ORDINATE("all ordinatae must be finite real numbers, but {0}-th is {1}"),
+    NON_REAL_FINITE_WEIGHT("all weights must be finite real numbers, but {0}-th is {1}"),
+    NON_SQUARE_MATRIX("a {0}x{1} matrix was provided instead of a square matrix"),
+    NORMALIZE_INFINITE("Cannot normalize to an infinite value"),
+    NORMALIZE_NAN("Cannot normalize to NaN"),
+    NOT_ADDITION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not addition compatible"),
+    NOT_DECREASING_NUMBER_OF_POINTS("points {0} and {1} are not decreasing ({2} < {3})"),
+    NOT_DECREASING_SEQUENCE("points {3} and {2} are not decreasing ({1} < {0})"), /* keep */
+    NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS("not enough data ({0} rows) for this many predictors ({1} predictors)"),
+    NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION("spline partition must have at least {0} points, got {1}"),
+    NOT_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not increasing ({2} > {3})"),
+    NOT_INCREASING_SEQUENCE("points {3} and {2} are not increasing ({1} > {0})"), /* keep */
+    NOT_MULTIPLICATION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not multiplication compatible"),
+    NOT_OVERRIDEN("method not overriden"),
+    NOT_POSITIVE_ALPHA("alpha must be positive ({0})"),
+    NOT_POSITIVE_BETA("beta must be positive ({0})"),
+    NOT_POSITIVE_COLUMNDIMENSION("invalid column dimension: {0} (must be positive)"),
+    NOT_POSITIVE_DEFINITE_MATRIX("not positive definite matrix"),
+    NOT_POSITIVE_DEGREES_OF_FREEDOM("degrees of freedom must be positive ({0})"),
+    NOT_POSITIVE_ELEMENT_AT_INDEX("element {0} is not positive: {1}"),
+    NOT_POSITIVE_EXPONENT("invalid exponent {0} (must be positive)"),
+    NOT_POSITIVE_LENGTH("length must be positive ({0})"),
+    LENGTH("length ({0})"), /* keep */
+    NOT_POSITIVE_MEAN("mean must be positive ({0})"),
+    MEAN("mean ({0})"), /* keep */
+    NOT_POSITIVE_NUMBER_OF_SAMPLES("number of sample is not positive: {0}"),
+    NUMBER_OF_SAMPLES("number of samples ({0})"), /* keep */
+    NOT_POSITIVE_PERMUTATION("permutation k ({0}) must be positive"),
+    PERMUTATION_SIZE("permutation size ({0}"), /* keep */
+    NOT_POSITIVE_POISSON_MEAN("the Poisson mean must be positive ({0})"),
+    NOT_POSITIVE_POPULATION_SIZE("population size must be positive ({0})"),
+    NOT_POSITIVE_ROW_DIMENSION("invalid row dimension: {0} (must be positive)"),
+    NOT_POSITIVE_SAMPLE_SIZE("sample size must be positive ({0})"),
+    NOT_POSITIVE_SCALE("scale must be positive ({0})"),
+    NOT_POSITIVE_SHAPE("shape must be positive ({0})"),
+    NOT_POSITIVE_STANDARD_DEVIATION("standard deviation must be positive ({0})"),
+    STANDARD_DEVIATION("standard deviation ({0})"), /* keep */
+    NOT_POSITIVE_UPPER_BOUND("upper bound must be positive ({0})"),
+    NOT_POSITIVE_WINDOW_SIZE("window size must be positive ({0})"),
+    NOT_POWER_OF_TWO("{0} is not a power of 2"),
+    NOT_POWER_OF_TWO_CONSIDER_PADDING("{0} is not a power of 2, consider padding for fix"),
+    NOT_POWER_OF_TWO_PLUS_ONE("{0} is not a power of 2 plus one"),
+    NOT_STRICTLY_DECREASING_NUMBER_OF_POINTS("points {0} and {1} are not strictly decreasing ({2} <= {3})"),
+    NOT_STRICTLY_DECREASING_SEQUENCE("points {3} and {2} are not strictly decreasing ({1} <= {0})"), /* keep */
+    NOT_STRICTLY_INCREASING_KNOT_VALUES("knot values must be strictly increasing"),
+    NOT_STRICTLY_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not strictly increasing ({2} >= {3})"),
+    NOT_STRICTLY_INCREASING_SEQUENCE("points {3} and {2} are not strictly increasing ({1} >= {0})"), /* keep */
+    NOT_SUBTRACTION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not subtraction compatible"),
+    NOT_SYMMETRIC_MATRIX("not symmetric matrix"),
+    NO_BIN_SELECTED("no bin selected"),
+    NO_CONVERGENCE_WITH_ANY_START_POINT("none of the {0} start points lead to convergence"),
+    NO_DATA("no data"), /* keep */
+    NO_DEGREES_OF_FREEDOM("no degrees of freedom ({0} measurements, {1} parameters)"),
+    NO_DENSITY_FOR_THIS_DISTRIBUTION("This distribution does not have a density function implemented"),
+    NO_FEASIBLE_SOLUTION("no feasible solution"),
+    NO_OPTIMUM_COMPUTED_YET("no optimum computed yet"),
+    NO_RESULT_AVAILABLE("no result available"),
+    NO_SUCH_MATRIX_ENTRY("no entry at indices ({0}, {1}) in a {2}x{3} matrix"),
+    NULL_NOT_ALLOWED("null is not allowed"), /* keep */
+    COVARIANCE_MATRIX("covariance matrix"), /* keep */
+    DENOMINATOR("denominator"), /* keep */
+    DENOMINATOR_FORMAT("denominator format"), /* keep */
+    FRACTION("fraction"), /* keep */
+    FUNCTION("function"), /* keep */
+    IMAGINARY_FORMAT("imaginary format"), /* keep */
+    INPUT_ARRAY("input array"), /* keep */
+    NUMERATOR("numerator"), /* keep */
+    NUMERATOR_FORMAT("numerator format"), /* keep */
+    OBJECT_TRANSFORMATION("conversion exception in transformation"), /* keep */
+    REAL_FORMAT("real format"), /* keep */
+    WHOLE_FORMAT("whole format"), /* keep */
+    NUMBER_TOO_LARGE("{0} is larger than the maximum ({1})"), /* keep */
+    NUMBER_TOO_SMALL("{0} is smaller than the minimum ({1})"), /* keep */
+    NUMBER_TOO_LARGE_BOUND_EXCLUDED("{0} is larger than, or equal to, the maximum ({1})"), /* keep */
+    NUMBER_TOO_SMALL_BOUND_EXCLUDED("{0} is smaller than, or equal to, the minimum ({1})"), /* keep */
+    NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE("number of successes ({0}) must be less than or equal to population size ({1})"),
+    NUMERATOR_OVERFLOW_AFTER_MULTIPLY("overflow, numerator too large after multiply: {0}"),
+    N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED("{0} points Legendre-Gauss integrator not supported, number of points must be in the {1}-{2} range"),
+    OBSERVED_COUNTS_ALL_ZERO("observed counts are all 0 in observed array {0}"),
+    OBSERVED_COUNTS_BOTTH_ZERO_FOR_ENTRY("observed counts are both zero for entry {0}"),
+    OUT_OF_BOUNDS_QUANTILE_VALUE("out of bounds quantile value: {0}, must be in (0, 100]"),
+    OUT_OF_BOUND_SIGNIFICANCE_LEVEL("out of bounds significance level {0}, must be between {1} and {2}"),
+    OUT_OF_ORDER_ABSCISSA_ARRAY("the abscissae array must be sorted in a strictly increasing order, but the {0}-th element is {1} whereas {2}-th is {3}"),
+    OUT_OF_RANGE_ROOT_OF_UNITY_INDEX("out of range root of unity index {0} (must be in [{1};{2}])"),
+    OUT_OF_RANGE_SIMPLE("{0} out of [{1}, {2}] range"), /* keep */
+    OVERFLOW_IN_FRACTION("overflow in fraction {0}/{1}, cannot negate"),
+    OVERFLOW_IN_ADDITION("overflow in addition: {0} + {1}"),
+    OVERFLOW_IN_SUBTRACTION("overflow in subtraction: {0} - {1}"),
+    PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD("cannot access {0} method in percentile implementation {1}"),
+    PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD("percentile implementation {0} does not support {1}"),
+    PERMUTATION_EXCEEDS_N("permutation size ({0}) exceeds permuation domain ({1})"), /* keep */
+    POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS("number of polynomial interpolants must match the number of segments ({0} != {1} - 1)"),
+    POPULATION_LIMIT_NOT_POSITIVE("population limit has to be positive"),
+    POSITION_SIZE_MISMATCH_INPUT_ARRAY("position {0} and size {1} don't fit to the size of the input array {2}"),
+    POWER_NEGATIVE_PARAMETERS("cannot raise an integral value to a negative power ({0}^{1})"),
+    PROPAGATION_DIRECTION_MISMATCH("propagation direction mismatch"),
+    RANDOMKEY_MUTATION_WRONG_CLASS("RandomKeyMutation works only with RandomKeys, not {0}"),
+    ROOTS_OF_UNITY_NOT_COMPUTED_YET("roots of unity have not been computed yet"),
+    ROTATION_MATRIX_DIMENSIONS("a {0}x{1} matrix cannot be a rotation matrix"),
+    ROW_INDEX_OUT_OF_RANGE("row index {0} out of allowed range [{1}, {2}]"),
+    SAME_SIGN_AT_ENDPOINTS("function values at endpoints do not have different signs, endpoints: [{0}, {1}], values: [{2}, {3}]"),
+    SAMPLE_SIZE_EXCEEDS_COLLECTION_SIZE("sample size ({0}) exceeds collection size ({1})"), /* keep */
+    SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE("sample size ({0}) must be less than or equal to population size ({1})"),
+    SIMPLEX_NEED_ONE_POINT("simplex must contain at least one point"),
+    SIMPLE_MESSAGE("{0}"),
+    SINGULAR_MATRIX("matrix is singular"),
+    SUBARRAY_ENDS_AFTER_ARRAY_END("subarray ends after array end"),
+    TOO_LARGE_CUTOFF_SINGULAR_VALUE("cutoff singular value is {0}, should be at most {1}"),
+    TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY("cannot discard {0} elements from a {1} elements array"),
+    TOO_SMALL_BANDWIDTH("the bandwidth must be large enough to accomodate at least 2 points. There are {0}  data points, and bandwidth must be at least {1}  but it is only {2}"),
+    TOO_SMALL_COST_RELATIVE_TOLERANCE("cost relative tolerance is too small ({0}), no further reduction in the sum of squares is possible"),
+    TOO_SMALL_INTEGRATION_INTERVAL("too small integration interval: length = {0}"),
+    TOO_SMALL_ORTHOGONALITY_TOLERANCE("orthogonality tolerance is too small ({0}), solution is orthogonal to the jacobian"),
+    TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE("parameters relative tolerance is too small ({0}), no further improvement in the approximate solution is possible"),
+    TWO_OR_MORE_CATEGORIES_REQUIRED("two or more categories required, got {0}"),
+    TWO_OR_MORE_VALUES_IN_CATEGORY_REQUIRED("two or more values required in each category, one has {0}"),
+    UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH("unable to bracket optimum in line search"),
+    UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM("unable to compute covariances: singular problem"),
+    UNABLE_TO_FIRST_GUESS_HARMONIC_COEFFICIENTS("unable to first guess the harmonic coefficients"),
+    UNABLE_TO_ORTHOGONOLIZE_MATRIX("unable to orthogonalize matrix in {0} iterations"),
+    UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN("unable to perform Q.R decomposition on the {0}x{1} jacobian matrix"),
+    UNABLE_TO_SOLVE_SINGULAR_PROBLEM("unable to solve: singular problem"),
+    UNBOUNDED_SOLUTION("unbounded solution"),
+    UNKNOWN_MODE("unknown mode {0}, known modes: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) and {11} ({12})"),
+    UNPARSEABLE_3D_VECTOR("unparseable 3D vector: \"{0}\""),
+    UNPARSEABLE_COMPLEX_NUMBER("unparseable complex number: \"{0}\""),
+    UNPARSEABLE_FRACTION_NUMBER("unparseable fraction number: \"{0}\""),
+    UNPARSEABLE_REAL_VECTOR("unparseable real vector: \"{0}\""),
+    UNSUPPORTED_EXPANSION_MODE("unsupported expansion mode {0}, supported modes are {1} ({2}) and {3} ({4})"),
+    UNSUPPORTED_OPERATION("unsupported operation"), /* keep */
+    USER_EXCEPTION("exception generated in user code"), /* keep */
+    URL_CONTAINS_NO_DATA("URL {0} contains no data"),
+    VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC("{0} values have been added before statistic is configured"),
+    VECTOR_LENGTH_MISMATCH("vector length mismatch: got {0} but expected {1}"),
+    VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT("vector must have at least one element"),
+    WEIGHT_AT_LEAST_ONE_NON_ZERO("weigth array must contain at least one non-zero value"),
+    WRONG_BLOCK_LENGTH("wrong array shape (block length = {0}, expected {1})"),
+    WRONG_NUMBER_OF_POINTS("{0} points are required, got only {1}"),
+    NUMBER_OF_POINTS("number of points ({0})"), /* keep */
+    ZERO_DENOMINATOR("denominator must be different from 0"),
+    ZERO_DENOMINATOR_IN_FRACTION("zero denominator in fraction {0}/{1}"),
+    ZERO_FRACTION_TO_DIVIDE_BY("the fraction to divide by must not be zero: {0}/{1}"),
+    ZERO_NORM("zero norm"),
+    ZERO_NORM_FOR_ROTATION_AXIS("zero norm for rotation axis"),
+    ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR("zero norm for rotation defining vector"),
+    ZERO_NOT_ALLOWED("zero not allowed here");
+
+    // CHECKSTYLE: resume JavadocVariable
+    // CHECKSTYLE: resume MultipleVariableDeclarations
+
+
+    /** Source English format. */
+    private final String sourceFormat;
+
+    /** Simple constructor.
+     * @param sourceFormat source English format to use when no
+     * localized version is available
+     */
+    private LocalizedFormats(final String sourceFormat) {
+        this.sourceFormat = sourceFormat;
+    }
+
+    /** {@inheritDoc} */
+    public String getSourceString() {
+        return sourceFormat;
+    }
+
+    /** {@inheritDoc} */
+    public String getLocalizedString(final Locale locale) {
+        try {
+            ResourceBundle bundle =
+                    ResourceBundle.getBundle("META-INF/localization/LocalizedFormats", locale);
+            if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) {
+                // the value of the resource is the translated format
+                return bundle.getString(toString());
+            }
+
+        } catch (MissingResourceException mre) {
+            // do nothing here
+        }
+
+        // either the locale is not supported or the resource is unknown
+        // don't translate and fall back to using the source format
+        return sourceFormat;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/exception/util/MessageFactory.java b/src/main/java/org/apache/commons/math/exception/util/MessageFactory.java
new file mode 100644
index 0000000..0e8cf14
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/util/MessageFactory.java
@@ -0,0 +1,78 @@
+/*
+ * 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.exception.util;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+
+/**
+ * Class for constructing localized messages.
+ *
+ * @since 2.2
+ * @version $Revision$ $Date$
+ */
+public class MessageFactory {
+    /**
+     * Class contains only static methods.
+     */
+    private MessageFactory() {}
+
+    /**
+     * Builds a message string by from a pattern and its arguments.
+     *
+     * @param locale Locale in which the message should be translated.
+     * @param pattern Format specifier.
+     * @param arguments Format arguments.
+     * @return a localized message string.
+     */
+    public static String buildMessage(Locale locale,
+                                      Localizable pattern,
+                                      Object ... arguments) {
+        return buildMessage(locale, null, pattern, arguments);
+    }
+
+    /**
+     * Builds a message string by from two patterns (specific and general) and
+     * an argument list.
+     *
+     * @param locale Locale in which the message should be translated.
+     * @param specific Format specifier (may be null).
+     * @param general Format specifier (may be null).
+     * @param arguments Format arguments. They will be substituted in
+     * <em>both</em> the {@code general} and {@code specific} format specifiers.
+     * @return a localized message string.
+     */
+    public static String buildMessage(Locale locale,
+                                      Localizable specific,
+                                      Localizable general,
+                                      Object ... arguments) {
+        final StringBuilder sb = new StringBuilder();
+        if (general != null) {
+            final MessageFormat fmt = new MessageFormat(general.getLocalizedString(locale), locale);
+            sb.append(fmt.format(arguments));
+        }
+        if (specific != null) {
+            if (general != null) {
+                sb.append(": ");
+            }
+            final MessageFormat fmt = new MessageFormat(specific.getLocalizedString(locale), locale);
+            sb.append(fmt.format(arguments));
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/exception/util/package.html b/src/main/java/org/apache/commons/math/exception/util/package.html
new file mode 100644
index 0000000..456a88a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/exception/util/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 1054315 $ $Date: 2011-01-02 00:22:24 +0100 (dim. 02 janv. 2011) $ -->
+  <body>
+    Classes supporting exception localization.
+  </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/fraction/AbstractFormat.java b/src/main/java/org/apache/commons/math/fraction/AbstractFormat.java
new file mode 100644
index 0000000..c409702
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/AbstractFormat.java
@@ -0,0 +1,210 @@
+/*
+ * 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.fraction;
+
+import java.io.Serializable;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Common part shared by both {@link FractionFormat} and {@link BigFractionFormat}.
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public abstract class AbstractFormat extends NumberFormat implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -6981118387974191891L;
+
+    /** The format used for the denominator. */
+    protected NumberFormat denominatorFormat;
+
+    /** The format used for the numerator. */
+    protected NumberFormat numeratorFormat;
+
+    /**
+     * Create an improper formatting instance with the default number format
+     * for the numerator and denominator.
+     */
+    protected AbstractFormat() {
+        this(getDefaultNumberFormat());
+    }
+
+    /**
+     * Create an improper formatting instance with a custom number format for
+     * both the numerator and denominator.
+     * @param format the custom format for both the numerator and denominator.
+     */
+    protected AbstractFormat(final NumberFormat format) {
+        this(format, (NumberFormat) format.clone());
+    }
+
+    /**
+     * Create an improper formatting instance with a custom number format for
+     * the numerator and a custom number format for the denominator.
+     * @param numeratorFormat the custom format for the numerator.
+     * @param denominatorFormat the custom format for the denominator.
+     */
+    protected AbstractFormat(final NumberFormat numeratorFormat,
+                             final NumberFormat denominatorFormat) {
+        this.numeratorFormat   = numeratorFormat;
+        this.denominatorFormat = denominatorFormat;
+    }
+
+    /**
+     * Create a default number format.  The default number format is based on
+     * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
+     * customizing is the maximum number of BigFraction digits, which is set to 0.
+     * @return the default number format.
+     */
+    protected static NumberFormat getDefaultNumberFormat() {
+        return getDefaultNumberFormat(Locale.getDefault());
+    }
+
+    /**
+     * Create a default number format.  The default number format is based on
+     * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
+     * customizing is the maximum number of BigFraction digits, which is set to 0.
+     * @param locale the specific locale used by the format.
+     * @return the default number format specific to the given locale.
+     */
+    protected static NumberFormat getDefaultNumberFormat(final Locale locale) {
+        final NumberFormat nf = NumberFormat.getNumberInstance(locale);
+        nf.setMaximumFractionDigits(0);
+        nf.setParseIntegerOnly(true);
+        return nf;
+    }
+
+    /**
+     * Access the denominator format.
+     * @return the denominator format.
+     */
+    public NumberFormat getDenominatorFormat() {
+        return denominatorFormat;
+    }
+
+    /**
+     * Access the numerator format.
+     * @return the numerator format.
+     */
+    public NumberFormat getNumeratorFormat() {
+        return numeratorFormat;
+    }
+
+    /**
+     * Modify the denominator format.
+     * @param format the new denominator format value.
+     * @throws NullArgumentException if {@code format} is {@code null}.
+     */
+    public void setDenominatorFormat(final NumberFormat format) {
+        if (format == null) {
+            throw new NullArgumentException(LocalizedFormats.DENOMINATOR_FORMAT);
+        }
+        this.denominatorFormat = format;
+    }
+
+    /**
+     * Modify the numerator format.
+     * @param format the new numerator format value.
+     * @throws NullArgumentException if {@code format} is {@code null}.
+     */
+    public void setNumeratorFormat(final NumberFormat format) {
+        if (format == null) {
+            throw new NullArgumentException(LocalizedFormats.NUMERATOR_FORMAT);
+        }
+        this.numeratorFormat = format;
+    }
+
+    /**
+     * Parses <code>source</code> until a non-whitespace character is found.
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.  On output, <code>pos</code>
+     *        holds the index of the next non-whitespace character.
+     */
+    protected static void parseAndIgnoreWhitespace(final String source,
+                                                   final ParsePosition pos) {
+        parseNextCharacter(source, pos);
+        pos.setIndex(pos.getIndex() - 1);
+    }
+
+    /**
+     * Parses <code>source</code> until a non-whitespace character is found.
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the first non-whitespace character.
+     */
+    protected static char parseNextCharacter(final String source,
+                                             final ParsePosition pos) {
+         int index = pos.getIndex();
+         final int n = source.length();
+         char ret = 0;
+
+         if (index < n) {
+             char c;
+             do {
+                 c = source.charAt(index++);
+             } while (Character.isWhitespace(c) && index < n);
+             pos.setIndex(index);
+
+             if (index < n) {
+                 ret = c;
+             }
+         }
+
+         return ret;
+    }
+
+    /**
+     * Formats a double value as a fraction and appends the result to a StringBuffer.
+     *
+     * @param value the double value to format
+     * @param buffer StringBuffer to append to
+     * @param position On input: an alignment field, if desired. On output: the
+     *            offsets of the alignment field
+     * @return a reference to the appended buffer
+     * @see #format(Object, StringBuffer, FieldPosition)
+     */
+    @Override
+    public StringBuffer format(final double value,
+                               final StringBuffer buffer, final FieldPosition position) {
+        return format(Double.valueOf(value), buffer, position);
+    }
+
+
+    /**
+     * Formats a long value as a fraction and appends the result to a StringBuffer.
+     *
+     * @param value the long value to format
+     * @param buffer StringBuffer to append to
+     * @param position On input: an alignment field, if desired. On output: the
+     *            offsets of the alignment field
+     * @return a reference to the appended buffer
+     * @see #format(Object, StringBuffer, FieldPosition)
+     */
+    @Override
+    public StringBuffer format(final long value,
+                               final StringBuffer buffer, final FieldPosition position) {
+        return format(Long.valueOf(value), buffer, position);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/BigFraction.java b/src/main/java/org/apache/commons/math/fraction/BigFraction.java
new file mode 100644
index 0000000..98fa676
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/BigFraction.java
@@ -0,0 +1,1129 @@
+/*
+ * 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.fraction;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Representation of a rational number without any overflow. This class is
+ * immutable.
+ *
+ * @version $Revision: 1073687 $ $Date: 2011-02-23 11:39:25 +0100 (mer. 23 févr. 2011) $
+ * @since 2.0
+ */
+public class BigFraction
+    extends Number
+    implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable {
+
+    /** A fraction representing "2 / 1". */
+    public static final BigFraction TWO = new BigFraction(2);
+
+    /** A fraction representing "1". */
+    public static final BigFraction ONE = new BigFraction(1);
+
+    /** A fraction representing "0". */
+    public static final BigFraction ZERO = new BigFraction(0);
+
+    /** A fraction representing "-1 / 1". */
+    public static final BigFraction MINUS_ONE = new BigFraction(-1);
+
+    /** A fraction representing "4/5". */
+    public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5);
+
+    /** A fraction representing "1/5". */
+    public static final BigFraction ONE_FIFTH = new BigFraction(1, 5);
+
+    /** A fraction representing "1/2". */
+    public static final BigFraction ONE_HALF = new BigFraction(1, 2);
+
+    /** A fraction representing "1/4". */
+    public static final BigFraction ONE_QUARTER = new BigFraction(1, 4);
+
+    /** A fraction representing "1/3". */
+    public static final BigFraction ONE_THIRD = new BigFraction(1, 3);
+
+    /** A fraction representing "3/5". */
+    public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5);
+
+    /** A fraction representing "3/4". */
+    public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4);
+
+    /** A fraction representing "2/5". */
+    public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5);
+
+    /** A fraction representing "2/4". */
+    public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4);
+
+    /** A fraction representing "2/3". */
+    public static final BigFraction TWO_THIRDS = new BigFraction(2, 3);
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -5630213147331578515L;
+
+    /** <code>BigInteger</code> representation of 100. */
+    private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100);
+
+    /** The numerator. */
+    private final BigInteger numerator;
+
+    /** The denominator. */
+    private final BigInteger denominator;
+
+    /**
+     * <p>
+     * Create a {@link BigFraction} equivalent to the passed <tt>BigInteger</tt>, ie
+     * "num / 1".
+     * </p>
+     *
+     * @param num
+     *            the numerator.
+     */
+    public BigFraction(final BigInteger num) {
+        this(num, BigInteger.ONE);
+    }
+
+    /**
+     * Create a {@link BigFraction} given the numerator and denominator as
+     * {@code BigInteger}. The {@link BigFraction} is reduced to lowest terms.
+     *
+     * @param num the numerator, must not be {@code null}.
+     * @param den the denominator, must not be {@code null}..
+     * @throws ArithmeticException if the denominator is zero.
+     */
+    public BigFraction(BigInteger num, BigInteger den) {
+        if (num == null) {
+            throw new NullPointerException(LocalizedFormats.NUMERATOR.getSourceString());
+        }
+        if (den == null) {
+            throw new NullPointerException(LocalizedFormats.DENOMINATOR.getSourceString());
+        }
+        if (BigInteger.ZERO.equals(den)) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
+        }
+        if (BigInteger.ZERO.equals(num)) {
+            numerator   = BigInteger.ZERO;
+            denominator = BigInteger.ONE;
+        } else {
+
+            // reduce numerator and denominator by greatest common denominator
+            final BigInteger gcd = num.gcd(den);
+            if (BigInteger.ONE.compareTo(gcd) < 0) {
+                num = num.divide(gcd);
+                den = den.divide(gcd);
+            }
+
+            // move sign to numerator
+            if (BigInteger.ZERO.compareTo(den) > 0) {
+                num = num.negate();
+                den = den.negate();
+            }
+
+            // store the values in the final fields
+            numerator   = num;
+            denominator = den;
+
+        }
+    }
+
+    /**
+     * Create a fraction given the double value.
+     * <p>
+     * This constructor behaves <em>differently</em> from
+     * {@link #BigFraction(double, double, int)}. It converts the
+     * double value exactly, considering its internal bits representation.
+     * This does work for all values except NaN and infinities and does
+     * not requires any loop or convergence threshold.
+     * </p>
+     * <p>
+     * Since this conversion is exact and since double numbers are sometimes
+     * approximated, the fraction created may seem strange in some cases. For example
+     * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create
+     * the fraction 1/3 but the fraction 6004799503160661 / 18014398509481984
+     * because the double number passed to the constructor is not exactly 1/3
+     * (this number cannot be stored exactly in IEEE754).
+     * </p>
+     * @see #BigFraction(double, double, int)
+     * @param value the double value to convert to a fraction.
+     * @exception IllegalArgumentException if value is NaN or infinite
+     */
+    public BigFraction(final double value) throws IllegalArgumentException {
+        if (Double.isNaN(value)) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NAN_VALUE_CONVERSION);
+        }
+        if (Double.isInfinite(value)) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.INFINITE_VALUE_CONVERSION);
+        }
+
+        // compute m and k such that value = m * 2^k
+        final long bits     = Double.doubleToLongBits(value);
+        final long sign     = bits & 0x8000000000000000L;
+        final long exponent = bits & 0x7ff0000000000000L;
+        long m              = bits & 0x000fffffffffffffL;
+        if (exponent != 0) {
+            // this was a normalized number, add the implicit most significant bit
+            m |= 0x0010000000000000L;
+        }
+        if (sign != 0) {
+            m = -m;
+        }
+        int k = ((int) (exponent >> 52)) - 1075;
+        while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) {
+            m = m >> 1;
+            ++k;
+        }
+
+        if (k < 0) {
+            numerator   = BigInteger.valueOf(m);
+            denominator = BigInteger.ZERO.flipBit(-k);
+        } else {
+            numerator   = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k));
+            denominator = BigInteger.ONE;
+        }
+
+    }
+
+    /**
+     * Create a fraction given the double value and maximum error allowed.
+     * <p>
+     * References:
+     * <ul>
+     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
+     * Continued Fraction</a> equations (11) and (22)-(26)</li>
+     * </ul>
+     * </p>
+     *
+     * @param value
+     *            the double value to convert to a fraction.
+     * @param epsilon
+     *            maximum error allowed. The resulting fraction is within
+     *            <code>epsilon</code> of <code>value</code>, in absolute terms.
+     * @param maxIterations
+     *            maximum number of convergents.
+     * @throws FractionConversionException
+     *             if the continued fraction failed to converge.
+     * @see #BigFraction(double)
+     */
+    public BigFraction(final double value, final double epsilon,
+                       final int maxIterations)
+        throws FractionConversionException {
+        this(value, epsilon, Integer.MAX_VALUE, maxIterations);
+    }
+
+    /**
+     * Create a fraction given the double value and either the maximum error
+     * allowed or the maximum number of denominator digits.
+     * <p>
+     *
+     * NOTE: This constructor is called with EITHER - a valid epsilon value and
+     * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator
+     * has no effect). OR - a valid maxDenominator value and the epsilon value
+     * set to zero (that way epsilon only has effect if there is an exact match
+     * before the maxDenominator value is reached).
+     * </p>
+     * <p>
+     *
+     * It has been done this way so that the same code can be (re)used for both
+     * scenarios. However this could be confusing to users if it were part of
+     * the public API and this constructor should therefore remain PRIVATE.
+     * </p>
+     *
+     * See JIRA issue ticket MATH-181 for more details:
+     *
+     * https://issues.apache.org/jira/browse/MATH-181
+     *
+     * @param value
+     *            the double value to convert to a fraction.
+     * @param epsilon
+     *            maximum error allowed. The resulting fraction is within
+     *            <code>epsilon</code> of <code>value</code>, in absolute terms.
+     * @param maxDenominator
+     *            maximum denominator value allowed.
+     * @param maxIterations
+     *            maximum number of convergents.
+     * @throws FractionConversionException
+     *             if the continued fraction failed to converge.
+     */
+    private BigFraction(final double value, final double epsilon,
+                        final int maxDenominator, int maxIterations)
+        throws FractionConversionException {
+        long overflow = Integer.MAX_VALUE;
+        double r0 = value;
+        long a0 = (long) FastMath.floor(r0);
+        if (a0 > overflow) {
+            throw new FractionConversionException(value, a0, 1l);
+        }
+
+        // check for (almost) integer arguments, which should not go
+        // to iterations.
+        if (FastMath.abs(a0 - value) < epsilon) {
+            numerator = BigInteger.valueOf(a0);
+            denominator = BigInteger.ONE;
+            return;
+        }
+
+        long p0 = 1;
+        long q0 = 0;
+        long p1 = a0;
+        long q1 = 1;
+
+        long p2 = 0;
+        long q2 = 1;
+
+        int n = 0;
+        boolean stop = false;
+        do {
+            ++n;
+            final double r1 = 1.0 / (r0 - a0);
+            final long a1 = (long) FastMath.floor(r1);
+            p2 = (a1 * p1) + p0;
+            q2 = (a1 * q1) + q0;
+            if ((p2 > overflow) || (q2 > overflow)) {
+                throw new FractionConversionException(value, p2, q2);
+            }
+
+            final double convergent = (double) p2 / (double) q2;
+            if ((n < maxIterations) &&
+                (FastMath.abs(convergent - value) > epsilon) &&
+                (q2 < maxDenominator)) {
+                p0 = p1;
+                p1 = p2;
+                q0 = q1;
+                q1 = q2;
+                a0 = a1;
+                r0 = r1;
+            } else {
+                stop = true;
+            }
+        } while (!stop);
+
+        if (n >= maxIterations) {
+            throw new FractionConversionException(value, maxIterations);
+        }
+
+        if (q2 < maxDenominator) {
+            numerator   = BigInteger.valueOf(p2);
+            denominator = BigInteger.valueOf(q2);
+        } else {
+            numerator   = BigInteger.valueOf(p1);
+            denominator = BigInteger.valueOf(q1);
+        }
+    }
+
+    /**
+     * Create a fraction given the double value and maximum denominator.
+     * <p>
+     * References:
+     * <ul>
+     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
+     * Continued Fraction</a> equations (11) and (22)-(26)</li>
+     * </ul>
+     * </p>
+     *
+     * @param value
+     *            the double value to convert to a fraction.
+     * @param maxDenominator
+     *            The maximum allowed value for denominator.
+     * @throws FractionConversionException
+     *             if the continued fraction failed to converge.
+     */
+    public BigFraction(final double value, final int maxDenominator)
+        throws FractionConversionException {
+        this(value, 0, maxDenominator, 100);
+    }
+
+    /**
+     * <p>
+     * Create a {@link BigFraction} equivalent to the passed <tt>int</tt>, ie
+     * "num / 1".
+     * </p>
+     *
+     * @param num
+     *            the numerator.
+     */
+    public BigFraction(final int num) {
+        this(BigInteger.valueOf(num), BigInteger.ONE);
+    }
+
+    /**
+     * <p>
+     * Create a {@link BigFraction} given the numerator and denominator as simple
+     * <tt>int</tt>. The {@link BigFraction} is reduced to lowest terms.
+     * </p>
+     *
+     * @param num
+     *            the numerator.
+     * @param den
+     *            the denominator.
+     */
+    public BigFraction(final int num, final int den) {
+        this(BigInteger.valueOf(num), BigInteger.valueOf(den));
+    }
+
+    /**
+     * <p>
+     * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1".
+     * </p>
+     *
+     * @param num
+     *            the numerator.
+     */
+    public BigFraction(final long num) {
+        this(BigInteger.valueOf(num), BigInteger.ONE);
+    }
+
+    /**
+     * <p>
+     * Create a {@link BigFraction} given the numerator and denominator as simple
+     * <tt>long</tt>. The {@link BigFraction} is reduced to lowest terms.
+     * </p>
+     *
+     * @param num
+     *            the numerator.
+     * @param den
+     *            the denominator.
+     */
+    public BigFraction(final long num, final long den) {
+        this(BigInteger.valueOf(num), BigInteger.valueOf(den));
+    }
+
+    /**
+     * <p>
+     * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction
+     * Y/Z.
+     * </p>
+     *
+     * <p>
+     * Any negative signs are resolved to be on the numerator.
+     * </p>
+     *
+     * @param numerator
+     *            the numerator, for example the three in 'three sevenths'.
+     * @param denominator
+     *            the denominator, for example the seven in 'three sevenths'.
+     * @return a new fraction instance, with the numerator and denominator
+     *         reduced.
+     * @throws ArithmeticException
+     *             if the denominator is <code>zero</code>.
+     */
+    public static BigFraction getReducedFraction(final int numerator,
+                                                 final int denominator) {
+        if (numerator == 0) {
+            return ZERO; // normalize zero.
+        }
+
+        return new BigFraction(numerator, denominator);
+    }
+
+    /**
+     * <p>
+     * Returns the absolute value of this {@link BigFraction}.
+     * </p>
+     *
+     * @return the absolute value as a {@link BigFraction}.
+     */
+    public BigFraction abs() {
+        return (BigInteger.ZERO.compareTo(numerator) <= 0) ? this : negate();
+    }
+
+    /**
+     * <p>
+     * Adds the value of this fraction to the passed {@link BigInteger},
+     * returning the result in reduced form.
+     * </p>
+     *
+     * @param bg
+     *            the {@link BigInteger} to add, must'nt be <code>null</code>.
+     * @return a <code>BigFraction</code> instance with the resulting values.
+     * @throws NullPointerException
+     *             if the {@link BigInteger} is <code>null</code>.
+     */
+    public BigFraction add(final BigInteger bg) {
+        return new BigFraction(numerator.add(denominator.multiply(bg)), denominator);
+    }
+
+    /**
+     * <p>
+     * Adds the value of this fraction to the passed <tt>integer</tt>, returning
+     * the result in reduced form.
+     * </p>
+     *
+     * @param i
+     *            the <tt>integer</tt> to add.
+     * @return a <code>BigFraction</code> instance with the resulting values.
+     */
+    public BigFraction add(final int i) {
+        return add(BigInteger.valueOf(i));
+    }
+
+    /**
+     * <p>
+     * Adds the value of this fraction to the passed <tt>long</tt>, returning
+     * the result in reduced form.
+     * </p>
+     *
+     * @param l
+     *            the <tt>long</tt> to add.
+     * @return a <code>BigFraction</code> instance with the resulting values.
+     */
+    public BigFraction add(final long l) {
+        return add(BigInteger.valueOf(l));
+    }
+
+    /**
+     * <p>
+     * Adds the value of this fraction to another, returning the result in
+     * reduced form.
+     * </p>
+     *
+     * @param fraction
+     *            the {@link BigFraction} to add, must not be <code>null</code>.
+     * @return a {@link BigFraction} instance with the resulting values.
+     * @throws NullPointerException if the {@link BigFraction} is {@code null}.
+     */
+    public BigFraction add(final BigFraction fraction) {
+        if (fraction == null) {
+            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
+        }
+        if (ZERO.equals(fraction)) {
+            return this;
+        }
+
+        BigInteger num = null;
+        BigInteger den = null;
+
+        if (denominator.equals(fraction.denominator)) {
+            num = numerator.add(fraction.numerator);
+            den = denominator;
+        } else {
+            num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator));
+            den = denominator.multiply(fraction.denominator);
+        }
+        return new BigFraction(num, den);
+
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as a <code>BigDecimal</code>. This calculates the
+     * fraction as the numerator divided by denominator.
+     * </p>
+     *
+     * @return the fraction as a <code>BigDecimal</code>.
+     * @throws ArithmeticException
+     *             if the exact quotient does not have a terminating decimal
+     *             expansion.
+     * @see BigDecimal
+     */
+    public BigDecimal bigDecimalValue() {
+        return new BigDecimal(numerator).divide(new BigDecimal(denominator));
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as a <code>BigDecimal</code> following the passed
+     * rounding mode. This calculates the fraction as the numerator divided by
+     * denominator.
+     * </p>
+     *
+     * @param roundingMode
+     *            rounding mode to apply. see {@link BigDecimal} constants.
+     * @return the fraction as a <code>BigDecimal</code>.
+     * @throws IllegalArgumentException
+     *             if <tt>roundingMode</tt> does not represent a valid rounding
+     *             mode.
+     * @see BigDecimal
+     */
+    public BigDecimal bigDecimalValue(final int roundingMode) {
+        return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode);
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as a <code>BigDecimal</code> following the passed scale
+     * and rounding mode. This calculates the fraction as the numerator divided
+     * by denominator.
+     * </p>
+     *
+     * @param scale
+     *            scale of the <code>BigDecimal</code> quotient to be returned.
+     *            see {@link BigDecimal} for more information.
+     * @param roundingMode
+     *            rounding mode to apply. see {@link BigDecimal} constants.
+     * @return the fraction as a <code>BigDecimal</code>.
+     * @see BigDecimal
+     */
+    public BigDecimal bigDecimalValue(final int scale, final int roundingMode) {
+        return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode);
+    }
+
+    /**
+     * <p>
+     * Compares this object to another based on size.
+     * </p>
+     *
+     * @param object
+     *            the object to compare to, must not be <code>null</code>.
+     * @return -1 if this is less than <tt>object</tt>, +1 if this is greater
+     *         than <tt>object</tt>, 0 if they are equal.
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    public int compareTo(final BigFraction object) {
+        BigInteger nOd = numerator.multiply(object.denominator);
+        BigInteger dOn = denominator.multiply(object.numerator);
+        return nOd.compareTo(dOn);
+    }
+
+    /**
+     * <p>
+     * Divide the value of this fraction by the passed <code>BigInteger</code>,
+     * ie "this * 1 / bg", returning the result in reduced form.
+     * </p>
+     *
+     * @param bg
+     *            the <code>BigInteger</code> to divide by, must not be
+     *            <code>null</code>.
+     * @return a {@link BigFraction} instance with the resulting values.
+     * @throws NullPointerException if the {@code BigInteger} is {@code null}.
+     * @throws ArithmeticException
+     *             if the fraction to divide by is zero.
+     */
+    public BigFraction divide(final BigInteger bg) {
+        if (BigInteger.ZERO.equals(bg)) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
+        }
+        return new BigFraction(numerator, denominator.multiply(bg));
+    }
+
+    /**
+     * <p>
+     * Divide the value of this fraction by the passed <tt>int</tt>, ie
+     * "this * 1 / i", returning the result in reduced form.
+     * </p>
+     *
+     * @param i
+     *            the <tt>int</tt> to divide by.
+     * @return a {@link BigFraction} instance with the resulting values.
+     * @throws ArithmeticException
+     *             if the fraction to divide by is zero.
+     */
+    public BigFraction divide(final int i) {
+        return divide(BigInteger.valueOf(i));
+    }
+
+    /**
+     * <p>
+     * Divide the value of this fraction by the passed <tt>long</tt>, ie
+     * "this * 1 / l", returning the result in reduced form.
+     * </p>
+     *
+     * @param l
+     *            the <tt>long</tt> to divide by.
+     * @return a {@link BigFraction} instance with the resulting values.
+     * @throws ArithmeticException
+     *             if the fraction to divide by is zero.
+     */
+    public BigFraction divide(final long l) {
+        return divide(BigInteger.valueOf(l));
+    }
+
+    /**
+     * <p>
+     * Divide the value of this fraction by another, returning the result in
+     * reduced form.
+     * </p>
+     *
+     * @param fraction Fraction to divide by, must not be {@code null}.
+     * @return a {@link BigFraction} instance with the resulting values.
+     * @throws NullPointerException if the {@code fraction} is {@code null}.
+     * @throws ArithmeticException if the fraction to divide by is zero.
+     */
+    public BigFraction divide(final BigFraction fraction) {
+        if (fraction == null) {
+            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
+        }
+        if (BigInteger.ZERO.equals(fraction.numerator)) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR);
+        }
+
+        return multiply(fraction.reciprocal());
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as a <tt>double</tt>. This calculates the fraction as
+     * the numerator divided by denominator.
+     * </p>
+     *
+     * @return the fraction as a <tt>double</tt>
+     * @see java.lang.Number#doubleValue()
+     */
+    @Override
+    public double doubleValue() {
+        return numerator.doubleValue() / denominator.doubleValue();
+    }
+
+    /**
+     * <p>
+     * Test for the equality of two fractions. If the lowest term numerator and
+     * denominators are the same for both fractions, the two fractions are
+     * considered to be equal.
+     * </p>
+     *
+     * @param other
+     *            fraction to test for equality to this fraction, can be
+     *            <code>null</code>.
+     * @return true if two fractions are equal, false if object is
+     *         <code>null</code>, not an instance of {@link BigFraction}, or not
+     *         equal to this fraction instance.
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(final Object other) {
+        boolean ret = false;
+
+        if (this == other) {
+            ret = true;
+        } else if (other instanceof BigFraction) {
+            BigFraction rhs = ((BigFraction) other).reduce();
+            BigFraction thisOne = this.reduce();
+            ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator);
+        }
+
+        return ret;
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as a <tt>float</tt>. This calculates the fraction as
+     * the numerator divided by denominator.
+     * </p>
+     *
+     * @return the fraction as a <tt>float</tt>.
+     * @see java.lang.Number#floatValue()
+     */
+    @Override
+    public float floatValue() {
+        return numerator.floatValue() / denominator.floatValue();
+    }
+
+    /**
+     * <p>
+     * Access the denominator as a <code>BigInteger</code>.
+     * </p>
+     *
+     * @return the denominator as a <code>BigInteger</code>.
+     */
+    public BigInteger getDenominator() {
+        return denominator;
+    }
+
+    /**
+     * <p>
+     * Access the denominator as a <tt>int</tt>.
+     * </p>
+     *
+     * @return the denominator as a <tt>int</tt>.
+     */
+    public int getDenominatorAsInt() {
+        return denominator.intValue();
+    }
+
+    /**
+     * <p>
+     * Access the denominator as a <tt>long</tt>.
+     * </p>
+     *
+     * @return the denominator as a <tt>long</tt>.
+     */
+    public long getDenominatorAsLong() {
+        return denominator.longValue();
+    }
+
+    /**
+     * <p>
+     * Access the numerator as a <code>BigInteger</code>.
+     * </p>
+     *
+     * @return the numerator as a <code>BigInteger</code>.
+     */
+    public BigInteger getNumerator() {
+        return numerator;
+    }
+
+    /**
+     * <p>
+     * Access the numerator as a <tt>int</tt>.
+     * </p>
+     *
+     * @return the numerator as a <tt>int</tt>.
+     */
+    public int getNumeratorAsInt() {
+        return numerator.intValue();
+    }
+
+    /**
+     * <p>
+     * Access the numerator as a <tt>long</tt>.
+     * </p>
+     *
+     * @return the numerator as a <tt>long</tt>.
+     */
+    public long getNumeratorAsLong() {
+        return numerator.longValue();
+    }
+
+    /**
+     * <p>
+     * Gets a hashCode for the fraction.
+     * </p>
+     *
+     * @return a hash code value for this object.
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode();
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as an <tt>int</tt>. This returns the whole number part
+     * of the fraction.
+     * </p>
+     *
+     * @return the whole number fraction part.
+     * @see java.lang.Number#intValue()
+     */
+    @Override
+    public int intValue() {
+        return numerator.divide(denominator).intValue();
+    }
+
+    /**
+     * <p>
+     * Gets the fraction as a <tt>long</tt>. This returns the whole number part
+     * of the fraction.
+     * </p>
+     *
+     * @return the whole number fraction part.
+     * @see java.lang.Number#longValue()
+     */
+    @Override
+    public long longValue() {
+        return numerator.divide(denominator).longValue();
+    }
+
+    /**
+     * <p>
+     * Multiplies the value of this fraction by the passed
+     * <code>BigInteger</code>, returning the result in reduced form.
+     * </p>
+     *
+     * @param bg the {@code BigInteger} to multiply by.
+     * @return a {@code BigFraction} instance with the resulting values.
+     * @throws NullPointerException if {@code bg} is {@code null}.
+     */
+    public BigFraction multiply(final BigInteger bg) {
+        if (bg == null) {
+            throw new NullPointerException();
+        }
+        return new BigFraction(bg.multiply(numerator), denominator);
+    }
+
+    /**
+     * <p>
+     * Multiply the value of this fraction by the passed <tt>int</tt>, returning
+     * the result in reduced form.
+     * </p>
+     *
+     * @param i
+     *            the <tt>int</tt> to multiply by.
+     * @return a {@link BigFraction} instance with the resulting values.
+     */
+    public BigFraction multiply(final int i) {
+        return multiply(BigInteger.valueOf(i));
+    }
+
+    /**
+     * <p>
+     * Multiply the value of this fraction by the passed <tt>long</tt>,
+     * returning the result in reduced form.
+     * </p>
+     *
+     * @param l
+     *            the <tt>long</tt> to multiply by.
+     * @return a {@link BigFraction} instance with the resulting values.
+     */
+    public BigFraction multiply(final long l) {
+        return multiply(BigInteger.valueOf(l));
+    }
+
+    /**
+     * <p>
+     * Multiplies the value of this fraction by another, returning the result in
+     * reduced form.
+     * </p>
+     *
+     * @param fraction Fraction to multiply by, must not be {@code null}.
+     * @return a {@link BigFraction} instance with the resulting values.
+     * @throws NullPointerException if {@code fraction} is {@code null}.
+     */
+    public BigFraction multiply(final BigFraction fraction) {
+        if (fraction == null) {
+            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
+        }
+        if (numerator.equals(BigInteger.ZERO) ||
+            fraction.numerator.equals(BigInteger.ZERO)) {
+            return ZERO;
+        }
+        return new BigFraction(numerator.multiply(fraction.numerator),
+                               denominator.multiply(fraction.denominator));
+    }
+
+    /**
+     * <p>
+     * Return the additive inverse of this fraction, returning the result in
+     * reduced form.
+     * </p>
+     *
+     * @return the negation of this fraction.
+     */
+    public BigFraction negate() {
+        return new BigFraction(numerator.negate(), denominator);
+    }
+
+    /**
+     * <p>
+     * Gets the fraction percentage as a <tt>double</tt>. This calculates the
+     * fraction as the numerator divided by denominator multiplied by 100.
+     * </p>
+     *
+     * @return the fraction percentage as a <tt>double</tt>.
+     */
+    public double percentageValue() {
+        return (numerator.divide(denominator)).multiply(ONE_HUNDRED_DOUBLE).doubleValue();
+    }
+
+    /**
+     * <p>
+     * Returns a <tt>integer</tt> whose value is
+     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
+     * </p>
+     *
+     * @param exponent
+     *            exponent to which this <code>BigInteger</code> is to be
+     *            raised.
+     * @return <tt>this<sup>exponent</sup></tt>.
+     */
+    public BigFraction pow(final int exponent) {
+        if (exponent < 0) {
+            return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent));
+        }
+        return new BigFraction(numerator.pow(exponent), denominator.pow(exponent));
+    }
+
+    /**
+     * <p>
+     * Returns a <code>BigFraction</code> whose value is
+     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
+     * </p>
+     *
+     * @param exponent
+     *            exponent to which this <code>BigFraction</code> is to be raised.
+     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
+     */
+    public BigFraction pow(final long exponent) {
+        if (exponent < 0) {
+            return new BigFraction(MathUtils.pow(denominator, -exponent),
+                                   MathUtils.pow(numerator,   -exponent));
+        }
+        return new BigFraction(MathUtils.pow(numerator,   exponent),
+                               MathUtils.pow(denominator, exponent));
+    }
+
+    /**
+     * <p>
+     * Returns a <code>BigFraction</code> whose value is
+     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
+     * </p>
+     *
+     * @param exponent
+     *            exponent to which this <code>BigFraction</code> is to be raised.
+     * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>.
+     */
+    public BigFraction pow(final BigInteger exponent) {
+        if (exponent.compareTo(BigInteger.ZERO) < 0) {
+            final BigInteger eNeg = exponent.negate();
+            return new BigFraction(MathUtils.pow(denominator, eNeg),
+                                   MathUtils.pow(numerator,   eNeg));
+        }
+        return new BigFraction(MathUtils.pow(numerator,   exponent),
+                               MathUtils.pow(denominator, exponent));
+    }
+
+    /**
+     * <p>
+     * Returns a <code>double</code> whose value is
+     * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form.
+     * </p>
+     *
+     * @param exponent
+     *            exponent to which this <code>BigFraction</code> is to be raised.
+     * @return <tt>this<sup>exponent</sup></tt>.
+     */
+    public double pow(final double exponent) {
+        return FastMath.pow(numerator.doubleValue(),   exponent) /
+               FastMath.pow(denominator.doubleValue(), exponent);
+    }
+
+    /**
+     * <p>
+     * Return the multiplicative inverse of this fraction.
+     * </p>
+     *
+     * @return the reciprocal fraction.
+     */
+    public BigFraction reciprocal() {
+        return new BigFraction(denominator, numerator);
+    }
+
+    /**
+     * <p>
+     * Reduce this <code>BigFraction</code> to its lowest terms.
+     * </p>
+     *
+     * @return the reduced <code>BigFraction</code>. It doesn't change anything if
+     *         the fraction can be reduced.
+     */
+    public BigFraction reduce() {
+        final BigInteger gcd = numerator.gcd(denominator);
+        return new BigFraction(numerator.divide(gcd), denominator.divide(gcd));
+    }
+
+    /**
+     * <p>
+     * Subtracts the value of an {@link BigInteger} from the value of this one,
+     * returning the result in reduced form.
+     * </p>
+     *
+     * @param bg the {@link BigInteger} to subtract, cannot be {@code null}.
+     * @return a {@code BigFraction} instance with the resulting values.
+     * @throws NullPointerException if the {@link BigInteger} is {@code null}.
+     */
+    public BigFraction subtract(final BigInteger bg) {
+        if (bg == null) {
+            throw new NullPointerException();
+        }
+        return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator);
+    }
+
+    /**
+     * <p>
+     * Subtracts the value of an <tt>integer</tt> from the value of this one,
+     * returning the result in reduced form.
+     * </p>
+     *
+     * @param i
+     *            the <tt>integer</tt> to subtract.
+     * @return a <code>BigFraction</code> instance with the resulting values.
+     */
+    public BigFraction subtract(final int i) {
+        return subtract(BigInteger.valueOf(i));
+    }
+
+    /**
+     * <p>
+     * Subtracts the value of an <tt>integer</tt> from the value of this one,
+     * returning the result in reduced form.
+     * </p>
+     *
+     * @param l
+     *            the <tt>long</tt> to subtract.
+     * @return a <code>BigFraction</code> instance with the resulting values, or
+     *         this object if the <tt>long</tt> is zero.
+     */
+    public BigFraction subtract(final long l) {
+        return subtract(BigInteger.valueOf(l));
+    }
+
+    /**
+     * <p>
+     * Subtracts the value of another fraction from the value of this one,
+     * returning the result in reduced form.
+     * </p>
+     *
+     * @param fraction {@link BigFraction} to subtract, must not be {@code null}.
+     * @return a {@link BigFraction} instance with the resulting values
+     * @throws NullPointerException if the {@code fraction} is {@code null}.
+     */
+    public BigFraction subtract(final BigFraction fraction) {
+        if (fraction == null) {
+            throw new NullPointerException(LocalizedFormats.FRACTION.getSourceString());
+        }
+        if (ZERO.equals(fraction)) {
+            return this;
+        }
+
+        BigInteger num = null;
+        BigInteger den = null;
+        if (denominator.equals(fraction.denominator)) {
+            num = numerator.subtract(fraction.numerator);
+            den = denominator;
+        } else {
+            num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator));
+            den = denominator.multiply(fraction.denominator);
+        }
+        return new BigFraction(num, den);
+
+    }
+
+    /**
+     * <p>
+     * Returns the <code>String</code> representing this fraction, ie
+     * "num / dem" or just "num" if the denominator is one.
+     * </p>
+     *
+     * @return a string representation of the fraction.
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        String str = null;
+        if (BigInteger.ONE.equals(denominator)) {
+            str = numerator.toString();
+        } else if (BigInteger.ZERO.equals(numerator)) {
+            str = "0";
+        } else {
+            str = numerator + " / " + denominator;
+        }
+        return str;
+    }
+
+    /** {@inheritDoc} */
+    public BigFractionField getField() {
+        return BigFractionField.getInstance();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/BigFractionField.java b/src/main/java/org/apache/commons/math/fraction/BigFractionField.java
new file mode 100644
index 0000000..bc3a7e9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/BigFractionField.java
@@ -0,0 +1,78 @@
+/*
+ * 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.fraction;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.Field;
+
+/**
+ * Representation of the fractional numbers  without any overflow field.
+ * <p>
+ * This class is a singleton.
+ * </p>
+ * @see Fraction
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public class BigFractionField implements Field<BigFraction>, Serializable  {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1699294557189741703L;
+
+    /** Private constructor for the singleton.
+     */
+    private BigFractionField() {
+    }
+
+    /** Get the unique instance.
+     * @return the unique instance
+     */
+    public static BigFractionField getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    /** {@inheritDoc} */
+    public BigFraction getOne() {
+        return BigFraction.ONE;
+    }
+
+    /** {@inheritDoc} */
+    public BigFraction getZero() {
+        return BigFraction.ZERO;
+    }
+
+    // CHECKSTYLE: stop HideUtilityClassConstructor
+    /** Holder for the instance.
+     * <p>We use here the Initialization On Demand Holder Idiom.</p>
+     */
+    private static class LazyHolder {
+        /** Cached field instance. */
+        private static final BigFractionField INSTANCE = new BigFractionField();
+    }
+    // CHECKSTYLE: resume HideUtilityClassConstructor
+
+    /** Handle deserialization of the singleton.
+     * @return the singleton instance
+     */
+    private Object readResolve() {
+        // return the singleton instance
+        return LazyHolder.INSTANCE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/BigFractionFormat.java b/src/main/java/org/apache/commons/math/fraction/BigFractionFormat.java
new file mode 100644
index 0000000..918e5e1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/BigFractionFormat.java
@@ -0,0 +1,291 @@
+/*
+ * 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.fraction;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Formats a BigFraction number in proper format or improper format.
+ * <p>
+ * The number format for each of the whole number, numerator and,
+ * denominator can be configured.
+ * </p>
+ *
+ * @since 2.0
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class BigFractionFormat extends AbstractFormat implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -2932167925527338976L;
+
+    /**
+     * Create an improper formatting instance with the default number format
+     * for the numerator and denominator.
+     */
+    public BigFractionFormat() {
+    }
+
+    /**
+     * Create an improper formatting instance with a custom number format for
+     * both the numerator and denominator.
+     * @param format the custom format for both the numerator and denominator.
+     */
+    public BigFractionFormat(final NumberFormat format) {
+        super(format);
+    }
+
+    /**
+     * Create an improper formatting instance with a custom number format for
+     * the numerator and a custom number format for the denominator.
+     * @param numeratorFormat the custom format for the numerator.
+     * @param denominatorFormat the custom format for the denominator.
+     */
+    public BigFractionFormat(final NumberFormat numeratorFormat,
+                             final NumberFormat denominatorFormat) {
+        super(numeratorFormat, denominatorFormat);
+    }
+
+    /**
+     * Get the set of locales for which complex formats are available.  This
+     * is the same set as the {@link NumberFormat} set.
+     * @return available complex format locales.
+     */
+    public static Locale[] getAvailableLocales() {
+        return NumberFormat.getAvailableLocales();
+    }
+
+    /**
+     * This static method calls formatBigFraction() on a default instance of
+     * BigFractionFormat.
+     *
+     * @param f BigFraction object to format
+     * @return A formatted BigFraction in proper form.
+     */
+    public static String formatBigFraction(final BigFraction f) {
+        return getImproperInstance().format(f);
+    }
+
+    /**
+     * Returns the default complex format for the current locale.
+     * @return the default complex format.
+     */
+    public static BigFractionFormat getImproperInstance() {
+        return getImproperInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns the default complex format for the given locale.
+     * @param locale the specific locale used by the format.
+     * @return the complex format specific to the given locale.
+     */
+    public static BigFractionFormat getImproperInstance(final Locale locale) {
+        return new BigFractionFormat(getDefaultNumberFormat(locale));
+    }
+
+    /**
+     * Returns the default complex format for the current locale.
+     * @return the default complex format.
+     */
+    public static BigFractionFormat getProperInstance() {
+        return getProperInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns the default complex format for the given locale.
+     * @param locale the specific locale used by the format.
+     * @return the complex format specific to the given locale.
+     */
+    public static BigFractionFormat getProperInstance(final Locale locale) {
+        return new ProperBigFractionFormat(getDefaultNumberFormat(locale));
+    }
+
+    /**
+     * Formats a {@link BigFraction} object to produce a string.  The BigFraction is
+     * output in improper format.
+     *
+     * @param BigFraction 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(final BigFraction BigFraction,
+                               final StringBuffer toAppendTo, final FieldPosition pos) {
+
+        pos.setBeginIndex(0);
+        pos.setEndIndex(0);
+
+        getNumeratorFormat().format(BigFraction.getNumerator(), toAppendTo, pos);
+        toAppendTo.append(" / ");
+        getDenominatorFormat().format(BigFraction.getDenominator(), toAppendTo, pos);
+
+        return toAppendTo;
+    }
+
+    /**
+     * Formats an object and appends the result to a StringBuffer.
+     * <code>obj</code> must be either a  {@link BigFraction} object or a
+     * {@link BigInteger} object or a {@link Number} 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 <code>obj</code> is not a valid type.
+     */
+    @Override
+    public StringBuffer format(final Object obj,
+                               final StringBuffer toAppendTo, final FieldPosition pos) {
+
+        final StringBuffer ret;
+        if (obj instanceof BigFraction) {
+            ret = format((BigFraction) obj, toAppendTo, pos);
+        } else if (obj instanceof BigInteger) {
+            ret = format(new BigFraction((BigInteger) obj), toAppendTo, pos);
+        } else if (obj instanceof Number) {
+            ret = format(new BigFraction(((Number) obj).doubleValue()),
+                         toAppendTo, pos);
+        } else {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.CANNOT_FORMAT_OBJECT_TO_FRACTION);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Parses a string to produce a {@link BigFraction} object.
+     * @param source the string to parse
+     * @return the parsed {@link BigFraction} object.
+     * @exception ParseException if the beginning of the specified string
+     *            cannot be parsed.
+     */
+    @Override
+    public BigFraction parse(final String source) throws ParseException {
+        final ParsePosition parsePosition = new ParsePosition(0);
+        final BigFraction result = parse(source, parsePosition);
+        if (parsePosition.getIndex() == 0) {
+            throw MathRuntimeException.createParseException(
+                    parsePosition.getErrorIndex(),
+                    LocalizedFormats.UNPARSEABLE_FRACTION_NUMBER, source);
+        }
+        return result;
+    }
+
+    /**
+     * Parses a string to produce a {@link BigFraction} object.
+     * This method expects the string to be formatted as an improper BigFraction.
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed {@link BigFraction} object.
+     */
+    @Override
+    public BigFraction parse(final String source, final ParsePosition pos) {
+        final int initialIndex = pos.getIndex();
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse numerator
+        final BigInteger num = parseNextBigInteger(source, pos);
+        if (num == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse '/'
+        final int startIndex = pos.getIndex();
+        final char c = parseNextCharacter(source, pos);
+        switch (c) {
+        case 0 :
+            // no '/'
+            // return num as a BigFraction
+            return new BigFraction(num);
+        case '/' :
+            // found '/', continue parsing denominator
+            break;
+        default :
+            // invalid '/'
+            // set index back to initial, error index should be the last
+            // character examined.
+            pos.setIndex(initialIndex);
+            pos.setErrorIndex(startIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse denominator
+        final BigInteger den = parseNextBigInteger(source, pos);
+        if (den == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        return new BigFraction(num, den);
+    }
+
+    /**
+     * Parses a string to produce a <code>BigInteger</code>.
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return a parsed <code>BigInteger</code> or null if string does not
+     * contain a BigInteger at the specified position
+     */
+    protected BigInteger parseNextBigInteger(final String source,
+                                             final ParsePosition pos) {
+
+        final int start = pos.getIndex();
+         int end = (source.charAt(start) == '-') ? (start + 1) : start;
+         while((end < source.length()) &&
+               Character.isDigit(source.charAt(end))) {
+             ++end;
+         }
+
+         try {
+             BigInteger n = new BigInteger(source.substring(start, end));
+             pos.setIndex(end);
+             return n;
+         } catch (NumberFormatException nfe) {
+             pos.setErrorIndex(start);
+             return null;
+         }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/Fraction.java b/src/main/java/org/apache/commons/math/fraction/Fraction.java
new file mode 100644
index 0000000..82ecf63
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/Fraction.java
@@ -0,0 +1,655 @@
+/*
+ * 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.fraction;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Representation of a rational number.
+ *
+ * implements Serializable since 2.0
+ *
+ * @since 1.1
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public class Fraction
+    extends Number
+    implements FieldElement<Fraction>, Comparable<Fraction>, Serializable {
+
+    /** A fraction representing "2 / 1". */
+    public static final Fraction TWO = new Fraction(2, 1);
+
+    /** A fraction representing "1". */
+    public static final Fraction ONE = new Fraction(1, 1);
+
+    /** A fraction representing "0". */
+    public static final Fraction ZERO = new Fraction(0, 1);
+
+    /** A fraction representing "4/5". */
+    public static final Fraction FOUR_FIFTHS = new Fraction(4, 5);
+
+    /** A fraction representing "1/5". */
+    public static final Fraction ONE_FIFTH = new Fraction(1, 5);
+
+    /** A fraction representing "1/2". */
+    public static final Fraction ONE_HALF = new Fraction(1, 2);
+
+    /** A fraction representing "1/4". */
+    public static final Fraction ONE_QUARTER = new Fraction(1, 4);
+
+    /** A fraction representing "1/3". */
+    public static final Fraction ONE_THIRD = new Fraction(1, 3);
+
+    /** A fraction representing "3/5". */
+    public static final Fraction THREE_FIFTHS = new Fraction(3, 5);
+
+    /** A fraction representing "3/4". */
+    public static final Fraction THREE_QUARTERS = new Fraction(3, 4);
+
+    /** A fraction representing "2/5". */
+    public static final Fraction TWO_FIFTHS = new Fraction(2, 5);
+
+    /** A fraction representing "2/4". */
+    public static final Fraction TWO_QUARTERS = new Fraction(2, 4);
+
+    /** A fraction representing "2/3". */
+    public static final Fraction TWO_THIRDS = new Fraction(2, 3);
+
+    /** A fraction representing "-1 / 1". */
+    public static final Fraction MINUS_ONE = new Fraction(-1, 1);
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 3698073679419233275L;
+
+    /** The denominator. */
+    private final int denominator;
+
+    /** The numerator. */
+    private final int numerator;
+
+    /**
+     * Create a fraction given the double value.
+     * @param value the double value to convert to a fraction.
+     * @throws FractionConversionException if the continued fraction failed to
+     *         converge.
+     */
+    public Fraction(double value) throws FractionConversionException {
+        this(value, 1.0e-5, 100);
+    }
+
+    /**
+     * Create a fraction given the double value and maximum error allowed.
+     * <p>
+     * References:
+     * <ul>
+     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
+     * Continued Fraction</a> equations (11) and (22)-(26)</li>
+     * </ul>
+     * </p>
+     * @param value the double value to convert to a fraction.
+     * @param epsilon maximum error allowed.  The resulting fraction is within
+     *        <code>epsilon</code> of <code>value</code>, in absolute terms.
+     * @param maxIterations maximum number of convergents
+     * @throws FractionConversionException if the continued fraction failed to
+     *         converge.
+     */
+    public Fraction(double value, double epsilon, int maxIterations)
+        throws FractionConversionException
+    {
+        this(value, epsilon, Integer.MAX_VALUE, maxIterations);
+    }
+
+    /**
+     * Create a fraction given the double value and maximum denominator.
+     * <p>
+     * References:
+     * <ul>
+     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
+     * Continued Fraction</a> equations (11) and (22)-(26)</li>
+     * </ul>
+     * </p>
+     * @param value the double value to convert to a fraction.
+     * @param maxDenominator The maximum allowed value for denominator
+     * @throws FractionConversionException if the continued fraction failed to
+     *         converge
+     */
+    public Fraction(double value, int maxDenominator)
+        throws FractionConversionException
+    {
+       this(value, 0, maxDenominator, 100);
+    }
+
+    /**
+     * Create a fraction given the double value and either the maximum error
+     * allowed or the maximum number of denominator digits.
+     * <p>
+     *
+     * NOTE: This constructor is called with EITHER
+     *   - a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE
+     *     (that way the maxDenominator has no effect).
+     * OR
+     *   - a valid maxDenominator value and the epsilon value set to zero
+     *     (that way epsilon only has effect if there is an exact match before
+     *     the maxDenominator value is reached).
+     * </p><p>
+     *
+     * It has been done this way so that the same code can be (re)used for both
+     * scenarios. However this could be confusing to users if it were part of
+     * the public API and this constructor should therefore remain PRIVATE.
+     * </p>
+     *
+     * See JIRA issue ticket MATH-181 for more details:
+     *
+     *     https://issues.apache.org/jira/browse/MATH-181
+     *
+     * @param value the double value to convert to a fraction.
+     * @param epsilon maximum error allowed.  The resulting fraction is within
+     *        <code>epsilon</code> of <code>value</code>, in absolute terms.
+     * @param maxDenominator maximum denominator value allowed.
+     * @param maxIterations maximum number of convergents
+     * @throws FractionConversionException if the continued fraction failed to
+     *         converge.
+     */
+    private Fraction(double value, double epsilon, int maxDenominator, int maxIterations)
+        throws FractionConversionException
+    {
+        long overflow = Integer.MAX_VALUE;
+        double r0 = value;
+        long a0 = (long)FastMath.floor(r0);
+        if (a0 > overflow) {
+            throw new FractionConversionException(value, a0, 1l);
+        }
+
+        // check for (almost) integer arguments, which should not go
+        // to iterations.
+        if (FastMath.abs(a0 - value) < epsilon) {
+            this.numerator = (int) a0;
+            this.denominator = 1;
+            return;
+        }
+
+        long p0 = 1;
+        long q0 = 0;
+        long p1 = a0;
+        long q1 = 1;
+
+        long p2 = 0;
+        long q2 = 1;
+
+        int n = 0;
+        boolean stop = false;
+        do {
+            ++n;
+            double r1 = 1.0 / (r0 - a0);
+            long a1 = (long)FastMath.floor(r1);
+            p2 = (a1 * p1) + p0;
+            q2 = (a1 * q1) + q0;
+            if ((p2 > overflow) || (q2 > overflow)) {
+                throw new FractionConversionException(value, p2, q2);
+            }
+
+            double convergent = (double)p2 / (double)q2;
+            if (n < maxIterations && FastMath.abs(convergent - value) > epsilon && q2 < maxDenominator) {
+                p0 = p1;
+                p1 = p2;
+                q0 = q1;
+                q1 = q2;
+                a0 = a1;
+                r0 = r1;
+            } else {
+                stop = true;
+            }
+        } while (!stop);
+
+        if (n >= maxIterations) {
+            throw new FractionConversionException(value, maxIterations);
+        }
+
+        if (q2 < maxDenominator) {
+            this.numerator = (int) p2;
+            this.denominator = (int) q2;
+        } else {
+            this.numerator = (int) p1;
+            this.denominator = (int) q1;
+        }
+
+    }
+
+    /**
+     * Create a fraction from an int.
+     * The fraction is num / 1.
+     * @param num the numerator.
+     */
+    public Fraction(int num) {
+        this(num, 1);
+    }
+
+    /**
+     * Create a fraction given the numerator and denominator.  The fraction is
+     * reduced to lowest terms.
+     * @param num the numerator.
+     * @param den the denominator.
+     * @throws ArithmeticException if the denominator is <code>zero</code>
+     */
+    public Fraction(int num, int den) {
+        if (den == 0) {
+            throw MathRuntimeException.createArithmeticException(
+                  LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION, num, den);
+        }
+        if (den < 0) {
+            if (num == Integer.MIN_VALUE || den == Integer.MIN_VALUE) {
+                throw MathRuntimeException.createArithmeticException(
+                      LocalizedFormats.OVERFLOW_IN_FRACTION, num, den);
+            }
+            num = -num;
+            den = -den;
+        }
+        // reduce numerator and denominator by greatest common denominator.
+        final int d = MathUtils.gcd(num, den);
+        if (d > 1) {
+            num /= d;
+            den /= d;
+        }
+
+        // move sign to numerator.
+        if (den < 0) {
+            num = -num;
+            den = -den;
+        }
+        this.numerator   = num;
+        this.denominator = den;
+    }
+
+    /**
+     * Returns the absolute value of this fraction.
+     * @return the absolute value.
+     */
+    public Fraction abs() {
+        Fraction ret;
+        if (numerator >= 0) {
+            ret = this;
+        } else {
+            ret = negate();
+        }
+        return ret;
+    }
+
+    /**
+     * Compares this object to another based on size.
+     * @param object the object to compare to
+     * @return -1 if this is less than <tt>object</tt>, +1 if this is greater
+     *         than <tt>object</tt>, 0 if they are equal.
+     */
+    public int compareTo(Fraction object) {
+        long nOd = ((long) numerator) * object.denominator;
+        long dOn = ((long) denominator) * object.numerator;
+        return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0);
+    }
+
+    /**
+     * Gets the fraction as a <tt>double</tt>. This calculates the fraction as
+     * the numerator divided by denominator.
+     * @return the fraction as a <tt>double</tt>
+     */
+    @Override
+    public double doubleValue() {
+        return (double)numerator / (double)denominator;
+    }
+
+    /**
+     * Test for the equality of two fractions.  If the lowest term
+     * numerator and denominators are the same for both fractions, the two
+     * fractions are considered to be equal.
+     * @param other fraction to test for equality to this fraction
+     * @return true if two fractions are equal, false if object is
+     *         <tt>null</tt>, not an instance of {@link Fraction}, or not equal
+     *         to this fraction instance.
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof Fraction) {
+            // since fractions are always in lowest terms, numerators and
+            // denominators can be compared directly for equality.
+            Fraction rhs = (Fraction)other;
+            return (numerator == rhs.numerator) &&
+                (denominator == rhs.denominator);
+        }
+        return false;
+    }
+
+    /**
+     * Gets the fraction as a <tt>float</tt>. This calculates the fraction as
+     * the numerator divided by denominator.
+     * @return the fraction as a <tt>float</tt>
+     */
+    @Override
+    public float floatValue() {
+        return (float)doubleValue();
+    }
+
+    /**
+     * Access the denominator.
+     * @return the denominator.
+     */
+    public int getDenominator() {
+        return denominator;
+    }
+
+    /**
+     * Access the numerator.
+     * @return the numerator.
+     */
+    public int getNumerator() {
+        return numerator;
+    }
+
+    /**
+     * Gets a hashCode for the fraction.
+     * @return a hash code value for this object
+     */
+    @Override
+    public int hashCode() {
+        return 37 * (37 * 17 + numerator) + denominator;
+    }
+
+    /**
+     * Gets the fraction as an <tt>int</tt>. This returns the whole number part
+     * of the fraction.
+     * @return the whole number fraction part
+     */
+    @Override
+    public int intValue() {
+        return (int)doubleValue();
+    }
+
+    /**
+     * Gets the fraction as a <tt>long</tt>. This returns the whole number part
+     * of the fraction.
+     * @return the whole number fraction part
+     */
+    @Override
+    public long longValue() {
+        return (long)doubleValue();
+    }
+
+    /**
+     * Return the additive inverse of this fraction.
+     * @return the negation of this fraction.
+     */
+    public Fraction negate() {
+        if (numerator==Integer.MIN_VALUE) {
+            throw MathRuntimeException.createArithmeticException(
+                  LocalizedFormats.OVERFLOW_IN_FRACTION, numerator, denominator);
+        }
+        return new Fraction(-numerator, denominator);
+    }
+
+    /**
+     * Return the multiplicative inverse of this fraction.
+     * @return the reciprocal fraction
+     */
+    public Fraction reciprocal() {
+        return new Fraction(denominator, numerator);
+    }
+
+    /**
+     * <p>Adds the value of this fraction to another, returning the result in reduced form.
+     * The algorithm follows Knuth, 4.5.1.</p>
+     *
+     * @param fraction  the fraction to add, must not be <code>null</code>
+     * @return a <code>Fraction</code> instance with the resulting values
+     * @throws IllegalArgumentException if the fraction is <code>null</code>
+     * @throws ArithmeticException if the resulting numerator or denominator exceeds
+     *  <code>Integer.MAX_VALUE</code>
+     */
+    public Fraction add(Fraction fraction) {
+        return addSub(fraction, true /* add */);
+    }
+
+    /**
+     * Add an integer to the fraction.
+     * @param i the <tt>integer</tt> to add.
+     * @return this + i
+     */
+    public Fraction add(final int i) {
+        return new Fraction(numerator + i * denominator, denominator);
+    }
+
+    /**
+     * <p>Subtracts the value of another fraction from the value of this one,
+     * returning the result in reduced form.</p>
+     *
+     * @param fraction  the fraction to subtract, must not be <code>null</code>
+     * @return a <code>Fraction</code> instance with the resulting values
+     * @throws IllegalArgumentException if the fraction is <code>null</code>
+     * @throws ArithmeticException if the resulting numerator or denominator
+     *   cannot be represented in an <code>int</code>.
+     */
+    public Fraction subtract(Fraction fraction) {
+        return addSub(fraction, false /* subtract */);
+    }
+
+    /**
+     * Subtract an integer from the fraction.
+     * @param i the <tt>integer</tt> to subtract.
+     * @return this - i
+     */
+    public Fraction subtract(final int i) {
+        return new Fraction(numerator - i * denominator, denominator);
+    }
+
+    /**
+     * Implement add and subtract using algorithm described in Knuth 4.5.1.
+     *
+     * @param fraction the fraction to subtract, must not be <code>null</code>
+     * @param isAdd true to add, false to subtract
+     * @return a <code>Fraction</code> instance with the resulting values
+     * @throws IllegalArgumentException if the fraction is <code>null</code>
+     * @throws ArithmeticException if the resulting numerator or denominator
+     *   cannot be represented in an <code>int</code>.
+     */
+    private Fraction addSub(Fraction fraction, boolean isAdd) {
+        if (fraction == null) {
+            throw new NullArgumentException(LocalizedFormats.FRACTION);
+        }
+        // zero is identity for addition.
+        if (numerator == 0) {
+            return isAdd ? fraction : fraction.negate();
+        }
+        if (fraction.numerator == 0) {
+            return this;
+        }
+        // if denominators are randomly distributed, d1 will be 1 about 61%
+        // of the time.
+        int d1 = MathUtils.gcd(denominator, fraction.denominator);
+        if (d1==1) {
+            // result is ( (u*v' +/- u'v) / u'v')
+            int uvp = MathUtils.mulAndCheck(numerator, fraction.denominator);
+            int upv = MathUtils.mulAndCheck(fraction.numerator, denominator);
+            return new Fraction
+                (isAdd ? MathUtils.addAndCheck(uvp, upv) :
+                 MathUtils.subAndCheck(uvp, upv),
+                 MathUtils.mulAndCheck(denominator, fraction.denominator));
+        }
+        // the quantity 't' requires 65 bits of precision; see knuth 4.5.1
+        // exercise 7.  we're going to use a BigInteger.
+        // t = u(v'/d1) +/- v(u'/d1)
+        BigInteger uvp = BigInteger.valueOf(numerator)
+        .multiply(BigInteger.valueOf(fraction.denominator/d1));
+        BigInteger upv = BigInteger.valueOf(fraction.numerator)
+        .multiply(BigInteger.valueOf(denominator/d1));
+        BigInteger t = isAdd ? uvp.add(upv) : uvp.subtract(upv);
+        // but d2 doesn't need extra precision because
+        // d2 = gcd(t,d1) = gcd(t mod d1, d1)
+        int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue();
+        int d2 = (tmodd1==0)?d1:MathUtils.gcd(tmodd1, d1);
+
+        // result is (t/d2) / (u'/d1)(v'/d2)
+        BigInteger w = t.divide(BigInteger.valueOf(d2));
+        if (w.bitLength() > 31) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.NUMERATOR_OVERFLOW_AFTER_MULTIPLY,
+                                                                 w);
+        }
+        return new Fraction (w.intValue(),
+                MathUtils.mulAndCheck(denominator/d1,
+                        fraction.denominator/d2));
+    }
+
+    /**
+     * <p>Multiplies the value of this fraction by another, returning the
+     * result in reduced form.</p>
+     *
+     * @param fraction  the fraction to multiply by, must not be <code>null</code>
+     * @return a <code>Fraction</code> instance with the resulting values
+     * @throws IllegalArgumentException if the fraction is <code>null</code>
+     * @throws ArithmeticException if the resulting numerator or denominator exceeds
+     *  <code>Integer.MAX_VALUE</code>
+     */
+    public Fraction multiply(Fraction fraction) {
+        if (fraction == null) {
+            throw new NullArgumentException(LocalizedFormats.FRACTION);
+        }
+        if (numerator == 0 || fraction.numerator == 0) {
+            return ZERO;
+        }
+        // knuth 4.5.1
+        // make sure we don't overflow unless the result *must* overflow.
+        int d1 = MathUtils.gcd(numerator, fraction.denominator);
+        int d2 = MathUtils.gcd(fraction.numerator, denominator);
+        return getReducedFraction
+        (MathUtils.mulAndCheck(numerator/d1, fraction.numerator/d2),
+                MathUtils.mulAndCheck(denominator/d2, fraction.denominator/d1));
+    }
+
+    /**
+     * Multiply the fraction by an integer.
+     * @param i the <tt>integer</tt> to multiply by.
+     * @return this * i
+     */
+    public Fraction multiply(final int i) {
+        return new Fraction(numerator * i, denominator);
+    }
+
+    /**
+     * <p>Divide the value of this fraction by another.</p>
+     *
+     * @param fraction  the fraction to divide by, must not be <code>null</code>
+     * @return a <code>Fraction</code> instance with the resulting values
+     * @throws IllegalArgumentException if the fraction is <code>null</code>
+     * @throws ArithmeticException if the fraction to divide by is zero
+     * @throws ArithmeticException if the resulting numerator or denominator exceeds
+     *  <code>Integer.MAX_VALUE</code>
+     */
+    public Fraction divide(Fraction fraction) {
+        if (fraction == null) {
+            throw new NullArgumentException(LocalizedFormats.FRACTION);
+        }
+        if (fraction.numerator == 0) {
+            throw MathRuntimeException.createArithmeticException(
+                    LocalizedFormats.ZERO_FRACTION_TO_DIVIDE_BY,
+                    fraction.numerator, fraction.denominator);
+        }
+        return multiply(fraction.reciprocal());
+    }
+
+    /**
+     * Divide the fraction by an integer.
+     * @param i the <tt>integer</tt> to divide by.
+     * @return this * i
+     */
+    public Fraction divide(final int i) {
+        return new Fraction(numerator, denominator * i);
+    }
+
+    /**
+     * <p>Creates a <code>Fraction</code> instance with the 2 parts
+     * of a fraction Y/Z.</p>
+     *
+     * <p>Any negative signs are resolved to be on the numerator.</p>
+     *
+     * @param numerator  the numerator, for example the three in 'three sevenths'
+     * @param denominator  the denominator, for example the seven in 'three sevenths'
+     * @return a new fraction instance, with the numerator and denominator reduced
+     * @throws ArithmeticException if the denominator is <code>zero</code>
+     */
+    public static Fraction getReducedFraction(int numerator, int denominator) {
+        if (denominator == 0) {
+            throw MathRuntimeException.createArithmeticException(
+                  LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION, numerator, denominator);
+        }
+        if (numerator==0) {
+            return ZERO; // normalize zero.
+        }
+        // allow 2^k/-2^31 as a valid fraction (where k>0)
+        if (denominator==Integer.MIN_VALUE && (numerator&1)==0) {
+            numerator/=2; denominator/=2;
+        }
+        if (denominator < 0) {
+            if (numerator==Integer.MIN_VALUE ||
+                    denominator==Integer.MIN_VALUE) {
+                throw MathRuntimeException.createArithmeticException(
+                      LocalizedFormats.OVERFLOW_IN_FRACTION, numerator, denominator);
+            }
+            numerator = -numerator;
+            denominator = -denominator;
+        }
+        // simplify fraction.
+        int gcd = MathUtils.gcd(numerator, denominator);
+        numerator /= gcd;
+        denominator /= gcd;
+        return new Fraction(numerator, denominator);
+    }
+
+    /**
+     * <p>
+     * Returns the <code>String</code> representing this fraction, ie
+     * "num / dem" or just "num" if the denominator is one.
+     * </p>
+     *
+     * @return a string representation of the fraction.
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        String str = null;
+        if (denominator == 1) {
+            str = Integer.toString(numerator);
+        } else if (numerator == 0) {
+            str = "0";
+        } else {
+            str = numerator + " / " + denominator;
+        }
+        return str;
+    }
+
+    /** {@inheritDoc} */
+    public FractionField getField() {
+        return FractionField.getInstance();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/FractionConversionException.java b/src/main/java/org/apache/commons/math/fraction/FractionConversionException.java
new file mode 100644
index 0000000..9c99fcd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/FractionConversionException.java
@@ -0,0 +1,56 @@
+/*
+ * 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.fraction;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Error thrown when a double value cannot be converted to a fraction
+ * in the allowed number of iterations.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 1.2
+ */
+public class FractionConversionException extends ConvergenceException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -4661812640132576263L;
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param value double value to convert
+     * @param maxIterations maximal number of iterations allowed
+     */
+    public FractionConversionException(double value, int maxIterations) {
+        super(LocalizedFormats.FAILED_FRACTION_CONVERSION, value, maxIterations);
+    }
+
+    /**
+     * Constructs an exception with specified formatted detail message.
+     * Message formatting is delegated to {@link java.text.MessageFormat}.
+     * @param value double value to convert
+     * @param p current numerator
+     * @param q current denominator
+     */
+    public FractionConversionException(double value, long p, long q) {
+        super(LocalizedFormats.FRACTION_CONVERSION_OVERFLOW, value, p, q);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/FractionField.java b/src/main/java/org/apache/commons/math/fraction/FractionField.java
new file mode 100644
index 0000000..e6d7c47
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/FractionField.java
@@ -0,0 +1,78 @@
+/*
+ * 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.fraction;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.Field;
+
+/**
+ * Representation of the fractional numbers field.
+ * <p>
+ * This class is a singleton.
+ * </p>
+ * @see Fraction
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public class FractionField implements Field<Fraction>, Serializable  {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1257768487499119313L;
+
+    /** Private constructor for the singleton.
+     */
+    private FractionField() {
+    }
+
+    /** Get the unique instance.
+     * @return the unique instance
+     */
+    public static FractionField getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    /** {@inheritDoc} */
+    public Fraction getOne() {
+        return Fraction.ONE;
+    }
+
+    /** {@inheritDoc} */
+    public Fraction getZero() {
+        return Fraction.ZERO;
+    }
+
+    // CHECKSTYLE: stop HideUtilityClassConstructor
+    /** Holder for the instance.
+     * <p>We use here the Initialization On Demand Holder Idiom.</p>
+     */
+    private static class LazyHolder {
+        /** Cached field instance. */
+        private static final FractionField INSTANCE = new FractionField();
+    }
+    // CHECKSTYLE: resume HideUtilityClassConstructor
+
+    /** Handle deserialization of the singleton.
+     * @return the singleton instance
+     */
+    private Object readResolve() {
+        // return the singleton instance
+        return LazyHolder.INSTANCE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/FractionFormat.java b/src/main/java/org/apache/commons/math/fraction/FractionFormat.java
new file mode 100644
index 0000000..b84f7cd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/FractionFormat.java
@@ -0,0 +1,274 @@
+/*
+ * 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.fraction;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Formats a Fraction number in proper format or improper format.  The number
+ * format for each of the whole number, numerator and, denominator can be
+ * configured.
+ *
+ * @since 1.1
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class FractionFormat extends AbstractFormat {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 3008655719530972611L;
+
+    /**
+     * Create an improper formatting instance with the default number format
+     * for the numerator and denominator.
+     */
+    public FractionFormat() {
+    }
+
+    /**
+     * Create an improper formatting instance with a custom number format for
+     * both the numerator and denominator.
+     * @param format the custom format for both the numerator and denominator.
+     */
+    public FractionFormat(final NumberFormat format) {
+        super(format);
+    }
+
+    /**
+     * Create an improper formatting instance with a custom number format for
+     * the numerator and a custom number format for the denominator.
+     * @param numeratorFormat the custom format for the numerator.
+     * @param denominatorFormat the custom format for the denominator.
+     */
+    public FractionFormat(final NumberFormat numeratorFormat,
+                          final NumberFormat denominatorFormat) {
+        super(numeratorFormat, denominatorFormat);
+    }
+
+    /**
+     * Get the set of locales for which complex formats are available.  This
+     * is the same set as the {@link NumberFormat} set.
+     * @return available complex format locales.
+     */
+    public static Locale[] getAvailableLocales() {
+        return NumberFormat.getAvailableLocales();
+    }
+
+    /**
+     * This static method calls formatFraction() on a default instance of
+     * FractionFormat.
+     *
+     * @param f Fraction object to format
+     * @return A formatted fraction in proper form.
+     */
+    public static String formatFraction(Fraction f) {
+        return getImproperInstance().format(f);
+    }
+
+    /**
+     * Returns the default complex format for the current locale.
+     * @return the default complex format.
+     */
+    public static FractionFormat getImproperInstance() {
+        return getImproperInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns the default complex format for the given locale.
+     * @param locale the specific locale used by the format.
+     * @return the complex format specific to the given locale.
+     */
+    public static FractionFormat getImproperInstance(final Locale locale) {
+        return new FractionFormat(getDefaultNumberFormat(locale));
+    }
+
+    /**
+     * Returns the default complex format for the current locale.
+     * @return the default complex format.
+     */
+    public static FractionFormat getProperInstance() {
+        return getProperInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns the default complex format for the given locale.
+     * @param locale the specific locale used by the format.
+     * @return the complex format specific to the given locale.
+     */
+    public static FractionFormat getProperInstance(final Locale locale) {
+        return new ProperFractionFormat(getDefaultNumberFormat(locale));
+    }
+
+    /**
+     * Create a default number format.  The default number format is based on
+     * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
+     * customizing is the maximum number of fraction digits, which is set to 0.
+     * @return the default number format.
+     */
+    protected static NumberFormat getDefaultNumberFormat() {
+        return getDefaultNumberFormat(Locale.getDefault());
+    }
+
+    /**
+     * Formats a {@link Fraction} object to produce a string.  The fraction is
+     * output in improper format.
+     *
+     * @param fraction 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(final Fraction fraction,
+                               final StringBuffer toAppendTo, final FieldPosition pos) {
+
+        pos.setBeginIndex(0);
+        pos.setEndIndex(0);
+
+        getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos);
+        toAppendTo.append(" / ");
+        getDenominatorFormat().format(fraction.getDenominator(), toAppendTo,
+            pos);
+
+        return toAppendTo;
+    }
+
+    /**
+     * Formats an object and appends the result to a StringBuffer. <code>obj</code> must be either a
+     * {@link Fraction} object or a {@link Number} 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 <code>obj</code> is not a valid type.
+     */
+    @Override
+    public StringBuffer format(final Object obj,
+                               final StringBuffer toAppendTo, final FieldPosition pos) {
+        StringBuffer ret = null;
+
+        if (obj instanceof Fraction) {
+            ret = format((Fraction) obj, toAppendTo, pos);
+        } else if (obj instanceof Number) {
+            try {
+                ret = format(new Fraction(((Number) obj).doubleValue()),
+                             toAppendTo, pos);
+            } catch (ConvergenceException ex) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.CANNOT_CONVERT_OBJECT_TO_FRACTION,
+                    ex.getLocalizedMessage());
+            }
+        } else {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.CANNOT_FORMAT_OBJECT_TO_FRACTION);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Parses a string to produce a {@link Fraction} object.
+     * @param source the string to parse
+     * @return the parsed {@link Fraction} object.
+     * @exception ParseException if the beginning of the specified string
+     *            cannot be parsed.
+     */
+    @Override
+    public Fraction parse(final String source) throws ParseException {
+        final ParsePosition parsePosition = new ParsePosition(0);
+        final Fraction result = parse(source, parsePosition);
+        if (parsePosition.getIndex() == 0) {
+            throw MathRuntimeException.createParseException(
+                    parsePosition.getErrorIndex(),
+                    LocalizedFormats.UNPARSEABLE_FRACTION_NUMBER, source);
+        }
+        return result;
+    }
+
+    /**
+     * Parses a string to produce a {@link Fraction} object.  This method
+     * expects the string to be formatted as an improper fraction.
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed {@link Fraction} object.
+     */
+    @Override
+    public Fraction parse(final String source, final ParsePosition pos) {
+        final int initialIndex = pos.getIndex();
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse numerator
+        final Number num = getNumeratorFormat().parse(source, pos);
+        if (num == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse '/'
+        final int startIndex = pos.getIndex();
+        final char c = parseNextCharacter(source, pos);
+        switch (c) {
+        case 0 :
+            // no '/'
+            // return num as a fraction
+            return new Fraction(num.intValue(), 1);
+        case '/' :
+            // found '/', continue parsing denominator
+            break;
+        default :
+            // invalid '/'
+            // set index back to initial, error index should be the last
+            // character examined.
+            pos.setIndex(initialIndex);
+            pos.setErrorIndex(startIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse denominator
+        final Number den = getDenominatorFormat().parse(source, pos);
+        if (den == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        return new Fraction(num.intValue(), den.intValue());
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/ProperBigFractionFormat.java b/src/main/java/org/apache/commons/math/fraction/ProperBigFractionFormat.java
new file mode 100644
index 0000000..398f565
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/ProperBigFractionFormat.java
@@ -0,0 +1,239 @@
+/*
+ * 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.fraction;
+
+import java.math.BigInteger;
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * Formats a BigFraction number in proper format.  The number format for each of
+ * the whole number, numerator and, denominator can be configured.
+ * <p>
+ * Minus signs are only allowed in the whole number part - i.e.,
+ * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
+ * will result in a <code>ParseException</code>.</p>
+ *
+ * @since 1.1
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class ProperBigFractionFormat extends BigFractionFormat {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -6337346779577272307L;
+
+    /** The format used for the whole number. */
+    private NumberFormat wholeFormat;
+
+    /**
+     * Create a proper formatting instance with the default number format for
+     * the whole, numerator, and denominator.
+     */
+    public ProperBigFractionFormat() {
+        this(getDefaultNumberFormat());
+    }
+
+    /**
+     * Create a proper formatting instance with a custom number format for the
+     * whole, numerator, and denominator.
+     * @param format the custom format for the whole, numerator, and
+     *        denominator.
+     */
+    public ProperBigFractionFormat(final NumberFormat format) {
+        this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone());
+    }
+
+    /**
+     * Create a proper formatting instance with a custom number format for each
+     * of the whole, numerator, and denominator.
+     * @param wholeFormat the custom format for the whole.
+     * @param numeratorFormat the custom format for the numerator.
+     * @param denominatorFormat the custom format for the denominator.
+     */
+    public ProperBigFractionFormat(final NumberFormat wholeFormat,
+                                   final NumberFormat numeratorFormat,
+                                   final NumberFormat denominatorFormat) {
+        super(numeratorFormat, denominatorFormat);
+        setWholeFormat(wholeFormat);
+    }
+
+    /**
+     * Formats a {@link BigFraction} object to produce a string.  The BigFraction
+     * is output in proper format.
+     *
+     * @param fraction 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.
+     */
+    @Override
+    public StringBuffer format(final BigFraction fraction,
+                               final StringBuffer toAppendTo, final FieldPosition pos) {
+
+        pos.setBeginIndex(0);
+        pos.setEndIndex(0);
+
+        BigInteger num = fraction.getNumerator();
+        BigInteger den = fraction.getDenominator();
+        BigInteger whole = num.divide(den);
+        num = num.remainder(den);
+
+        if (!BigInteger.ZERO.equals(whole)) {
+            getWholeFormat().format(whole, toAppendTo, pos);
+            toAppendTo.append(' ');
+            if (num.compareTo(BigInteger.ZERO) < 0) {
+                num = num.negate();
+            }
+        }
+        getNumeratorFormat().format(num, toAppendTo, pos);
+        toAppendTo.append(" / ");
+        getDenominatorFormat().format(den, toAppendTo, pos);
+
+        return toAppendTo;
+    }
+
+    /**
+     * Access the whole format.
+     * @return the whole format.
+     */
+    public NumberFormat getWholeFormat() {
+        return wholeFormat;
+    }
+
+    /**
+     * Parses a string to produce a {@link BigFraction} object.  This method
+     * expects the string to be formatted as a proper BigFraction.
+     * <p>
+     * Minus signs are only allowed in the whole number part - i.e.,
+     * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
+     * will result in a <code>ParseException</code>.</p>
+     *
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed {@link BigFraction} object.
+     */
+    @Override
+    public BigFraction parse(final String source, final ParsePosition pos) {
+        // try to parse improper BigFraction
+        BigFraction ret = super.parse(source, pos);
+        if (ret != null) {
+            return ret;
+        }
+
+        final int initialIndex = pos.getIndex();
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse whole
+        BigInteger whole = parseNextBigInteger(source, pos);
+        if (whole == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse numerator
+        BigInteger num = parseNextBigInteger(source, pos);
+        if (num == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        if (num.compareTo(BigInteger.ZERO) < 0) {
+            // minus signs should be leading, invalid expression
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse '/'
+        final int startIndex = pos.getIndex();
+        final char c = parseNextCharacter(source, pos);
+        switch (c) {
+        case 0 :
+            // no '/'
+            // return num as a BigFraction
+            return new BigFraction(num);
+        case '/' :
+            // found '/', continue parsing denominator
+            break;
+        default :
+            // invalid '/'
+            // set index back to initial, error index should be the last
+            // character examined.
+            pos.setIndex(initialIndex);
+            pos.setErrorIndex(startIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse denominator
+        final BigInteger den = parseNextBigInteger(source, pos);
+        if (den == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        if (den.compareTo(BigInteger.ZERO) < 0) {
+            // minus signs must be leading, invalid
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        boolean wholeIsNeg = whole.compareTo(BigInteger.ZERO) < 0;
+        if (wholeIsNeg) {
+            whole = whole.negate();
+        }
+        num = whole.multiply(den).add(num);
+        if (wholeIsNeg) {
+            num = num.negate();
+        }
+
+        return new BigFraction(num, den);
+
+    }
+
+    /**
+     * Modify the whole format.
+     * @param format The new whole format value.
+     * @throws NullArgumentException if {@code format} is {@code null}.
+     */
+    public void setWholeFormat(final NumberFormat format) {
+        if (format == null) {
+            throw new NullArgumentException(LocalizedFormats.WHOLE_FORMAT);
+        }
+        this.wholeFormat = format;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/ProperFractionFormat.java b/src/main/java/org/apache/commons/math/fraction/ProperFractionFormat.java
new file mode 100644
index 0000000..a70925d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/ProperFractionFormat.java
@@ -0,0 +1,232 @@
+/*
+ * 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.fraction;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Formats a Fraction number in proper format.  The number format for each of
+ * the whole number, numerator and, denominator can be configured.
+ * <p>
+ * Minus signs are only allowed in the whole number part - i.e.,
+ * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
+ * will result in a <code>ParseException</code>.</p>
+ *
+ * @since 1.1
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class ProperFractionFormat extends FractionFormat {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 760934726031766749L;
+
+    /** The format used for the whole number. */
+    private NumberFormat wholeFormat;
+
+    /**
+     * Create a proper formatting instance with the default number format for
+     * the whole, numerator, and denominator.
+     */
+    public ProperFractionFormat() {
+        this(getDefaultNumberFormat());
+    }
+
+    /**
+     * Create a proper formatting instance with a custom number format for the
+     * whole, numerator, and denominator.
+     * @param format the custom format for the whole, numerator, and
+     *        denominator.
+     */
+    public ProperFractionFormat(NumberFormat format) {
+        this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone());
+    }
+
+    /**
+     * Create a proper formatting instance with a custom number format for each
+     * of the whole, numerator, and denominator.
+     * @param wholeFormat the custom format for the whole.
+     * @param numeratorFormat the custom format for the numerator.
+     * @param denominatorFormat the custom format for the denominator.
+     */
+    public ProperFractionFormat(NumberFormat wholeFormat,
+            NumberFormat numeratorFormat,
+            NumberFormat denominatorFormat)
+    {
+        super(numeratorFormat, denominatorFormat);
+        setWholeFormat(wholeFormat);
+    }
+
+    /**
+     * Formats a {@link Fraction} object to produce a string.  The fraction
+     * is output in proper format.
+     *
+     * @param fraction 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.
+     */
+    @Override
+    public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
+            FieldPosition pos) {
+
+        pos.setBeginIndex(0);
+        pos.setEndIndex(0);
+
+        int num = fraction.getNumerator();
+        int den = fraction.getDenominator();
+        int whole = num / den;
+        num = num % den;
+
+        if (whole != 0) {
+            getWholeFormat().format(whole, toAppendTo, pos);
+            toAppendTo.append(' ');
+            num = Math.abs(num);
+        }
+        getNumeratorFormat().format(num, toAppendTo, pos);
+        toAppendTo.append(" / ");
+        getDenominatorFormat().format(den, toAppendTo,
+            pos);
+
+        return toAppendTo;
+    }
+
+    /**
+     * Access the whole format.
+     * @return the whole format.
+     */
+    public NumberFormat getWholeFormat() {
+        return wholeFormat;
+    }
+
+    /**
+     * Parses a string to produce a {@link Fraction} object.  This method
+     * expects the string to be formatted as a proper fraction.
+     * <p>
+     * Minus signs are only allowed in the whole number part - i.e.,
+     * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
+     * will result in a <code>ParseException</code>.</p>
+     *
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed {@link Fraction} object.
+     */
+    @Override
+    public Fraction parse(String source, ParsePosition pos) {
+        // try to parse improper fraction
+        Fraction ret = super.parse(source, pos);
+        if (ret != null) {
+            return ret;
+        }
+
+        int initialIndex = pos.getIndex();
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse whole
+        Number whole = getWholeFormat().parse(source, pos);
+        if (whole == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse numerator
+        Number num = getNumeratorFormat().parse(source, pos);
+        if (num == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        if (num.intValue() < 0) {
+            // minus signs should be leading, invalid expression
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse '/'
+        int startIndex = pos.getIndex();
+        char c = parseNextCharacter(source, pos);
+        switch (c) {
+        case 0 :
+            // no '/'
+            // return num as a fraction
+            return new Fraction(num.intValue(), 1);
+        case '/' :
+            // found '/', continue parsing denominator
+            break;
+        default :
+            // invalid '/'
+            // set index back to initial, error index should be the last
+            // character examined.
+            pos.setIndex(initialIndex);
+            pos.setErrorIndex(startIndex);
+            return null;
+        }
+
+        // parse whitespace
+        parseAndIgnoreWhitespace(source, pos);
+
+        // parse denominator
+        Number den = getDenominatorFormat().parse(source, pos);
+        if (den == null) {
+            // invalid integer number
+            // set index back to initial, error index should already be set
+            // character examined.
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        if (den.intValue() < 0) {
+            // minus signs must be leading, invalid
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        int w = whole.intValue();
+        int n = num.intValue();
+        int d = den.intValue();
+        return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d);
+    }
+
+    /**
+     * Modify the whole format.
+     * @param format The new whole format value.
+     * @throws NullArgumentException if {@code format} is {@code null}.
+     */
+    public void setWholeFormat(NumberFormat format) {
+        if (format == null) {
+            throw new NullArgumentException(LocalizedFormats.WHOLE_FORMAT);
+        }
+        this.wholeFormat = format;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/fraction/package.html b/src/main/java/org/apache/commons/math/fraction/package.html
new file mode 100644
index 0000000..201ae20
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/fraction/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+  <body>
+    Fraction number type and fraction number formatting.
+  </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/genetics/AbstractListChromosome.java b/src/main/java/org/apache/commons/math/genetics/AbstractListChromosome.java
new file mode 100644
index 0000000..c618dff
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/AbstractListChromosome.java
@@ -0,0 +1,104 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Chromosome represented by an immutable list of a fixed length.
+ *
+ * @param <T> type of the representation list
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public abstract class AbstractListChromosome<T> extends Chromosome {
+
+    /** List representing the chromosome */
+    private final List<T> representation;
+
+    /**
+     * Constructor.
+     * @param representation inner representation of the chromosome
+     */
+    public AbstractListChromosome(final List<T> representation) {
+        try {
+            checkValidity(representation);
+        } catch (InvalidRepresentationException e) {
+            throw new IllegalArgumentException(String.format("Invalid representation for %s", getClass().getSimpleName()), e);
+        }
+        this.representation = Collections.unmodifiableList(new ArrayList<T> (representation));
+    }
+
+    /**
+     * Constructor.
+     * @param representation inner representation of the chromosome
+     */
+    public AbstractListChromosome(final T[] representation) {
+        this(Arrays.asList(representation));
+    }
+
+    /**
+     *
+     * Asserts that <code>representation</code> can represent a valid chromosome.
+     * @param chromosomeRepresentation representation of the chromosome
+     * @throws InvalidRepresentationException iff the <code>representation</code> can not represent
+     *         a valid chromosome
+     */
+    protected abstract void checkValidity(List<T> chromosomeRepresentation) throws InvalidRepresentationException;
+
+    /**
+     * Returns the (immutable) inner representation of the chromosome.
+     * @return the representation of the chromosome
+     */
+    protected List<T> getRepresentation() {
+        return representation;
+    }
+
+    /**
+     * Returns the length of the chromosome.
+     * @return the length of the chromosome
+     */
+    public int getLength() {
+        return getRepresentation().size();
+    }
+
+    /**
+     * Creates a new instance of the same class as <code>this</code> is, with a
+     * given <code>arrayRepresentation</code>. This is needed in crossover and
+     * mutation operators, where we need a new instance of the same class, but
+     * with different array representation.
+     *
+     * Usually, this method just calls a constructor of the class.
+     *
+     * @param chromosomeRepresentation
+     *            the inner array representation of the new chromosome.
+     * @return new instance extended from FixedLengthChromosome with the given
+     *         arrayRepresentation
+     */
+    public abstract AbstractListChromosome<T> newFixedLengthChromosome(final List<T> chromosomeRepresentation);
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return String.format("(f=%s %s)", getFitness(), getRepresentation());
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/BinaryChromosome.java b/src/main/java/org/apache/commons/math/genetics/BinaryChromosome.java
new file mode 100644
index 0000000..19dab38
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/BinaryChromosome.java
@@ -0,0 +1,92 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Chromosome represented by a vector of 0s and 1s.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public abstract class BinaryChromosome extends AbstractListChromosome<Integer> {
+
+    /**
+     * Constructor.
+     * @param representation list of {0,1} values representing the chromosome
+     */
+    public BinaryChromosome(List<Integer> representation) {
+        super(representation);
+    }
+
+    /**
+     * Constructor.
+     * @param representation array of {0,1} values representing the chromosome
+     */
+    public BinaryChromosome(Integer[] representation) {
+        super(representation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void checkValidity(List<Integer> chromosomeRepresentation) throws InvalidRepresentationException {
+        for (int i : chromosomeRepresentation) {
+            if (i < 0 || i >1)
+                throw new InvalidRepresentationException("Elements can be only 0 or 1.");
+        }
+    }
+
+    /**
+     * Returns a representation of a random binary array of length <code>length</code>.
+     * @param length length of the array
+     * @return a random binary array of length <code>length</code>
+     */
+    public static List<Integer> randomBinaryRepresentation(int length) {
+        // random binary list
+        List<Integer> rList= new ArrayList<Integer> (length);
+        for (int j=0; j<length; j++) {
+            rList.add(GeneticAlgorithm.getRandomGenerator().nextInt(2));
+        }
+        return rList;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean isSame(Chromosome another) {
+        // type check
+        if (! (another instanceof BinaryChromosome))
+            return false;
+        BinaryChromosome anotherBc = (BinaryChromosome) another;
+        // size check
+        if (getLength() != anotherBc.getLength())
+            return false;
+
+        for (int i=0; i< getRepresentation().size(); i++) {
+            if (!(getRepresentation().get(i).equals(anotherBc.getRepresentation().get(i))))
+                return false;
+        }
+        // all is ok
+        return true;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/BinaryMutation.java b/src/main/java/org/apache/commons/math/genetics/BinaryMutation.java
new file mode 100644
index 0000000..f762f89
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/BinaryMutation.java
@@ -0,0 +1,52 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Mutation for {@link BinaryChromosome}s. Randomly changes one gene.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public class BinaryMutation implements MutationPolicy {
+
+    /**
+     * Mutate the given chromosome. Randomly changes one gene.
+     * @param original the original chromosome.
+     * @return the mutated chromomsome.
+     */
+    public Chromosome mutate(Chromosome original) {
+        if (!(original instanceof BinaryChromosome)) {
+            throw new IllegalArgumentException("Binary mutation works on BinaryChromosome only.");
+        }
+
+        BinaryChromosome origChrom = (BinaryChromosome) original;
+        List<Integer> newRepr = new ArrayList<Integer>(origChrom.getRepresentation());
+
+        // randomly select a gene
+        int geneIndex = GeneticAlgorithm.getRandomGenerator().nextInt(origChrom.getLength());
+        // and change it
+        newRepr.set(geneIndex, origChrom.getRepresentation().get(geneIndex) == 0 ? 1 : 0);
+
+        Chromosome newChrom = origChrom.newFixedLengthChromosome(newRepr);
+        return newChrom;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/Chromosome.java b/src/main/java/org/apache/commons/math/genetics/Chromosome.java
new file mode 100644
index 0000000..5641a5b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/Chromosome.java
@@ -0,0 +1,111 @@
+/*
+ * 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.genetics;
+
+/**
+ * Individual in a population. Chromosomes are compared based on their fitness.
+ *
+ * The chromosomes are IMMUTABLE, and so their fitness is also immutable and
+ * therefore it can be cached.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public abstract class Chromosome implements Comparable<Chromosome>,Fitness {
+
+    /**
+     * Cached value of the fitness of this chromosome.
+     */
+    private double fitness = Double.MIN_VALUE;
+
+    /**
+     * Access the fitness of this chromosome. The bigger the fitness, the better
+     * the chromosome.
+     *
+     * Computation of fitness is usually very time-consuming task, therefore the
+     * fitness is cached.
+     *
+     * @return the fitness.
+     */
+    public double getFitness() {
+        if (this.fitness == Double.MIN_VALUE) {
+            // no cache - compute the fitness
+            this.fitness = fitness();
+        }
+        return this.fitness;
+    }
+
+    /**
+     * Compares two chromosomes based on their fitness. The bigger the fitness,
+     * the better the chromosome.
+     *
+     * @param another another chromosome to compare
+     * @return
+     * <ul>
+     *     <li>-1 if <code>another</code> is better than <code>this</code></li>
+     *     <li>1 if <code>another</code> is worse than <code>this</code></li>
+     *     <li>0 if the two chromosomes have the same fitness</li>
+     * </ul>
+     */
+    public int compareTo(Chromosome another) {
+        return ((Double)this.getFitness()).compareTo(another.getFitness());
+    }
+
+    /**
+     * Returns <code>true<code> iff <code>another</code> has the same
+     * representation and therefore the same fitness. By default, it returns
+     * false -- override it in your implementation if you need it.
+     * @param another chromosome to compare
+     * @return true if <code>another</code> is equivalent to this chromosome
+     */
+    protected boolean isSame(Chromosome another) {
+        return false;
+    }
+
+    /**
+     * Searches the <code>population</code> for another chromosome with the same
+     * representation. If such chromosome is found, it is returned, if no such
+     * chromosome exists, returns <code>null</code>.
+     *
+     * @param population
+     *            Population to search
+     * @return Chromosome with the same representation, or <code>null</code> if
+     *         no such chromosome exists.
+     */
+    protected Chromosome findSameChromosome(Population population) {
+        for (Chromosome anotherChr : population) {
+            if (this.isSame(anotherChr))
+                return anotherChr;
+        }
+        return null;
+    }
+
+    /**
+     * Searches the population for a chromosome representing the same solution,
+     * and if it finds one, updates the fitness to its value.
+     *
+     * @param population
+     *            Population to search
+     */
+    public void searchForFitnessUpdate(Population population) {
+        Chromosome sameChromosome = findSameChromosome(population);
+        if (sameChromosome != null) {
+            fitness = sameChromosome.getFitness();
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/ChromosomePair.java b/src/main/java/org/apache/commons/math/genetics/ChromosomePair.java
new file mode 100644
index 0000000..82b048f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/ChromosomePair.java
@@ -0,0 +1,69 @@
+/*
+ * 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.genetics;
+
+/**
+ * A pair of {@link Chromosome} objects.
+ * @since 2.0
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class ChromosomePair {
+    /** the first chromosome in the pair. */
+    private final Chromosome first;
+
+    /** the second chromosome in the pair. */
+    private final Chromosome second;
+
+    /**
+     * Create a chromosome pair.
+     *
+     * @param c1 the first chromosome.
+     * @param c2 the second chromosome.
+     */
+    public ChromosomePair(final Chromosome c1, final Chromosome c2) {
+        super();
+        first = c1;
+        second = c2;
+    }
+
+    /**
+     * Access the first chromosome.
+     *
+     * @return the first chromosome.
+     */
+    public Chromosome getFirst() {
+        return first;
+    }
+
+    /**
+     * Access the second chromosome.
+     *
+     * @return the second chromosome.
+     */
+    public Chromosome getSecond() {
+        return second;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return String.format("(%s,%s)", getFirst(), getSecond());
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/CrossoverPolicy.java b/src/main/java/org/apache/commons/math/genetics/CrossoverPolicy.java
new file mode 100644
index 0000000..8742dac
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/CrossoverPolicy.java
@@ -0,0 +1,35 @@
+/*
+ * 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.genetics;
+
+/**
+ * Policy used to create a pair of new chromosomes by performing a crossover
+ * operation on a source pair of chromosomes.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface CrossoverPolicy {
+    /**
+     * Perform a crossover operation on the given chromosomes.
+     *
+     * @param first the first chromosome.
+     * @param second the second chromosome.
+     * @return the pair of new chromosomes that resulted from the crossover.
+     */
+    ChromosomePair crossover(Chromosome first, Chromosome second);
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/ElitisticListPopulation.java b/src/main/java/org/apache/commons/math/genetics/ElitisticListPopulation.java
new file mode 100644
index 0000000..045632a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/ElitisticListPopulation.java
@@ -0,0 +1,110 @@
+/*
+ * 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.genetics;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Population of chromosomes which uses elitism (certain percentace of the best
+ * chromosomes is directly copied to the next generation).
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class ElitisticListPopulation extends ListPopulation {
+
+    /** percentage of chromosomes copied to the next generation */
+    private double elitismRate = 0.9;
+
+    /**
+     * Creates a new ElitisticListPopulation instance.
+     *
+     * @param chromosomes
+     *            list of chromosomes in the population
+     * @param populationLimit
+     *            maximal size of the population
+     * @param elitismRate
+     *            how many best chromosomes will be directly transferred to the
+     *            next generation [in %]
+     */
+    public ElitisticListPopulation(List<Chromosome> chromosomes, int populationLimit, double elitismRate) {
+        super(chromosomes, populationLimit);
+        this.elitismRate = elitismRate;
+    }
+
+    /**
+     * Creates a new ListPopulation instance and initializes its inner
+     * chromosome list.
+     *
+     * @param populationLimit maximal size of the population
+     * @param elitismRate
+     *            how many best chromosomes will be directly transferred to the
+     *            next generation [in %]
+     */
+    public ElitisticListPopulation(int populationLimit, double elitismRate) {
+        super(populationLimit);
+        this.elitismRate = elitismRate;
+    }
+
+    /**
+     * Start the population for the next generation. The
+     * <code>{@link #elitismRate}<code> percents of the best
+     * chromosomes are directly copied to the next generation.
+     *
+     * @return the beginnings of the next generation.
+     */
+    public Population nextGeneration() {
+        // initialize a new generation with the same parameters
+        ElitisticListPopulation nextGeneration = new ElitisticListPopulation(this.getPopulationLimit(), this.getElitismRate());
+
+        List<Chromosome> oldChromosomes = this.getChromosomes();
+        Collections.sort(oldChromosomes);
+
+        // index of the last "not good enough" chromosome
+        int boundIndex = (int) FastMath.ceil((1.0 - this.getElitismRate()) * oldChromosomes.size());
+        for (int i=boundIndex; i<oldChromosomes.size(); i++) {
+            nextGeneration.addChromosome(oldChromosomes.get(i));
+        }
+        return nextGeneration;
+    }
+
+    /**
+     * Sets the elitism rate, i.e. how many best chromosomes will be directly
+     * transferred to the next generation [in %].
+     *
+     * @param elitismRate
+     *            how many best chromosomes will be directly transferred to the
+     *            next generation [in %]
+     */
+    public void setElitismRate(double elitismRate) {
+        if (elitismRate < 0 || elitismRate > 1)
+            throw new IllegalArgumentException("Elitism rate has to be in [0,1]");
+        this.elitismRate = elitismRate;
+    }
+
+    /**
+     * Access the elitism rate.
+     * @return the elitism rate
+     */
+    public double getElitismRate() {
+        return this.elitismRate;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/Fitness.java b/src/main/java/org/apache/commons/math/genetics/Fitness.java
new file mode 100644
index 0000000..40d674c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/Fitness.java
@@ -0,0 +1,35 @@
+/*
+ * 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.genetics;
+
+/**
+ * Fitness of a chromosome.
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public interface Fitness {
+
+    /**
+     * Compute the fitness. This is usually very time-consuming, so the value
+     * should be cached.
+     *
+     * @return fitness
+     */
+    double fitness();
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/FixedGenerationCount.java b/src/main/java/org/apache/commons/math/genetics/FixedGenerationCount.java
new file mode 100644
index 0000000..337c5c0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/FixedGenerationCount.java
@@ -0,0 +1,70 @@
+/*
+ * 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.genetics;
+
+/**
+ * Stops after a fixed number of generations.  Each time
+ * {@link #isSatisfied(Population)} is invoked, a generation counter is
+ * incremented.  Once the counter reaches the configured
+ * <code>maxGenerations</code> value, {@link #isSatisfied(Population)} returns
+ * true.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public class FixedGenerationCount implements StoppingCondition {
+    /** Number of generations that have passed */
+    private int numGenerations = 0;
+
+    /** Maximum number of generations (stopping criteria) */
+    private final int maxGenerations;
+
+    /**
+     * Create a new FixedGenerationCount instance.
+     *
+     * @param maxGenerations number of generations to evolve
+     */
+    public FixedGenerationCount(int maxGenerations) {
+        if (maxGenerations <= 0)
+            throw new IllegalArgumentException("The number of generations has to be >= 0");
+        this.maxGenerations = maxGenerations;
+    }
+
+    /**
+     * Determine whether or not the given number of generations have passed.
+     * Increments the number of generations counter if the maximum has not
+     * been reached.
+     *
+     * @param population ignored (no impact on result)
+     * @return <code>true</code> IFF the maximum number of generations has been exceeded
+     */
+    public boolean isSatisfied(Population population) {
+        if (this.numGenerations < this.maxGenerations) {
+            numGenerations++;
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @return the number of generations that have passed
+     */
+    public int getNumGenerations() {
+        return numGenerations;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/GeneticAlgorithm.java b/src/main/java/org/apache/commons/math/genetics/GeneticAlgorithm.java
new file mode 100644
index 0000000..fc666ac
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/GeneticAlgorithm.java
@@ -0,0 +1,228 @@
+/*
+ * 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.genetics;
+
+import org.apache.commons.math.random.RandomGenerator;
+import org.apache.commons.math.random.JDKRandomGenerator;
+
+/**
+ * Implementation of a genetic algorithm. All factors that govern the operation
+ * of the algorithm can be configured for a specific problem.
+ *
+ * @since 2.0
+ * @version $Revision: 925812 $ $Date: 2010-03-21 16:49:31 +0100 (dim. 21 mars 2010) $
+ */
+public class GeneticAlgorithm {
+
+    /**
+     * Static random number generator shared by GA implementation classes.
+     * Set the randomGenerator seed to get reproducible results.
+     * Use {@link #setRandomGenerator(RandomGenerator)} to supply an alternative
+     * to the default JDK-provided PRNG.
+     */
+    //@GuardedBy("this")
+    private static RandomGenerator randomGenerator = new JDKRandomGenerator();
+
+    /** the crossover policy used by the algorithm. */
+    private final CrossoverPolicy crossoverPolicy;
+
+    /** the rate of crossover for the algorithm. */
+    private final double crossoverRate;
+
+    /** the mutation policy used by the algorithm. */
+    private final MutationPolicy mutationPolicy;
+
+    /** the rate of mutation for the algorithm. */
+    private final double mutationRate;
+
+    /** the selection policy used by the algorithm. */
+    private final SelectionPolicy selectionPolicy;
+
+    /** the number of generations evolved to reach {@link StoppingCondition} in the last run. */
+    private int generationsEvolved = 0;
+
+    /**
+     * @param crossoverPolicy The {@link CrossoverPolicy}
+     * @param crossoverRate The crossover rate as a percentage (0-1 inclusive)
+     * @param mutationPolicy The {@link MutationPolicy}
+     * @param mutationRate The mutation rate as a percentage (0-1 inclusive)
+     * @param selectionPolicy The {@link SelectionPolicy}
+     */
+    public GeneticAlgorithm(
+            CrossoverPolicy crossoverPolicy, double crossoverRate,
+            MutationPolicy mutationPolicy, double mutationRate,
+            SelectionPolicy selectionPolicy) {
+        if (crossoverRate < 0 || crossoverRate > 1) {
+            throw new IllegalArgumentException("crossoverRate must be between 0 and 1");
+        }
+        if (mutationRate < 0 || mutationRate > 1) {
+            throw new IllegalArgumentException("mutationRate must be between 0 and 1");
+        }
+        this.crossoverPolicy = crossoverPolicy;
+        this.crossoverRate = crossoverRate;
+        this.mutationPolicy = mutationPolicy;
+        this.mutationRate = mutationRate;
+        this.selectionPolicy = selectionPolicy;
+    }
+
+    /**
+     * Set the (static) random generator.
+     *
+     * @param random random generator
+     */
+    public static synchronized void setRandomGenerator(RandomGenerator random) {
+        randomGenerator = random;
+    }
+
+    /**
+     * Returns the (static) random generator.
+     *
+     * @return the static random generator shared by GA implementation classes
+     */
+    public static synchronized RandomGenerator getRandomGenerator() {
+        return randomGenerator;
+    }
+
+    /**
+     * Evolve the given population. Evolution stops when the stopping condition
+     * is satisfied. Updates the {@link #getGenerationsEvolved() generationsEvolved}
+     * property with the number of generations evolved before the StoppingCondition
+     * is satisfied.
+     *
+     * @param initial the initial, seed population.
+     * @param condition the stopping condition used to stop evolution.
+     * @return the population that satisfies the stopping condition.
+     */
+    public Population evolve(Population initial, StoppingCondition condition) {
+        Population current = initial;
+        generationsEvolved = 0;
+        while (!condition.isSatisfied(current)) {
+            current = nextGeneration(current);
+            generationsEvolved++;
+        }
+        return current;
+    }
+
+    /**
+     * <p>Evolve the given population into the next generation.</p>
+     * <p><ol>
+     *    <li>Get nextGeneration population to fill from <code>current</code>
+     *        generation, using its nextGeneration method</li>
+     *    <li>Loop until new generation is filled:</li>
+     *    <ul><li>Apply configured SelectionPolicy to select a pair of parents
+     *            from <code>current</code></li>
+     *        <li>With probability = {@link #getCrossoverRate()}, apply
+     *            configured {@link CrossoverPolicy} to parents</li>
+     *        <li>With probability = {@link #getMutationRate()}, apply
+     *            configured {@link MutationPolicy} to each of the offspring</li>
+     *        <li>Add offspring individually to nextGeneration,
+     *            space permitting</li>
+     *    </ul>
+     *    <li>Return nextGeneration</li>
+     *    </ol>
+     * </p>
+     *
+     * @param current the current population.
+     * @return the population for the next generation.
+     */
+    public Population nextGeneration(Population current) {
+        Population nextGeneration = current.nextGeneration();
+
+        RandomGenerator randGen = getRandomGenerator();
+
+        while (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) {
+            // select parent chromosomes
+            ChromosomePair pair = getSelectionPolicy().select(current);
+
+            // crossover?
+            if (randGen.nextDouble() < getCrossoverRate()) {
+                // apply crossover policy to create two offspring
+                pair = getCrossoverPolicy().crossover(pair.getFirst(), pair.getSecond());
+            }
+
+            // mutation?
+            if (randGen.nextDouble() < getMutationRate()) {
+                // apply mutation policy to the chromosomes
+                pair = new ChromosomePair(
+                    getMutationPolicy().mutate(pair.getFirst()),
+                    getMutationPolicy().mutate(pair.getSecond()));
+            }
+
+            // add the first chromosome to the population
+            nextGeneration.addChromosome(pair.getFirst());
+            // is there still a place for the second chromosome?
+            if (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) {
+                // add the second chromosome to the population
+                nextGeneration.addChromosome(pair.getSecond());
+            }
+        }
+
+        return nextGeneration;
+    }
+
+    /**
+     * Returns the crossover policy.
+     * @return crossover policy
+     */
+    public CrossoverPolicy getCrossoverPolicy() {
+        return crossoverPolicy;
+    }
+
+    /**
+     * Returns the crossover rate.
+     * @return crossover rate
+     */
+    public double getCrossoverRate() {
+        return crossoverRate;
+    }
+
+    /**
+     * Returns the mutation policy.
+     * @return mutation policy
+     */
+    public MutationPolicy getMutationPolicy() {
+        return mutationPolicy;
+    }
+
+    /**
+     * Returns the mutation rate.
+     * @return mutation rate
+     */
+    public double getMutationRate() {
+        return mutationRate;
+    }
+
+    /**
+     * Returns the selection policy.
+     * @return selection policy
+     */
+    public SelectionPolicy getSelectionPolicy() {
+        return selectionPolicy;
+    }
+
+    /**
+     * Returns the number of generations evolved to
+     * reach {@link StoppingCondition} in the last run.
+     *
+     * @return number of generations evolved
+     * @since 2.1
+     */
+    public int getGenerationsEvolved() {
+        return generationsEvolved;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/InvalidRepresentationException.java b/src/main/java/org/apache/commons/math/genetics/InvalidRepresentationException.java
new file mode 100644
index 0000000..b60ded8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/InvalidRepresentationException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.genetics;
+
+/**
+ * Exception indicating that the representation of a chromosome is not valid.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public class InvalidRepresentationException extends Exception {
+
+    /** Serialization version id */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor
+     */
+    public InvalidRepresentationException() {
+        super();
+    }
+
+    /**
+     * Construct an InvalidRepresentationException
+     * @param arg0 exception message
+     */
+    public InvalidRepresentationException(String arg0) {
+        super(arg0);
+    }
+
+    /**
+     * Construct an InvalidRepresentationException
+     * @param arg0 cause
+     */
+    public InvalidRepresentationException(Throwable arg0) {
+        super(arg0);
+    }
+
+    /**
+     * Construct an InvalidRepresentationException
+     *
+     * @param arg0 exception message
+     * @param arg1 cause
+     */
+    public InvalidRepresentationException(String arg0, Throwable arg1) {
+        super(arg0, arg1);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/ListPopulation.java b/src/main/java/org/apache/commons/math/genetics/ListPopulation.java
new file mode 100644
index 0000000..e880b2c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/ListPopulation.java
@@ -0,0 +1,155 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NotPositiveException;
+import org.apache.commons.math.exception.NumberIsTooLargeException;
+
+/**
+ * Population of chromosomes represented by a {@link List}.
+ *
+ * @since 2.0
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public abstract class ListPopulation implements Population {
+
+    /** List of chromosomes */
+    private List<Chromosome> chromosomes;
+
+    /** maximial size of the population */
+    private int populationLimit;
+
+
+    /**
+     * Creates a new ListPopulation instance.
+     *
+     * @param chromosomes list of chromosomes in the population
+     * @param populationLimit maximal size of the population
+     */
+    public ListPopulation (List<Chromosome> chromosomes, int populationLimit) {
+        if (chromosomes.size() > populationLimit) {
+            throw new NumberIsTooLargeException(LocalizedFormats.LIST_OF_CHROMOSOMES_BIGGER_THAN_POPULATION_SIZE,
+                                                chromosomes.size(), populationLimit, false);
+        }
+        if (populationLimit < 0) {
+            throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit);
+        }
+
+        this.chromosomes = chromosomes;
+        this.populationLimit = populationLimit;
+    }
+
+    /**
+     * Creates a new ListPopulation instance and initializes its inner
+     * chromosome list.
+     *
+     * @param populationLimit maximal size of the population
+     */
+    public ListPopulation (int populationLimit) {
+        if (populationLimit < 0) {
+            throw new NotPositiveException(LocalizedFormats.POPULATION_LIMIT_NOT_POSITIVE, populationLimit);
+        }
+        this.populationLimit = populationLimit;
+        this.chromosomes = new ArrayList<Chromosome>(populationLimit);
+    }
+
+    /**
+     * Sets the list of chromosomes.
+     * @param chromosomes the list of chromosomes
+     */
+    public void setChromosomes(List<Chromosome> chromosomes) {
+        this.chromosomes = chromosomes;
+    }
+
+    /**
+     * Access the list of chromosomes.
+     * @return the list of chromosomes
+     */
+    public List<Chromosome> getChromosomes() {
+        return chromosomes;
+    }
+
+    /**
+     * Add the given chromosome to the population.
+     * @param chromosome the chromosome to add.
+     */
+    public void addChromosome(Chromosome chromosome) {
+        this.chromosomes.add(chromosome);
+    }
+
+    /**
+     * Access the fittest chromosome in this population.
+     * @return the fittest chromosome.
+     */
+    public Chromosome getFittestChromosome() {
+        // best so far
+        Chromosome bestChromosome = this.chromosomes.get(0);
+        for (Chromosome chromosome : this.chromosomes) {
+            if (chromosome.compareTo(bestChromosome) > 0) {
+                // better chromosome found
+                bestChromosome = chromosome;
+            }
+        }
+        return bestChromosome;
+    }
+
+    /**
+     * Access the maximum population size.
+     * @return the maximum population size.
+     */
+    public int getPopulationLimit() {
+        return this.populationLimit;
+    }
+
+    /**
+     * Sets the maximal population size.
+     * @param populationLimit maximal population size.
+     */
+    public void setPopulationLimit(int populationLimit) {
+        this.populationLimit = populationLimit;
+    }
+
+    /**
+     * Access the current population size.
+     * @return the current population size.
+     */
+    public int getPopulationSize() {
+        return this.chromosomes.size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return this.chromosomes.toString();
+    }
+
+    /**
+     * Chromosome list iterator
+     *
+     * @return chromosome iterator
+     */
+    public Iterator<Chromosome> iterator() {
+        return chromosomes.iterator();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/MutationPolicy.java b/src/main/java/org/apache/commons/math/genetics/MutationPolicy.java
new file mode 100644
index 0000000..9753db7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/MutationPolicy.java
@@ -0,0 +1,33 @@
+/*
+ * 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.genetics;
+
+/**
+ * Algorithm used to mutate a chrommosome.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface MutationPolicy {
+
+    /**
+     * Mutate the given chromosome.
+     * @param original the original chromosome.
+     * @return the mutated chromomsome.
+     */
+    Chromosome mutate(Chromosome original);
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/OnePointCrossover.java b/src/main/java/org/apache/commons/math/genetics/OnePointCrossover.java
new file mode 100644
index 0000000..f5f6ffd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/OnePointCrossover.java
@@ -0,0 +1,117 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * One point crossover policy. A random crossover point is selected and the
+ * first part from each parent is copied to the corresponding child, and the
+ * second parts are copied crosswise.
+ *
+ * Example:
+ * <pre>
+ * -C- denotes a crossover point
+ *                   -C-                                -C-
+ * p1 = (1 0 1 0 0 1  | 0 1 1)    X    p2 = (0 1 1 0 1 0  | 1 1 1)
+ *         \------------/ \-----/              \------------/ \-----/
+ *            ||         (*)                       ||        (**)
+ *            VV         (**)                      VV        (*)
+ *      /------------\ /-----\              /------------\ /-----\
+ * c1 = (1 0 1 0 0 1  | 1 1 1)    X    p2 = (0 1 1 0 1 0  | 0 1 1)
+ * </pre>
+ *
+ * This policy works only on {@link AbstractListChromosome}, and therefore it
+ * is parametrized by T. Moreover, the chromosomes must have same lengths.
+ *
+ * @param <T> generic type of the {@link AbstractListChromosome}s for crossover
+ * @since 2.0
+ * @version $Revision: 903046 $ $Date: 2010-01-26 03:07:26 +0100 (mar. 26 janv. 2010) $
+ *
+ */
+public class OnePointCrossover<T> implements CrossoverPolicy {
+
+    /**
+     * Performs one point crossover. A random crossover point is selected and the
+     * first part from each parent is copied to the corresponding child, and the
+     * second parts are copied crosswise.
+     *
+     * Example:
+     * -C- denotes a crossover point
+     *                   -C-                                -C-
+     * p1 = (1 0 1 0 0 1  | 0 1 1)    X    p2 = (0 1 1 0 1 0  | 1 1 1)
+     *         \------------/ \-----/              \------------/ \-----/
+     *            ||         (*)                       ||        (**)
+     *            VV         (**)                      VV        (*)
+     *      /------------\ /-----\              /------------\ /-----\
+     * c1 = (1 0 1 0 0 1  | 1 1 1)    X    p2 = (0 1 1 0 1 0  | 0 1 1)
+     *
+     * @param first first parent (p1)
+     * @param second second parent (p2)
+     * @return pair of two children (c1,c2)
+     */
+    @SuppressWarnings("unchecked") // OK because of instanceof checks
+    public ChromosomePair crossover(Chromosome first, Chromosome second) {
+        if (! (first instanceof AbstractListChromosome<?> && second instanceof AbstractListChromosome<?>)) {
+            throw new IllegalArgumentException("One point crossover works on FixedLengthChromosomes only.");
+        }
+        return crossover((AbstractListChromosome<T>) first, (AbstractListChromosome<T>) second);
+    }
+
+
+    /**
+     * Helper for {@link #crossover(Chromosome, Chromosome)}. Performs the actual crossover.
+     *
+     * @param first the first chromosome.
+     * @param second the second chromosome.
+     * @return the pair of new chromosomes that resulted from the crossover.
+     */
+    private ChromosomePair crossover(AbstractListChromosome<T> first, AbstractListChromosome<T> second) {
+        int length = first.getLength();
+        if (length != second.getLength())
+            throw new IllegalArgumentException("Both chromosomes must have same lengths.");
+
+        // array representations of the parents
+        List<T> parent1Rep = first.getRepresentation();
+        List<T> parent2Rep = second.getRepresentation();
+        // and of the children
+        ArrayList<T> child1Rep = new ArrayList<T> (first.getLength());
+        ArrayList<T> child2Rep = new ArrayList<T> (second.getLength());
+
+        // select a crossover point at random (0 and length makes no sense)
+        int crossoverIndex = 1 + (GeneticAlgorithm.getRandomGenerator().nextInt(length-2));
+
+        // copy the first part
+        for (int i = 0; i < crossoverIndex; i++) {
+            child1Rep.add(parent1Rep.get(i));
+            child2Rep.add(parent2Rep.get(i));
+        }
+        // and switch the second part
+        for (int i = crossoverIndex; i < length; i++) {
+            child1Rep.add(parent2Rep.get(i));
+            child2Rep.add(parent1Rep.get(i));
+        }
+
+        return new ChromosomePair(
+                first.newFixedLengthChromosome(child1Rep),
+                second.newFixedLengthChromosome(child2Rep)
+                );
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/PermutationChromosome.java b/src/main/java/org/apache/commons/math/genetics/PermutationChromosome.java
new file mode 100644
index 0000000..676b5dc
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/PermutationChromosome.java
@@ -0,0 +1,44 @@
+/*
+ * 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.genetics;
+
+import java.util.List;
+
+/**
+ * Interface indicating that the chromosome represents a permutation of objects.
+ *
+ * @param <T>
+ *            type of the permuted objects
+ * @since 2.0
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ */
+public interface PermutationChromosome<T> {
+
+    /**
+     * Permutes the <code>sequence</code> of objects of type T according to the
+     * permutation this chromosome represents. For example, if this chromosome
+     * represents a permutation (3,0,1,2), and the unpermuted sequence is
+     * (a,b,c,d), this yields (d,a,b,c).
+     *
+     * @param sequence
+     *            the unpermuted (original) sequence of objects
+     * @return permutation of <code>sequence</code> represented by this
+     *         permutation
+     */
+    List<T> decode(List<T> sequence);
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/Population.java b/src/main/java/org/apache/commons/math/genetics/Population.java
new file mode 100644
index 0000000..3fc758a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/Population.java
@@ -0,0 +1,55 @@
+/*
+ * 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.genetics;
+
+/**
+ * A collection of chromosomes that facilitates generational evolution.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface Population extends Iterable<Chromosome> {
+    /**
+     * Access the current population size.
+     * @return the current population size.
+     */
+    int getPopulationSize();
+
+    /**
+     * Access the maximum population size.
+     * @return the maximum population size.
+     */
+    int getPopulationLimit();
+
+    /**
+     * Start the population for the next generation.
+     * @return the beginnings of the next generation.
+     */
+    Population nextGeneration();
+
+    /**
+     * Add the given chromosome to the population.
+     * @param chromosome the chromosome to add.
+     */
+    void addChromosome(Chromosome chromosome);
+
+    /**
+     * Access the fittest chromosome in this population.
+     * @return the fittest chromosome.
+     */
+    Chromosome getFittestChromosome();
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/RandomKey.java b/src/main/java/org/apache/commons/math/genetics/RandomKey.java
new file mode 100644
index 0000000..1cd28d3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/RandomKey.java
@@ -0,0 +1,290 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * <p>
+ * Random Key chromosome is used for permutation representation. It is a vector
+ * of a fixed length of real numbers in [0,1] interval. The index of the i-th
+ * smallest value in the vector represents an i-th member of the permutation.
+ * </p>
+ *
+ * <p>
+ * For example, the random key [0.2, 0.3, 0.8, 0.1] corresponds to the
+ * permutation of indices (3,0,1,2). If the original (unpermuted) sequence would
+ * be (a,b,c,d), this would mean the sequence (d,a,b,c).
+ * </p>
+ *
+ * <p>
+ * With this representation, common operators like n-point crossover can be
+ * used, because any such chromosome represents a valid permutation.
+ * </p>
+ *
+ * <p>
+ * Since the chromosome (and thus its arrayRepresentation) is immutable, the
+ * array representation is sorted only once in the constructor.
+ * </p>
+ *
+ * <p>
+ * For details, see:
+ * <ul>
+ * <li>Bean, J.C.: Genetic algorithms and random keys for sequencing and
+ * optimization. ORSA Journal on Computing 6 (1994) 154–160</li>
+ * <li>Rothlauf, F.: Representations for Genetic and Evolutionary Algorithms.
+ * Volume 104 of Studies in Fuzziness and Soft Computing. Physica-Verlag,
+ * Heidelberg (2002)</li>
+ * </ul>
+ * </p>
+ *
+ * @param <T>
+ *            type of the permuted objects
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public abstract class RandomKey<T> extends AbstractListChromosome<Double> implements PermutationChromosome<T> {
+
+    /**
+     * Cache of sorted representation (unmodifiable).
+     */
+    private final List<Double> sortedRepresentation;
+
+    /**
+     * Base sequence [0,1,...,n-1], permuted accorting to the representation (unmodifiable).
+     */
+    private final List<Integer> baseSeqPermutation;
+
+    /**
+     * Constructor.
+     *
+     * @param representation list of [0,1] values representing the permutation
+     */
+    public RandomKey(List<Double> representation) {
+        super(representation);
+        // store the sorted representation
+        List<Double> sortedRepr = new ArrayList<Double> (getRepresentation());
+        Collections.sort(sortedRepr);
+        sortedRepresentation = Collections.unmodifiableList(sortedRepr);
+        // store the permutation of [0,1,...,n-1] list for toString() and isSame() methods
+        baseSeqPermutation = Collections.unmodifiableList(
+            decodeGeneric(baseSequence(getLength()), getRepresentation(), sortedRepresentation)
+        );
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param representation array of [0,1] values representing the permutation
+     */
+    public RandomKey(Double[] representation) {
+        this(Arrays.asList(representation));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<T> decode(List<T> sequence) {
+        return decodeGeneric(sequence, getRepresentation(), sortedRepresentation);
+    }
+
+    /**
+     * Decodes a permutation represented by <code>representation</code> and
+     * returns a (generic) list with the permuted values.
+     *
+     * @param <S> generic type of the sequence values
+     * @param sequence the unpermuted sequence
+     * @param representation representation of the permutation ([0,1] vector)
+     * @param sortedRepr sorted <code>representation</code>
+     * @return list with the sequence values permuted according to the representation
+     */
+    private static <S> List<S> decodeGeneric(List<S> sequence, List<Double> representation, List<Double> sortedRepr) {
+        int l = sequence.size();
+
+        if (representation.size() != l) {
+            throw new IllegalArgumentException(String.format("Length of sequence for decoding (%s) has to be equal to the length of the RandomKey (%s)", l, representation.size()));
+        }
+        if (representation.size() != sortedRepr.size()) {
+            throw new IllegalArgumentException(String.format("Representation and sortedRepr must have same sizes, %d != %d", representation.size(), sortedRepr.size()));
+        }
+
+        List<Double> reprCopy = new ArrayList<Double> (representation);// do not modify the orig. representation
+
+        // now find the indices in the original repr and use them for permuting
+        List<S> res = new ArrayList<S> (l);
+        for (int i=0; i<l; i++) {
+            int index = reprCopy.indexOf(sortedRepr.get(i));
+            res.add(sequence.get(index));
+            reprCopy.set(index, null);
+        }
+        return res;
+    }
+
+    /**
+     * Returns <code>true</code> iff <code>another</code> is a RandomKey and
+     * encodes the same permutation.
+     *
+     * @param another chromosome to compare
+     * @return true iff chromosomes encode the same permutation
+     */
+    @Override
+    protected boolean isSame(Chromosome another) {
+        // type check
+        if (! (another instanceof RandomKey<?>))
+            return false;
+        RandomKey<?> anotherRk = (RandomKey<?>) another;
+        // size check
+        if (getLength() != anotherRk.getLength())
+            return false;
+
+        // two different representations can still encode the same permutation
+        // the ordering is what counts
+        List<Integer> thisPerm = this.baseSeqPermutation;
+        List<Integer> anotherPerm = anotherRk.baseSeqPermutation;
+
+        for (int i=0; i<getLength(); i++) {
+            if (thisPerm.get(i) != anotherPerm.get(i))
+                return false;
+        }
+        // the permutations are the same
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void checkValidity(java.util.List<Double> chromosomeRepresentation) throws InvalidRepresentationException {
+        for (double val : chromosomeRepresentation) {
+            if (val < 0 || val > 1) {
+                throw new InvalidRepresentationException("Values of representation must be in [0,1] interval");
+            }
+        }
+    }
+
+
+    /**
+     * Generates a representation corresponding to a random permutation of
+     * length l which can be passed to the RandomKey constructor.
+     *
+     * @param l
+     *            length of the permutation
+     * @return representation of a random permutation
+     */
+    public static final List<Double> randomPermutation(int l) {
+        List<Double> repr = new ArrayList<Double>(l);
+        for (int i=0; i<l; i++) {
+            repr.add(GeneticAlgorithm.getRandomGenerator().nextDouble());
+        }
+        return repr;
+    }
+
+    /**
+     * Generates a representation corresponding to an identity permutation of
+     * length l which can be passed to the RandomKey constructor.
+     *
+     * @param l
+     *            length of the permutation
+     * @return representation of an identity permutation
+     */
+    public static final List<Double> identityPermutation(int l) {
+        List<Double> repr = new ArrayList<Double>(l);
+        for (int i=0; i<l; i++) {
+            repr.add((double)i/l);
+        }
+        return repr;
+    }
+
+    /**
+     * Generates a representation of a permutation corresponding to the
+     * <code>data</code> sorted by <code>comparator</code>. The
+     * <code>data</code> is not modified during the process.
+     *
+     * This is useful if you want to inject some permutations to the initial
+     * population.
+     *
+     * @param <S> type of the data
+     * @param data list of data determining the order
+     * @param comparator how the data will be compared
+     * @return list representation of the permutation corresponding to the parameters
+     */
+    public static <S> List<Double> comparatorPermutation(List<S> data, Comparator<S> comparator) {
+        List<S> sortedData = new ArrayList<S> (data);
+        Collections.sort(sortedData, comparator);
+
+        return inducedPermutation(data, sortedData);
+    }
+
+    /**
+     * Generates a representation of a permutation corresponding to a
+     * permutation which yields <code>permutedData</code> when applied to
+     * <code>originalData</code>.
+     *
+     * This method can be viewed as an inverse to {@link #decode(List)}.
+     *
+     * @param <S> type of the data
+     * @param originalData the original, unpermuted data
+     * @param permutedData the data, somehow permuted
+     * @return representation of a permutation corresponding to the permutation <code>originalData -> permutedData</code>
+     * @throws IllegalArgumentException iff the <code>permutedData</code> and <code>originalData</code> contains different data
+     */
+    public static <S> List<Double> inducedPermutation(List<S> originalData, List<S> permutedData) throws IllegalArgumentException {
+        if (originalData.size() != permutedData.size()) {
+            throw new IllegalArgumentException("originalData and permutedData must have same length");
+        }
+        int l = originalData.size();
+
+        List<S> origDataCopy = new ArrayList<S> (originalData);
+
+        Double[] res = new Double[l];
+        for (int i=0; i<l; i++) {
+            int index = origDataCopy.indexOf(permutedData.get(i));
+            if (index == -1) {
+                throw new IllegalArgumentException("originalData and permutedData must contain the same objects.");
+            }
+            res[index] = (double) i / l;
+            origDataCopy.set(index, null);
+        }
+        return Arrays.asList(res);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return String.format("(f=%s pi=(%s))", getFitness(), baseSeqPermutation);
+    }
+
+    /**
+     * Helper for constructor. Generates a list of natural numbers (0,1,...,l-1).
+     *
+     * @param l length of list to generate
+     * @return list of integers from 0 to l-1
+     */
+    private static List<Integer> baseSequence(int l) {
+        List<Integer> baseSequence = new ArrayList<Integer> (l);
+        for (int i=0; i<l; i++) {
+            baseSequence.add(i);
+        }
+        return baseSequence;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/RandomKeyMutation.java b/src/main/java/org/apache/commons/math/genetics/RandomKeyMutation.java
new file mode 100644
index 0000000..792eef2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/RandomKeyMutation.java
@@ -0,0 +1,57 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Mutation operator for {@link RandomKey}s. Changes a randomly chosen element
+ * of the array representation to a random value uniformly distributed in [0,1].
+ *
+ * @since 2.0
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class RandomKeyMutation implements MutationPolicy {
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws IllegalArgumentException if <code>original</code> is not a
+     * {@link RandomKey} instance
+     */
+    public Chromosome mutate(Chromosome original) {
+        if (!(original instanceof RandomKey<?>)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.RANDOMKEY_MUTATION_WRONG_CLASS,
+                    original.getClass().getSimpleName());
+        }
+
+        RandomKey<?> originalRk = (RandomKey<?>) original;
+        List<Double> repr = originalRk.getRepresentation();
+        int rInd = GeneticAlgorithm.getRandomGenerator().nextInt(repr.size());
+
+        List<Double> newRepr = new ArrayList<Double> (repr);
+        newRepr.set(rInd, GeneticAlgorithm.getRandomGenerator().nextDouble());
+
+        return originalRk.newFixedLengthChromosome(newRepr);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/SelectionPolicy.java b/src/main/java/org/apache/commons/math/genetics/SelectionPolicy.java
new file mode 100644
index 0000000..4cf6768
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/SelectionPolicy.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.genetics;
+
+/**
+ * Algorithm used to select a chromosome pair from a population.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface SelectionPolicy {
+    /**
+     * Select two chromosomes from the population.
+     * @param population the population from which the chromosomes are choosen.
+     * @return the selected chromosomes.
+     */
+    ChromosomePair select(Population population);
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/StoppingCondition.java b/src/main/java/org/apache/commons/math/genetics/StoppingCondition.java
new file mode 100644
index 0000000..0253ce9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/StoppingCondition.java
@@ -0,0 +1,35 @@
+/*
+ * 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.genetics;
+
+/**
+ * Algorithm used to determine when to stop evolution.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface StoppingCondition {
+    /**
+     * Determine whether or not the given population satisfies the stopping
+     * condition.
+     *
+     * @param population the population to test.
+     * @return <code>true</code> if this stopping condition is met by the
+     *         given population. <code>false</code> otherwise.
+     */
+    boolean isSatisfied(Population population);
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/TournamentSelection.java b/src/main/java/org/apache/commons/math/genetics/TournamentSelection.java
new file mode 100644
index 0000000..f1a091f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/TournamentSelection.java
@@ -0,0 +1,114 @@
+/*
+ * 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.genetics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tournament selection scheme. Each of the two selected chromosomes is selected
+ * based on n-ary tournament -- this is done by drawing {@link #arity} random
+ * chromosomes without replacement from the population, and then selecting the
+ * fittest chromosome among them.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class TournamentSelection implements SelectionPolicy {
+
+    /** number of chromosomes included in the tournament selections */
+    private int arity;
+
+    /**
+     * Creates a new TournamentSelection instance.
+     *
+     * @param arity
+     *            how many chromosomes will be drawn to the tournament
+     */
+    public TournamentSelection(int arity) {
+        this.arity = arity;
+    }
+
+    /**
+     * Select two chromosomes from the population. Each of the two selected
+     * chromosomes is selected based on n-ary tournament -- this is done by
+     * drawing {@link #arity} random chromosomes without replacement from the
+     * population, and then selecting the fittest chromosome among them.
+     *
+     * @param population
+     *            the population from which the chromosomes are choosen.
+     * @return the selected chromosomes.
+     */
+    public ChromosomePair select(Population population) {
+        return new ChromosomePair(
+                tournament((ListPopulation) population),
+                tournament((ListPopulation)population)
+                );
+    }
+
+    /**
+     * Helper for {@link #select(Population)}. Draw {@link #arity} random
+     * chromosomes without replacement from the population, and then select the
+     * fittest chromosome among them.
+     *
+     * @param population
+     *            the population from which the chromosomes are choosen.
+     * @return the selected chromosome.
+     */
+    private Chromosome tournament(ListPopulation population) {
+        if (population.getPopulationSize() < this.arity)
+            throw new IllegalArgumentException("Tournament arity cannot be bigger than population size.");
+        // auxiliary population
+        ListPopulation tournamentPopulation = new ListPopulation(this.arity) {
+            public Population nextGeneration() {
+                // not useful here
+                return null;
+            }
+        };
+
+        // create a copy of the chromosome list
+        List<Chromosome> chromosomes = new ArrayList<Chromosome> (population.getChromosomes());
+        for (int i=0; i<this.arity; i++) {
+            // select a random individual and add it to the tournament
+            int rind = GeneticAlgorithm.getRandomGenerator().nextInt(chromosomes.size());
+            tournamentPopulation.addChromosome(chromosomes.get(rind));
+            // do not select it again
+            chromosomes.remove(rind);
+        }
+        // the winner takes it all
+        return tournamentPopulation.getFittestChromosome();
+    }
+
+    /**
+     * Gets the arity (number of chromosomes drawn to the tournament).
+     *
+     * @return arity of the tournament
+     */
+    public int getArity() {
+        return arity;
+    }
+
+    /**
+     * Sets the arity (number of chromosomes drawn to the tournament).
+     *
+     * @param arity arity of the tournament
+     */
+    public void setArity(int arity) {
+        this.arity = arity;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/genetics/package.html b/src/main/java/org/apache/commons/math/genetics/package.html
new file mode 100644
index 0000000..adcd5a9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/genetics/package.html
@@ -0,0 +1,24 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 784604 $ -->
+<body>
+<p>
+This package provides Genetic Algorithms components and implementations.
+</p>
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/geometry/CardanEulerSingularityException.java b/src/main/java/org/apache/commons/math/geometry/CardanEulerSingularityException.java
new file mode 100644
index 0000000..61d349e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/CardanEulerSingularityException.java
@@ -0,0 +1,45 @@
+/*
+ * 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.geometry;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/** This class represents exceptions thrown while extractiong Cardan
+ * or Euler angles from a rotation.
+
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 1.2
+ */
+public class CardanEulerSingularityException
+  extends MathException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1360952845582206770L;
+
+    /**
+     * Simple constructor.
+     * build an exception with a default message.
+     * @param isCardan if true, the rotation is related to Cardan angles,
+     * if false it is related to EulerAngles
+     */
+    public CardanEulerSingularityException(boolean isCardan) {
+        super(isCardan ? LocalizedFormats.CARDAN_ANGLES_SINGULARITY : LocalizedFormats.EULER_ANGLES_SINGULARITY);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/geometry/NotARotationMatrixException.java b/src/main/java/org/apache/commons/math/geometry/NotARotationMatrixException.java
new file mode 100644
index 0000000..0b6ff8d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/NotARotationMatrixException.java
@@ -0,0 +1,60 @@
+/*
+ * 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.geometry;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * This class represents exceptions thrown while building rotations
+ * from matrices.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 1.2
+ */
+
+public class NotARotationMatrixException
+  extends MathException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 5647178478658937642L;
+
+    /**
+     * Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @deprecated as of 2.2 replaced by {@link #NotARotationMatrixException(Localizable, Object...)}
+     */
+    @Deprecated
+    public NotARotationMatrixException(String specifier, Object ... parts) {
+        super(specifier, parts);
+    }
+
+    /**
+     * Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @since 2.2
+     */
+    public NotARotationMatrixException(Localizable specifier, Object ... parts) {
+        super(specifier, parts);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/geometry/Rotation.java b/src/main/java/org/apache/commons/math/geometry/Rotation.java
new file mode 100644
index 0000000..ee3f4b7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/Rotation.java
@@ -0,0 +1,1072 @@
+/*
+ * 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.geometry;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements rotations in a three-dimensional space.
+ *
+ * <p>Rotations can be represented by several different mathematical
+ * entities (matrices, axe and angle, Cardan or Euler angles,
+ * quaternions). This class presents an higher level abstraction, more
+ * user-oriented and hiding this implementation details. Well, for the
+ * curious, we use quaternions for the internal representation. The
+ * user can build a rotation from any of these representations, and
+ * any of these representations can be retrieved from a
+ * <code>Rotation</code> instance (see the various constructors and
+ * getters). In addition, a rotation can also be built implicitly
+ * from a set of vectors and their image.</p>
+ * <p>This implies that this class can be used to convert from one
+ * representation to another one. For example, converting a rotation
+ * matrix into a set of Cardan angles from can be done using the
+ * following single line of code:</p>
+ * <pre>
+ * double[] angles = new Rotation(matrix, 1.0e-10).getAngles(RotationOrder.XYZ);
+ * </pre>
+ * <p>Focus is oriented on what a rotation <em>do</em> rather than on its
+ * underlying representation. Once it has been built, and regardless of its
+ * internal representation, a rotation is an <em>operator</em> which basically
+ * transforms three dimensional {@link Vector3D vectors} into other three
+ * dimensional {@link Vector3D vectors}. Depending on the application, the
+ * meaning of these vectors may vary and the semantics of the rotation also.</p>
+ * <p>For example in an spacecraft attitude simulation tool, users will often
+ * consider the vectors are fixed (say the Earth direction for example) and the
+ * frames change. The rotation transforms the coordinates of the vector in inertial
+ * frame into the coordinates of the same vector in satellite frame. In this
+ * case, the rotation implicitly defines the relation between the two frames.</p>
+ * <p>Another example could be a telescope control application, where the rotation
+ * would transform the sighting direction at rest into the desired observing
+ * direction when the telescope is pointed towards an object of interest. In this
+ * case the rotation transforms the direction at rest in a topocentric frame
+ * into the sighting direction in the same topocentric frame. This implies in this
+ * case the frame is fixed and the vector moves.</p>
+ * <p>In many case, both approaches will be combined. In our telescope example,
+ * we will probably also need to transform the observing direction in the topocentric
+ * frame into the observing direction in inertial frame taking into account the observatory
+ * location and the Earth rotation, which would essentially be an application of the
+ * first approach.</p>
+ *
+ * <p>These examples show that a rotation is what the user wants it to be. This
+ * class does not push the user towards one specific definition and hence does not
+ * provide methods like <code>projectVectorIntoDestinationFrame</code> or
+ * <code>computeTransformedDirection</code>. It provides simpler and more generic
+ * methods: {@link #applyTo(Vector3D) applyTo(Vector3D)} and {@link
+ * #applyInverseTo(Vector3D) applyInverseTo(Vector3D)}.</p>
+ *
+ * <p>Since a rotation is basically a vectorial operator, several rotations can be
+ * composed together and the composite operation <code>r = r<sub>1</sub> o
+ * r<sub>2</sub></code> (which means that for each vector <code>u</code>,
+ * <code>r(u) = r<sub>1</sub>(r<sub>2</sub>(u))</code>) is also a rotation. Hence
+ * we can consider that in addition to vectors, a rotation can be applied to other
+ * rotations as well (or to itself). With our previous notations, we would say we
+ * can apply <code>r<sub>1</sub></code> to <code>r<sub>2</sub></code> and the result
+ * we get is <code>r = r<sub>1</sub> o r<sub>2</sub></code>. For this purpose, the
+ * class provides the methods: {@link #applyTo(Rotation) applyTo(Rotation)} and
+ * {@link #applyInverseTo(Rotation) applyInverseTo(Rotation)}.</p>
+ *
+ * <p>Rotations are guaranteed to be immutable objects.</p>
+ *
+ * @version $Revision: 1067500 $ $Date: 2011-02-05 21:11:30 +0100 (sam. 05 févr. 2011) $
+ * @see Vector3D
+ * @see RotationOrder
+ * @since 1.2
+ */
+
+public class Rotation implements Serializable {
+
+  /** Identity rotation. */
+  public static final Rotation IDENTITY = new Rotation(1.0, 0.0, 0.0, 0.0, false);
+
+  /** Serializable version identifier */
+  private static final long serialVersionUID = -2153622329907944313L;
+
+  /** Scalar coordinate of the quaternion. */
+  private final double q0;
+
+  /** First coordinate of the vectorial part of the quaternion. */
+  private final double q1;
+
+  /** Second coordinate of the vectorial part of the quaternion. */
+  private final double q2;
+
+  /** Third coordinate of the vectorial part of the quaternion. */
+  private final double q3;
+
+  /** Build a rotation from the quaternion coordinates.
+   * <p>A rotation can be built from a <em>normalized</em> quaternion,
+   * i.e. a quaternion for which q<sub>0</sub><sup>2</sup> +
+   * q<sub>1</sub><sup>2</sup> + q<sub>2</sub><sup>2</sup> +
+   * q<sub>3</sub><sup>2</sup> = 1. If the quaternion is not normalized,
+   * the constructor can normalize it in a preprocessing step.</p>
+   * <p>Note that some conventions put the scalar part of the quaternion
+   * as the 4<sup>th</sup> component and the vector part as the first three
+   * components. This is <em>not</em> our convention. We put the scalar part
+   * as the first component.</p>
+   * @param q0 scalar part of the quaternion
+   * @param q1 first coordinate of the vectorial part of the quaternion
+   * @param q2 second coordinate of the vectorial part of the quaternion
+   * @param q3 third coordinate of the vectorial part of the quaternion
+   * @param needsNormalization if true, the coordinates are considered
+   * not to be normalized, a normalization preprocessing step is performed
+   * before using them
+   */
+  public Rotation(double q0, double q1, double q2, double q3,
+                  boolean needsNormalization) {
+
+    if (needsNormalization) {
+      // normalization preprocessing
+      double inv = 1.0 / FastMath.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
+      q0 *= inv;
+      q1 *= inv;
+      q2 *= inv;
+      q3 *= inv;
+    }
+
+    this.q0 = q0;
+    this.q1 = q1;
+    this.q2 = q2;
+    this.q3 = q3;
+
+  }
+
+  /** Build a rotation from an axis and an angle.
+   * <p>We use the convention that angles are oriented according to
+   * the effect of the rotation on vectors around the axis. That means
+   * that if (i, j, k) is a direct frame and if we first provide +k as
+   * the axis and &pi;/2 as the angle to this constructor, and then
+   * {@link #applyTo(Vector3D) apply} the instance to +i, we will get
+   * +j.</p>
+   * <p>Another way to represent our convention is to say that a rotation
+   * of angle &theta; about the unit vector (x, y, z) is the same as the
+   * rotation build from quaternion components { cos(-&theta;/2),
+   * x * sin(-&theta;/2), y * sin(-&theta;/2), z * sin(-&theta;/2) }.
+   * Note the minus sign on the angle!</p>
+   * <p>On the one hand this convention is consistent with a vectorial
+   * perspective (moving vectors in fixed frames), on the other hand it
+   * is different from conventions with a frame perspective (fixed vectors
+   * viewed from different frames) like the ones used for example in spacecraft
+   * attitude community or in the graphics community.</p>
+   * @param axis axis around which to rotate
+   * @param angle rotation angle.
+   * @exception ArithmeticException if the axis norm is zero
+   */
+  public Rotation(Vector3D axis, double angle) {
+
+    double norm = axis.getNorm();
+    if (norm == 0) {
+      throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_AXIS);
+    }
+
+    double halfAngle = -0.5 * angle;
+    double coeff = FastMath.sin(halfAngle) / norm;
+
+    q0 = FastMath.cos (halfAngle);
+    q1 = coeff * axis.getX();
+    q2 = coeff * axis.getY();
+    q3 = coeff * axis.getZ();
+
+  }
+
+  /** Build a rotation from a 3X3 matrix.
+
+   * <p>Rotation matrices are orthogonal matrices, i.e. unit matrices
+   * (which are matrices for which m.m<sup>T</sup> = I) with real
+   * coefficients. The module of the determinant of unit matrices is
+   * 1, among the orthogonal 3X3 matrices, only the ones having a
+   * positive determinant (+1) are rotation matrices.</p>
+   *
+   * <p>When a rotation is defined by a matrix with truncated values
+   * (typically when it is extracted from a technical sheet where only
+   * four to five significant digits are available), the matrix is not
+   * orthogonal anymore. This constructor handles this case
+   * transparently by using a copy of the given matrix and applying a
+   * correction to the copy in order to perfect its orthogonality. If
+   * the Frobenius norm of the correction needed is above the given
+   * threshold, then the matrix is considered to be too far from a
+   * true rotation matrix and an exception is thrown.<p>
+   *
+   * @param m rotation matrix
+   * @param threshold convergence threshold for the iterative
+   * orthogonality correction (convergence is reached when the
+   * difference between two steps of the Frobenius norm of the
+   * correction is below this threshold)
+   *
+   * @exception NotARotationMatrixException if the matrix is not a 3X3
+   * matrix, or if it cannot be transformed into an orthogonal matrix
+   * with the given threshold, or if the determinant of the resulting
+   * orthogonal matrix is negative
+   *
+   */
+  public Rotation(double[][] m, double threshold)
+    throws NotARotationMatrixException {
+
+    // dimension check
+    if ((m.length != 3) || (m[0].length != 3) ||
+        (m[1].length != 3) || (m[2].length != 3)) {
+      throw new NotARotationMatrixException(
+              LocalizedFormats.ROTATION_MATRIX_DIMENSIONS,
+              m.length, m[0].length);
+    }
+
+    // compute a "close" orthogonal matrix
+    double[][] ort = orthogonalizeMatrix(m, threshold);
+
+    // check the sign of the determinant
+    double det = ort[0][0] * (ort[1][1] * ort[2][2] - ort[2][1] * ort[1][2]) -
+                 ort[1][0] * (ort[0][1] * ort[2][2] - ort[2][1] * ort[0][2]) +
+                 ort[2][0] * (ort[0][1] * ort[1][2] - ort[1][1] * ort[0][2]);
+    if (det < 0.0) {
+      throw new NotARotationMatrixException(
+              LocalizedFormats.CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT,
+              det);
+    }
+
+    // There are different ways to compute the quaternions elements
+    // from the matrix. They all involve computing one element from
+    // the diagonal of the matrix, and computing the three other ones
+    // using a formula involving a division by the first element,
+    // which unfortunately can be zero. Since the norm of the
+    // quaternion is 1, we know at least one element has an absolute
+    // value greater or equal to 0.5, so it is always possible to
+    // select the right formula and avoid division by zero and even
+    // numerical inaccuracy. Checking the elements in turn and using
+    // the first one greater than 0.45 is safe (this leads to a simple
+    // test since qi = 0.45 implies 4 qi^2 - 1 = -0.19)
+    double s = ort[0][0] + ort[1][1] + ort[2][2];
+    if (s > -0.19) {
+      // compute q0 and deduce q1, q2 and q3
+      q0 = 0.5 * FastMath.sqrt(s + 1.0);
+      double inv = 0.25 / q0;
+      q1 = inv * (ort[1][2] - ort[2][1]);
+      q2 = inv * (ort[2][0] - ort[0][2]);
+      q3 = inv * (ort[0][1] - ort[1][0]);
+    } else {
+      s = ort[0][0] - ort[1][1] - ort[2][2];
+      if (s > -0.19) {
+        // compute q1 and deduce q0, q2 and q3
+        q1 = 0.5 * FastMath.sqrt(s + 1.0);
+        double inv = 0.25 / q1;
+        q0 = inv * (ort[1][2] - ort[2][1]);
+        q2 = inv * (ort[0][1] + ort[1][0]);
+        q3 = inv * (ort[0][2] + ort[2][0]);
+      } else {
+        s = ort[1][1] - ort[0][0] - ort[2][2];
+        if (s > -0.19) {
+          // compute q2 and deduce q0, q1 and q3
+          q2 = 0.5 * FastMath.sqrt(s + 1.0);
+          double inv = 0.25 / q2;
+          q0 = inv * (ort[2][0] - ort[0][2]);
+          q1 = inv * (ort[0][1] + ort[1][0]);
+          q3 = inv * (ort[2][1] + ort[1][2]);
+        } else {
+          // compute q3 and deduce q0, q1 and q2
+          s = ort[2][2] - ort[0][0] - ort[1][1];
+          q3 = 0.5 * FastMath.sqrt(s + 1.0);
+          double inv = 0.25 / q3;
+          q0 = inv * (ort[0][1] - ort[1][0]);
+          q1 = inv * (ort[0][2] + ort[2][0]);
+          q2 = inv * (ort[2][1] + ort[1][2]);
+        }
+      }
+    }
+
+  }
+
+  /** Build the rotation that transforms a pair of vector into another pair.
+
+   * <p>Except for possible scale factors, if the instance were applied to
+   * the pair (u<sub>1</sub>, u<sub>2</sub>) it will produce the pair
+   * (v<sub>1</sub>, v<sub>2</sub>).</p>
+   *
+   * <p>If the angular separation between u<sub>1</sub> and u<sub>2</sub> is
+   * not the same as the angular separation between v<sub>1</sub> and
+   * v<sub>2</sub>, then a corrected v'<sub>2</sub> will be used rather than
+   * v<sub>2</sub>, the corrected vector will be in the (v<sub>1</sub>,
+   * v<sub>2</sub>) plane.</p>
+   *
+   * @param u1 first vector of the origin pair
+   * @param u2 second vector of the origin pair
+   * @param v1 desired image of u1 by the rotation
+   * @param v2 desired image of u2 by the rotation
+   * @exception IllegalArgumentException if the norm of one of the vectors is zero
+   */
+  public Rotation(Vector3D u1, Vector3D u2, Vector3D v1, Vector3D v2) {
+
+  // norms computation
+  double u1u1 = Vector3D.dotProduct(u1, u1);
+  double u2u2 = Vector3D.dotProduct(u2, u2);
+  double v1v1 = Vector3D.dotProduct(v1, v1);
+  double v2v2 = Vector3D.dotProduct(v2, v2);
+  if ((u1u1 == 0) || (u2u2 == 0) || (v1v1 == 0) || (v2v2 == 0)) {
+    throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR);
+  }
+
+  double u1x = u1.getX();
+  double u1y = u1.getY();
+  double u1z = u1.getZ();
+
+  double u2x = u2.getX();
+  double u2y = u2.getY();
+  double u2z = u2.getZ();
+
+  // normalize v1 in order to have (v1'|v1') = (u1|u1)
+  double coeff = FastMath.sqrt (u1u1 / v1v1);
+  double v1x   = coeff * v1.getX();
+  double v1y   = coeff * v1.getY();
+  double v1z   = coeff * v1.getZ();
+  v1 = new Vector3D(v1x, v1y, v1z);
+
+  // adjust v2 in order to have (u1|u2) = (v1|v2) and (v2'|v2') = (u2|u2)
+  double u1u2   = Vector3D.dotProduct(u1, u2);
+  double v1v2   = Vector3D.dotProduct(v1, v2);
+  double coeffU = u1u2 / u1u1;
+  double coeffV = v1v2 / u1u1;
+  double beta   = FastMath.sqrt((u2u2 - u1u2 * coeffU) / (v2v2 - v1v2 * coeffV));
+  double alpha  = coeffU - beta * coeffV;
+  double v2x    = alpha * v1x + beta * v2.getX();
+  double v2y    = alpha * v1y + beta * v2.getY();
+  double v2z    = alpha * v1z + beta * v2.getZ();
+  v2 = new Vector3D(v2x, v2y, v2z);
+
+  // preliminary computation (we use explicit formulation instead
+  // of relying on the Vector3D class in order to avoid building lots
+  // of temporary objects)
+  Vector3D uRef = u1;
+  Vector3D vRef = v1;
+  double dx1 = v1x - u1.getX();
+  double dy1 = v1y - u1.getY();
+  double dz1 = v1z - u1.getZ();
+  double dx2 = v2x - u2.getX();
+  double dy2 = v2y - u2.getY();
+  double dz2 = v2z - u2.getZ();
+  Vector3D k = new Vector3D(dy1 * dz2 - dz1 * dy2,
+                            dz1 * dx2 - dx1 * dz2,
+                            dx1 * dy2 - dy1 * dx2);
+  double c = k.getX() * (u1y * u2z - u1z * u2y) +
+             k.getY() * (u1z * u2x - u1x * u2z) +
+             k.getZ() * (u1x * u2y - u1y * u2x);
+
+  if (c == 0) {
+    // the (q1, q2, q3) vector is in the (u1, u2) plane
+    // we try other vectors
+    Vector3D u3 = Vector3D.crossProduct(u1, u2);
+    Vector3D v3 = Vector3D.crossProduct(v1, v2);
+    double u3x  = u3.getX();
+    double u3y  = u3.getY();
+    double u3z  = u3.getZ();
+    double v3x  = v3.getX();
+    double v3y  = v3.getY();
+    double v3z  = v3.getZ();
+
+    double dx3 = v3x - u3x;
+    double dy3 = v3y - u3y;
+    double dz3 = v3z - u3z;
+    k = new Vector3D(dy1 * dz3 - dz1 * dy3,
+                     dz1 * dx3 - dx1 * dz3,
+                     dx1 * dy3 - dy1 * dx3);
+    c = k.getX() * (u1y * u3z - u1z * u3y) +
+        k.getY() * (u1z * u3x - u1x * u3z) +
+        k.getZ() * (u1x * u3y - u1y * u3x);
+
+    if (c == 0) {
+      // the (q1, q2, q3) vector is aligned with u1:
+      // we try (u2, u3) and (v2, v3)
+      k = new Vector3D(dy2 * dz3 - dz2 * dy3,
+                       dz2 * dx3 - dx2 * dz3,
+                       dx2 * dy3 - dy2 * dx3);
+      c = k.getX() * (u2y * u3z - u2z * u3y) +
+          k.getY() * (u2z * u3x - u2x * u3z) +
+          k.getZ() * (u2x * u3y - u2y * u3x);
+
+      if (c == 0) {
+        // the (q1, q2, q3) vector is aligned with everything
+        // this is really the identity rotation
+        q0 = 1.0;
+        q1 = 0.0;
+        q2 = 0.0;
+        q3 = 0.0;
+        return;
+      }
+
+      // we will have to use u2 and v2 to compute the scalar part
+      uRef = u2;
+      vRef = v2;
+
+    }
+
+  }
+
+  // compute the vectorial part
+  c = FastMath.sqrt(c);
+  double inv = 1.0 / (c + c);
+  q1 = inv * k.getX();
+  q2 = inv * k.getY();
+  q3 = inv * k.getZ();
+
+  // compute the scalar part
+   k = new Vector3D(uRef.getY() * q3 - uRef.getZ() * q2,
+                    uRef.getZ() * q1 - uRef.getX() * q3,
+                    uRef.getX() * q2 - uRef.getY() * q1);
+   c = Vector3D.dotProduct(k, k);
+  q0 = Vector3D.dotProduct(vRef, k) / (c + c);
+
+  }
+
+  /** Build one of the rotations that transform one vector into another one.
+
+   * <p>Except for a possible scale factor, if the instance were
+   * applied to the vector u it will produce the vector v. There is an
+   * infinite number of such rotations, this constructor choose the
+   * one with the smallest associated angle (i.e. the one whose axis
+   * is orthogonal to the (u, v) plane). If u and v are colinear, an
+   * arbitrary rotation axis is chosen.</p>
+   *
+   * @param u origin vector
+   * @param v desired image of u by the rotation
+   * @exception IllegalArgumentException if the norm of one of the vectors is zero
+   */
+  public Rotation(Vector3D u, Vector3D v) {
+
+    double normProduct = u.getNorm() * v.getNorm();
+    if (normProduct == 0) {
+        throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.ZERO_NORM_FOR_ROTATION_DEFINING_VECTOR);
+    }
+
+    double dot = Vector3D.dotProduct(u, v);
+
+    if (dot < ((2.0e-15 - 1.0) * normProduct)) {
+      // special case u = -v: we select a PI angle rotation around
+      // an arbitrary vector orthogonal to u
+      Vector3D w = u.orthogonal();
+      q0 = 0.0;
+      q1 = -w.getX();
+      q2 = -w.getY();
+      q3 = -w.getZ();
+    } else {
+      // general case: (u, v) defines a plane, we select
+      // the shortest possible rotation: axis orthogonal to this plane
+      q0 = FastMath.sqrt(0.5 * (1.0 + dot / normProduct));
+      double coeff = 1.0 / (2.0 * q0 * normProduct);
+      q1 = coeff * (v.getY() * u.getZ() - v.getZ() * u.getY());
+      q2 = coeff * (v.getZ() * u.getX() - v.getX() * u.getZ());
+      q3 = coeff * (v.getX() * u.getY() - v.getY() * u.getX());
+    }
+
+  }
+
+  /** Build a rotation from three Cardan or Euler elementary rotations.
+
+   * <p>Cardan rotations are three successive rotations around the
+   * canonical axes X, Y and Z, each axis being used once. There are
+   * 6 such sets of rotations (XYZ, XZY, YXZ, YZX, ZXY and ZYX). Euler
+   * rotations are three successive rotations around the canonical
+   * axes X, Y and Z, the first and last rotations being around the
+   * same axis. There are 6 such sets of rotations (XYX, XZX, YXY,
+   * YZY, ZXZ and ZYZ), the most popular one being ZXZ.</p>
+   * <p>Beware that many people routinely use the term Euler angles even
+   * for what really are Cardan angles (this confusion is especially
+   * widespread in the aerospace business where Roll, Pitch and Yaw angles
+   * are often wrongly tagged as Euler angles).</p>
+   *
+   * @param order order of rotations to use
+   * @param alpha1 angle of the first elementary rotation
+   * @param alpha2 angle of the second elementary rotation
+   * @param alpha3 angle of the third elementary rotation
+   */
+  public Rotation(RotationOrder order,
+                  double alpha1, double alpha2, double alpha3) {
+    Rotation r1 = new Rotation(order.getA1(), alpha1);
+    Rotation r2 = new Rotation(order.getA2(), alpha2);
+    Rotation r3 = new Rotation(order.getA3(), alpha3);
+    Rotation composed = r1.applyTo(r2.applyTo(r3));
+    q0 = composed.q0;
+    q1 = composed.q1;
+    q2 = composed.q2;
+    q3 = composed.q3;
+  }
+
+  /** Revert a rotation.
+   * Build a rotation which reverse the effect of another
+   * rotation. This means that if r(u) = v, then r.revert(v) = u. The
+   * instance is not changed.
+   * @return a new rotation whose effect is the reverse of the effect
+   * of the instance
+   */
+  public Rotation revert() {
+    return new Rotation(-q0, q1, q2, q3, false);
+  }
+
+  /** Get the scalar coordinate of the quaternion.
+   * @return scalar coordinate of the quaternion
+   */
+  public double getQ0() {
+    return q0;
+  }
+
+  /** Get the first coordinate of the vectorial part of the quaternion.
+   * @return first coordinate of the vectorial part of the quaternion
+   */
+  public double getQ1() {
+    return q1;
+  }
+
+  /** Get the second coordinate of the vectorial part of the quaternion.
+   * @return second coordinate of the vectorial part of the quaternion
+   */
+  public double getQ2() {
+    return q2;
+  }
+
+  /** Get the third coordinate of the vectorial part of the quaternion.
+   * @return third coordinate of the vectorial part of the quaternion
+   */
+  public double getQ3() {
+    return q3;
+  }
+
+  /** Get the normalized axis of the rotation.
+   * @return normalized axis of the rotation
+   * @see #Rotation(Vector3D, double)
+   */
+  public Vector3D getAxis() {
+    double squaredSine = q1 * q1 + q2 * q2 + q3 * q3;
+    if (squaredSine == 0) {
+      return new Vector3D(1, 0, 0);
+    } else if (q0 < 0) {
+      double inverse = 1 / FastMath.sqrt(squaredSine);
+      return new Vector3D(q1 * inverse, q2 * inverse, q3 * inverse);
+    }
+    double inverse = -1 / FastMath.sqrt(squaredSine);
+    return new Vector3D(q1 * inverse, q2 * inverse, q3 * inverse);
+  }
+
+  /** Get the angle of the rotation.
+   * @return angle of the rotation (between 0 and &pi;)
+   * @see #Rotation(Vector3D, double)
+   */
+  public double getAngle() {
+    if ((q0 < -0.1) || (q0 > 0.1)) {
+      return 2 * FastMath.asin(FastMath.sqrt(q1 * q1 + q2 * q2 + q3 * q3));
+    } else if (q0 < 0) {
+      return 2 * FastMath.acos(-q0);
+    }
+    return 2 * FastMath.acos(q0);
+  }
+
+  /** Get the Cardan or Euler angles corresponding to the instance.
+
+   * <p>The equations show that each rotation can be defined by two
+   * different values of the Cardan or Euler angles set. For example
+   * if Cardan angles are used, the rotation defined by the angles
+   * a<sub>1</sub>, a<sub>2</sub> and a<sub>3</sub> is the same as
+   * the rotation defined by the angles &pi; + a<sub>1</sub>, &pi;
+   * - a<sub>2</sub> and &pi; + a<sub>3</sub>. This method implements
+   * the following arbitrary choices:</p>
+   * <ul>
+   *   <li>for Cardan angles, the chosen set is the one for which the
+   *   second angle is between -&pi;/2 and &pi;/2 (i.e its cosine is
+   *   positive),</li>
+   *   <li>for Euler angles, the chosen set is the one for which the
+   *   second angle is between 0 and &pi; (i.e its sine is positive).</li>
+   * </ul>
+   *
+   * <p>Cardan and Euler angle have a very disappointing drawback: all
+   * of them have singularities. This means that if the instance is
+   * too close to the singularities corresponding to the given
+   * rotation order, it will be impossible to retrieve the angles. For
+   * Cardan angles, this is often called gimbal lock. There is
+   * <em>nothing</em> to do to prevent this, it is an intrinsic problem
+   * with Cardan and Euler representation (but not a problem with the
+   * rotation itself, which is perfectly well defined). For Cardan
+   * angles, singularities occur when the second angle is close to
+   * -&pi;/2 or +&pi;/2, for Euler angle singularities occur when the
+   * second angle is close to 0 or &pi;, this implies that the identity
+   * rotation is always singular for Euler angles!</p>
+   *
+   * @param order rotation order to use
+   * @return an array of three angles, in the order specified by the set
+   * @exception CardanEulerSingularityException if the rotation is
+   * singular with respect to the angles set specified
+   */
+  public double[] getAngles(RotationOrder order)
+    throws CardanEulerSingularityException {
+
+    if (order == RotationOrder.XYZ) {
+
+      // r (Vector3D.plusK) coordinates are :
+      //  sin (theta), -cos (theta) sin (phi), cos (theta) cos (phi)
+      // (-r) (Vector3D.plusI) coordinates are :
+      // cos (psi) cos (theta), -sin (psi) cos (theta), sin (theta)
+      // and we can choose to have theta in the interval [-PI/2 ; +PI/2]
+      Vector3D v1 = applyTo(Vector3D.PLUS_K);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_I);
+      if  ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(true);
+      }
+      return new double[] {
+        FastMath.atan2(-(v1.getY()), v1.getZ()),
+        FastMath.asin(v2.getZ()),
+        FastMath.atan2(-(v2.getY()), v2.getX())
+      };
+
+    } else if (order == RotationOrder.XZY) {
+
+      // r (Vector3D.plusJ) coordinates are :
+      // -sin (psi), cos (psi) cos (phi), cos (psi) sin (phi)
+      // (-r) (Vector3D.plusI) coordinates are :
+      // cos (theta) cos (psi), -sin (psi), sin (theta) cos (psi)
+      // and we can choose to have psi in the interval [-PI/2 ; +PI/2]
+      Vector3D v1 = applyTo(Vector3D.PLUS_J);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_I);
+      if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(true);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getZ(), v1.getY()),
+       -FastMath.asin(v2.getY()),
+        FastMath.atan2(v2.getZ(), v2.getX())
+      };
+
+    } else if (order == RotationOrder.YXZ) {
+
+      // r (Vector3D.plusK) coordinates are :
+      //  cos (phi) sin (theta), -sin (phi), cos (phi) cos (theta)
+      // (-r) (Vector3D.plusJ) coordinates are :
+      // sin (psi) cos (phi), cos (psi) cos (phi), -sin (phi)
+      // and we can choose to have phi in the interval [-PI/2 ; +PI/2]
+      Vector3D v1 = applyTo(Vector3D.PLUS_K);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_J);
+      if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(true);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getX(), v1.getZ()),
+       -FastMath.asin(v2.getZ()),
+        FastMath.atan2(v2.getX(), v2.getY())
+      };
+
+    } else if (order == RotationOrder.YZX) {
+
+      // r (Vector3D.plusI) coordinates are :
+      // cos (psi) cos (theta), sin (psi), -cos (psi) sin (theta)
+      // (-r) (Vector3D.plusJ) coordinates are :
+      // sin (psi), cos (phi) cos (psi), -sin (phi) cos (psi)
+      // and we can choose to have psi in the interval [-PI/2 ; +PI/2]
+      Vector3D v1 = applyTo(Vector3D.PLUS_I);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_J);
+      if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(true);
+      }
+      return new double[] {
+        FastMath.atan2(-(v1.getZ()), v1.getX()),
+        FastMath.asin(v2.getX()),
+        FastMath.atan2(-(v2.getZ()), v2.getY())
+      };
+
+    } else if (order == RotationOrder.ZXY) {
+
+      // r (Vector3D.plusJ) coordinates are :
+      // -cos (phi) sin (psi), cos (phi) cos (psi), sin (phi)
+      // (-r) (Vector3D.plusK) coordinates are :
+      // -sin (theta) cos (phi), sin (phi), cos (theta) cos (phi)
+      // and we can choose to have phi in the interval [-PI/2 ; +PI/2]
+      Vector3D v1 = applyTo(Vector3D.PLUS_J);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_K);
+      if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(true);
+      }
+      return new double[] {
+        FastMath.atan2(-(v1.getX()), v1.getY()),
+        FastMath.asin(v2.getY()),
+        FastMath.atan2(-(v2.getX()), v2.getZ())
+      };
+
+    } else if (order == RotationOrder.ZYX) {
+
+      // r (Vector3D.plusI) coordinates are :
+      //  cos (theta) cos (psi), cos (theta) sin (psi), -sin (theta)
+      // (-r) (Vector3D.plusK) coordinates are :
+      // -sin (theta), sin (phi) cos (theta), cos (phi) cos (theta)
+      // and we can choose to have theta in the interval [-PI/2 ; +PI/2]
+      Vector3D v1 = applyTo(Vector3D.PLUS_I);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_K);
+      if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(true);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getY(), v1.getX()),
+       -FastMath.asin(v2.getX()),
+        FastMath.atan2(v2.getY(), v2.getZ())
+      };
+
+    } else if (order == RotationOrder.XYX) {
+
+      // r (Vector3D.plusI) coordinates are :
+      //  cos (theta), sin (phi1) sin (theta), -cos (phi1) sin (theta)
+      // (-r) (Vector3D.plusI) coordinates are :
+      // cos (theta), sin (theta) sin (phi2), sin (theta) cos (phi2)
+      // and we can choose to have theta in the interval [0 ; PI]
+      Vector3D v1 = applyTo(Vector3D.PLUS_I);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_I);
+      if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(false);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getY(), -v1.getZ()),
+        FastMath.acos(v2.getX()),
+        FastMath.atan2(v2.getY(), v2.getZ())
+      };
+
+    } else if (order == RotationOrder.XZX) {
+
+      // r (Vector3D.plusI) coordinates are :
+      //  cos (psi), cos (phi1) sin (psi), sin (phi1) sin (psi)
+      // (-r) (Vector3D.plusI) coordinates are :
+      // cos (psi), -sin (psi) cos (phi2), sin (psi) sin (phi2)
+      // and we can choose to have psi in the interval [0 ; PI]
+      Vector3D v1 = applyTo(Vector3D.PLUS_I);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_I);
+      if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(false);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getZ(), v1.getY()),
+        FastMath.acos(v2.getX()),
+        FastMath.atan2(v2.getZ(), -v2.getY())
+      };
+
+    } else if (order == RotationOrder.YXY) {
+
+      // r (Vector3D.plusJ) coordinates are :
+      //  sin (theta1) sin (phi), cos (phi), cos (theta1) sin (phi)
+      // (-r) (Vector3D.plusJ) coordinates are :
+      // sin (phi) sin (theta2), cos (phi), -sin (phi) cos (theta2)
+      // and we can choose to have phi in the interval [0 ; PI]
+      Vector3D v1 = applyTo(Vector3D.PLUS_J);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_J);
+      if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(false);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getX(), v1.getZ()),
+        FastMath.acos(v2.getY()),
+        FastMath.atan2(v2.getX(), -v2.getZ())
+      };
+
+    } else if (order == RotationOrder.YZY) {
+
+      // r (Vector3D.plusJ) coordinates are :
+      //  -cos (theta1) sin (psi), cos (psi), sin (theta1) sin (psi)
+      // (-r) (Vector3D.plusJ) coordinates are :
+      // sin (psi) cos (theta2), cos (psi), sin (psi) sin (theta2)
+      // and we can choose to have psi in the interval [0 ; PI]
+      Vector3D v1 = applyTo(Vector3D.PLUS_J);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_J);
+      if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(false);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getZ(), -v1.getX()),
+        FastMath.acos(v2.getY()),
+        FastMath.atan2(v2.getZ(), v2.getX())
+      };
+
+    } else if (order == RotationOrder.ZXZ) {
+
+      // r (Vector3D.plusK) coordinates are :
+      //  sin (psi1) sin (phi), -cos (psi1) sin (phi), cos (phi)
+      // (-r) (Vector3D.plusK) coordinates are :
+      // sin (phi) sin (psi2), sin (phi) cos (psi2), cos (phi)
+      // and we can choose to have phi in the interval [0 ; PI]
+      Vector3D v1 = applyTo(Vector3D.PLUS_K);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_K);
+      if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(false);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getX(), -v1.getY()),
+        FastMath.acos(v2.getZ()),
+        FastMath.atan2(v2.getX(), v2.getY())
+      };
+
+    } else { // last possibility is ZYZ
+
+      // r (Vector3D.plusK) coordinates are :
+      //  cos (psi1) sin (theta), sin (psi1) sin (theta), cos (theta)
+      // (-r) (Vector3D.plusK) coordinates are :
+      // -sin (theta) cos (psi2), sin (theta) sin (psi2), cos (theta)
+      // and we can choose to have theta in the interval [0 ; PI]
+      Vector3D v1 = applyTo(Vector3D.PLUS_K);
+      Vector3D v2 = applyInverseTo(Vector3D.PLUS_K);
+      if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) {
+        throw new CardanEulerSingularityException(false);
+      }
+      return new double[] {
+        FastMath.atan2(v1.getY(), v1.getX()),
+        FastMath.acos(v2.getZ()),
+        FastMath.atan2(v2.getY(), -v2.getX())
+      };
+
+    }
+
+  }
+
+  /** Get the 3X3 matrix corresponding to the instance
+   * @return the matrix corresponding to the instance
+   */
+  public double[][] getMatrix() {
+
+    // products
+    double q0q0  = q0 * q0;
+    double q0q1  = q0 * q1;
+    double q0q2  = q0 * q2;
+    double q0q3  = q0 * q3;
+    double q1q1  = q1 * q1;
+    double q1q2  = q1 * q2;
+    double q1q3  = q1 * q3;
+    double q2q2  = q2 * q2;
+    double q2q3  = q2 * q3;
+    double q3q3  = q3 * q3;
+
+    // create the matrix
+    double[][] m = new double[3][];
+    m[0] = new double[3];
+    m[1] = new double[3];
+    m[2] = new double[3];
+
+    m [0][0] = 2.0 * (q0q0 + q1q1) - 1.0;
+    m [1][0] = 2.0 * (q1q2 - q0q3);
+    m [2][0] = 2.0 * (q1q3 + q0q2);
+
+    m [0][1] = 2.0 * (q1q2 + q0q3);
+    m [1][1] = 2.0 * (q0q0 + q2q2) - 1.0;
+    m [2][1] = 2.0 * (q2q3 - q0q1);
+
+    m [0][2] = 2.0 * (q1q3 - q0q2);
+    m [1][2] = 2.0 * (q2q3 + q0q1);
+    m [2][2] = 2.0 * (q0q0 + q3q3) - 1.0;
+
+    return m;
+
+  }
+
+  /** Apply the rotation to a vector.
+   * @param u vector to apply the rotation to
+   * @return a new vector which is the image of u by the rotation
+   */
+  public Vector3D applyTo(Vector3D u) {
+
+    double x = u.getX();
+    double y = u.getY();
+    double z = u.getZ();
+
+    double s = q1 * x + q2 * y + q3 * z;
+
+    return new Vector3D(2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x,
+                        2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y,
+                        2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z);
+
+  }
+
+  /** Apply the inverse of the rotation to a vector.
+   * @param u vector to apply the inverse of the rotation to
+   * @return a new vector which such that u is its image by the rotation
+   */
+  public Vector3D applyInverseTo(Vector3D u) {
+
+    double x = u.getX();
+    double y = u.getY();
+    double z = u.getZ();
+
+    double s = q1 * x + q2 * y + q3 * z;
+    double m0 = -q0;
+
+    return new Vector3D(2 * (m0 * (x * m0 - (q2 * z - q3 * y)) + s * q1) - x,
+                        2 * (m0 * (y * m0 - (q3 * x - q1 * z)) + s * q2) - y,
+                        2 * (m0 * (z * m0 - (q1 * y - q2 * x)) + s * q3) - z);
+
+  }
+
+  /** Apply the instance to another rotation.
+   * Applying the instance to a rotation is computing the composition
+   * in an order compliant with the following rule : let u be any
+   * vector and v its image by r (i.e. r.applyTo(u) = v), let w be the image
+   * of v by the instance (i.e. applyTo(v) = w), then w = comp.applyTo(u),
+   * where comp = applyTo(r).
+   * @param r rotation to apply the rotation to
+   * @return a new rotation which is the composition of r by the instance
+   */
+  public Rotation applyTo(Rotation r) {
+    return new Rotation(r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3),
+                        r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2),
+                        r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3),
+                        r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1),
+                        false);
+  }
+
+  /** Apply the inverse of the instance to another rotation.
+   * Applying the inverse of the instance to a rotation is computing
+   * the composition in an order compliant with the following rule :
+   * let u be any vector and v its image by r (i.e. r.applyTo(u) = v),
+   * let w be the inverse image of v by the instance
+   * (i.e. applyInverseTo(v) = w), then w = comp.applyTo(u), where
+   * comp = applyInverseTo(r).
+   * @param r rotation to apply the rotation to
+   * @return a new rotation which is the composition of r by the inverse
+   * of the instance
+   */
+  public Rotation applyInverseTo(Rotation r) {
+    return new Rotation(-r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3),
+                        -r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2),
+                        -r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3),
+                        -r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1),
+                        false);
+  }
+
+  /** Perfect orthogonality on a 3X3 matrix.
+   * @param m initial matrix (not exactly orthogonal)
+   * @param threshold convergence threshold for the iterative
+   * orthogonality correction (convergence is reached when the
+   * difference between two steps of the Frobenius norm of the
+   * correction is below this threshold)
+   * @return an orthogonal matrix close to m
+   * @exception NotARotationMatrixException if the matrix cannot be
+   * orthogonalized with the given threshold after 10 iterations
+   */
+  private double[][] orthogonalizeMatrix(double[][] m, double threshold)
+    throws NotARotationMatrixException {
+    double[] m0 = m[0];
+    double[] m1 = m[1];
+    double[] m2 = m[2];
+    double x00 = m0[0];
+    double x01 = m0[1];
+    double x02 = m0[2];
+    double x10 = m1[0];
+    double x11 = m1[1];
+    double x12 = m1[2];
+    double x20 = m2[0];
+    double x21 = m2[1];
+    double x22 = m2[2];
+    double fn = 0;
+    double fn1;
+
+    double[][] o = new double[3][3];
+    double[] o0 = o[0];
+    double[] o1 = o[1];
+    double[] o2 = o[2];
+
+    // iterative correction: Xn+1 = Xn - 0.5 * (Xn.Mt.Xn - M)
+    int i = 0;
+    while (++i < 11) {
+
+      // Mt.Xn
+      double mx00 = m0[0] * x00 + m1[0] * x10 + m2[0] * x20;
+      double mx10 = m0[1] * x00 + m1[1] * x10 + m2[1] * x20;
+      double mx20 = m0[2] * x00 + m1[2] * x10 + m2[2] * x20;
+      double mx01 = m0[0] * x01 + m1[0] * x11 + m2[0] * x21;
+      double mx11 = m0[1] * x01 + m1[1] * x11 + m2[1] * x21;
+      double mx21 = m0[2] * x01 + m1[2] * x11 + m2[2] * x21;
+      double mx02 = m0[0] * x02 + m1[0] * x12 + m2[0] * x22;
+      double mx12 = m0[1] * x02 + m1[1] * x12 + m2[1] * x22;
+      double mx22 = m0[2] * x02 + m1[2] * x12 + m2[2] * x22;
+
+      // Xn+1
+      o0[0] = x00 - 0.5 * (x00 * mx00 + x01 * mx10 + x02 * mx20 - m0[0]);
+      o0[1] = x01 - 0.5 * (x00 * mx01 + x01 * mx11 + x02 * mx21 - m0[1]);
+      o0[2] = x02 - 0.5 * (x00 * mx02 + x01 * mx12 + x02 * mx22 - m0[2]);
+      o1[0] = x10 - 0.5 * (x10 * mx00 + x11 * mx10 + x12 * mx20 - m1[0]);
+      o1[1] = x11 - 0.5 * (x10 * mx01 + x11 * mx11 + x12 * mx21 - m1[1]);
+      o1[2] = x12 - 0.5 * (x10 * mx02 + x11 * mx12 + x12 * mx22 - m1[2]);
+      o2[0] = x20 - 0.5 * (x20 * mx00 + x21 * mx10 + x22 * mx20 - m2[0]);
+      o2[1] = x21 - 0.5 * (x20 * mx01 + x21 * mx11 + x22 * mx21 - m2[1]);
+      o2[2] = x22 - 0.5 * (x20 * mx02 + x21 * mx12 + x22 * mx22 - m2[2]);
+
+      // correction on each elements
+      double corr00 = o0[0] - m0[0];
+      double corr01 = o0[1] - m0[1];
+      double corr02 = o0[2] - m0[2];
+      double corr10 = o1[0] - m1[0];
+      double corr11 = o1[1] - m1[1];
+      double corr12 = o1[2] - m1[2];
+      double corr20 = o2[0] - m2[0];
+      double corr21 = o2[1] - m2[1];
+      double corr22 = o2[2] - m2[2];
+
+      // Frobenius norm of the correction
+      fn1 = corr00 * corr00 + corr01 * corr01 + corr02 * corr02 +
+            corr10 * corr10 + corr11 * corr11 + corr12 * corr12 +
+            corr20 * corr20 + corr21 * corr21 + corr22 * corr22;
+
+      // convergence test
+      if (FastMath.abs(fn1 - fn) <= threshold)
+        return o;
+
+      // prepare next iteration
+      x00 = o0[0];
+      x01 = o0[1];
+      x02 = o0[2];
+      x10 = o1[0];
+      x11 = o1[1];
+      x12 = o1[2];
+      x20 = o2[0];
+      x21 = o2[1];
+      x22 = o2[2];
+      fn  = fn1;
+
+    }
+
+    // the algorithm did not converge after 10 iterations
+    throw new NotARotationMatrixException(
+            LocalizedFormats.UNABLE_TO_ORTHOGONOLIZE_MATRIX,
+            i - 1);
+  }
+
+  /** Compute the <i>distance</i> between two rotations.
+   * <p>The <i>distance</i> is intended here as a way to check if two
+   * rotations are almost similar (i.e. they transform vectors the same way)
+   * or very different. It is mathematically defined as the angle of
+   * the rotation r that prepended to one of the rotations gives the other
+   * one:</p>
+   * <pre>
+   *        r<sub>1</sub>(r) = r<sub>2</sub>
+   * </pre>
+   * <p>This distance is an angle between 0 and &pi;. Its value is the smallest
+   * possible upper bound of the angle in radians between r<sub>1</sub>(v)
+   * and r<sub>2</sub>(v) for all possible vectors v. This upper bound is
+   * reached for some v. The distance is equal to 0 if and only if the two
+   * rotations are identical.</p>
+   * <p>Comparing two rotations should always be done using this value rather
+   * than for example comparing the components of the quaternions. It is much
+   * more stable, and has a geometric meaning. Also comparing quaternions
+   * components is error prone since for example quaternions (0.36, 0.48, -0.48, -0.64)
+   * and (-0.36, -0.48, 0.48, 0.64) represent exactly the same rotation despite
+   * their components are different (they are exact opposites).</p>
+   * @param r1 first rotation
+   * @param r2 second rotation
+   * @return <i>distance</i> between r1 and r2
+   */
+  public static double distance(Rotation r1, Rotation r2) {
+      return r1.applyInverseTo(r2).getAngle();
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/geometry/RotationOrder.java b/src/main/java/org/apache/commons/math/geometry/RotationOrder.java
new file mode 100644
index 0000000..9292b14
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/RotationOrder.java
@@ -0,0 +1,175 @@
+/*
+ * 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.geometry;
+
+/**
+ * This class is a utility representing a rotation order specification
+ * for Cardan or Euler angles specification.
+ *
+ * This class cannot be instanciated by the user. He can only use one
+ * of the twelve predefined supported orders as an argument to either
+ * the {@link Rotation#Rotation(RotationOrder,double,double,double)}
+ * constructor or the {@link Rotation#getAngles} method.
+ *
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ */
+public final class RotationOrder {
+
+    /** Set of Cardan angles.
+     * this ordered set of rotations is around X, then around Y, then
+     * around Z
+     */
+    public static final RotationOrder XYZ =
+      new RotationOrder("XYZ", Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_K);
+
+    /** Set of Cardan angles.
+     * this ordered set of rotations is around X, then around Z, then
+     * around Y
+     */
+    public static final RotationOrder XZY =
+      new RotationOrder("XZY", Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_J);
+
+    /** Set of Cardan angles.
+     * this ordered set of rotations is around Y, then around X, then
+     * around Z
+     */
+    public static final RotationOrder YXZ =
+      new RotationOrder("YXZ", Vector3D.PLUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K);
+
+    /** Set of Cardan angles.
+     * this ordered set of rotations is around Y, then around Z, then
+     * around X
+     */
+    public static final RotationOrder YZX =
+      new RotationOrder("YZX", Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I);
+
+    /** Set of Cardan angles.
+     * this ordered set of rotations is around Z, then around X, then
+     * around Y
+     */
+    public static final RotationOrder ZXY =
+      new RotationOrder("ZXY", Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J);
+
+    /** Set of Cardan angles.
+     * this ordered set of rotations is around Z, then around Y, then
+     * around X
+     */
+    public static final RotationOrder ZYX =
+      new RotationOrder("ZYX", Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_I);
+
+    /** Set of Euler angles.
+     * this ordered set of rotations is around X, then around Y, then
+     * around X
+     */
+    public static final RotationOrder XYX =
+      new RotationOrder("XYX", Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_I);
+
+    /** Set of Euler angles.
+     * this ordered set of rotations is around X, then around Z, then
+     * around X
+     */
+    public static final RotationOrder XZX =
+      new RotationOrder("XZX", Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_I);
+
+    /** Set of Euler angles.
+     * this ordered set of rotations is around Y, then around X, then
+     * around Y
+     */
+    public static final RotationOrder YXY =
+      new RotationOrder("YXY", Vector3D.PLUS_J, Vector3D.PLUS_I, Vector3D.PLUS_J);
+
+    /** Set of Euler angles.
+     * this ordered set of rotations is around Y, then around Z, then
+     * around Y
+     */
+    public static final RotationOrder YZY =
+      new RotationOrder("YZY", Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_J);
+
+    /** Set of Euler angles.
+     * this ordered set of rotations is around Z, then around X, then
+     * around Z
+     */
+    public static final RotationOrder ZXZ =
+      new RotationOrder("ZXZ", Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_K);
+
+    /** Set of Euler angles.
+     * this ordered set of rotations is around Z, then around Y, then
+     * around Z
+     */
+    public static final RotationOrder ZYZ =
+      new RotationOrder("ZYZ", Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_K);
+
+    /** Name of the rotations order. */
+    private final String name;
+
+    /** Axis of the first rotation. */
+    private final Vector3D a1;
+
+    /** Axis of the second rotation. */
+    private final Vector3D a2;
+
+    /** Axis of the third rotation. */
+    private final Vector3D a3;
+
+    /** Private constructor.
+     * This is a utility class that cannot be instantiated by the user,
+     * so its only constructor is private.
+     * @param name name of the rotation order
+     * @param a1 axis of the first rotation
+     * @param a2 axis of the second rotation
+     * @param a3 axis of the third rotation
+     */
+    private RotationOrder(final String name,
+                          final Vector3D a1, final Vector3D a2, final Vector3D a3) {
+        this.name = name;
+        this.a1   = a1;
+        this.a2   = a2;
+        this.a3   = a3;
+    }
+
+    /** Get a string representation of the instance.
+     * @return a string representation of the instance (in fact, its name)
+     */
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    /** Get the axis of the first rotation.
+     * @return axis of the first rotation
+     */
+    public Vector3D getA1() {
+        return a1;
+    }
+
+    /** Get the axis of the second rotation.
+     * @return axis of the second rotation
+     */
+    public Vector3D getA2() {
+        return a2;
+    }
+
+    /** Get the axis of the second rotation.
+     * @return axis of the second rotation
+     */
+    public Vector3D getA3() {
+        return a3;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/geometry/Vector3D.java b/src/main/java/org/apache/commons/math/geometry/Vector3D.java
new file mode 100644
index 0000000..db18795
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/Vector3D.java
@@ -0,0 +1,534 @@
+/*
+ * 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.geometry;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements vectors in a three-dimensional space.
+ * <p>Instance of this class are guaranteed to be immutable.</p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ */
+
+public class Vector3D
+  implements Serializable {
+
+  /** Null vector (coordinates: 0, 0, 0). */
+  public static final Vector3D ZERO   = new Vector3D(0, 0, 0);
+
+  /** First canonical vector (coordinates: 1, 0, 0). */
+  public static final Vector3D PLUS_I = new Vector3D(1, 0, 0);
+
+  /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */
+  public static final Vector3D MINUS_I = new Vector3D(-1, 0, 0);
+
+  /** Second canonical vector (coordinates: 0, 1, 0). */
+  public static final Vector3D PLUS_J = new Vector3D(0, 1, 0);
+
+  /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */
+  public static final Vector3D MINUS_J = new Vector3D(0, -1, 0);
+
+  /** Third canonical vector (coordinates: 0, 0, 1). */
+  public static final Vector3D PLUS_K = new Vector3D(0, 0, 1);
+
+  /** Opposite of the third canonical vector (coordinates: 0, 0, -1).  */
+  public static final Vector3D MINUS_K = new Vector3D(0, 0, -1);
+
+  // CHECKSTYLE: stop ConstantName
+  /** A vector with all coordinates set to NaN. */
+  public static final Vector3D NaN = new Vector3D(Double.NaN, Double.NaN, Double.NaN);
+  // CHECKSTYLE: resume ConstantName
+
+  /** A vector with all coordinates set to positive infinity. */
+  public static final Vector3D POSITIVE_INFINITY =
+      new Vector3D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
+
+  /** A vector with all coordinates set to negative infinity. */
+  public static final Vector3D NEGATIVE_INFINITY =
+      new Vector3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
+
+  /** Default format. */
+  private static final Vector3DFormat DEFAULT_FORMAT =
+      Vector3DFormat.getInstance();
+
+  /** Serializable version identifier. */
+  private static final long serialVersionUID = 5133268763396045979L;
+
+  /** Abscissa. */
+  private final double x;
+
+  /** Ordinate. */
+  private final double y;
+
+  /** Height. */
+  private final double z;
+
+  /** Simple constructor.
+   * Build a vector from its coordinates
+   * @param x abscissa
+   * @param y ordinate
+   * @param z height
+   * @see #getX()
+   * @see #getY()
+   * @see #getZ()
+   */
+  public Vector3D(double x, double y, double z) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+  }
+
+  /** Simple constructor.
+   * Build a vector from its azimuthal coordinates
+   * @param alpha azimuth (&alpha;) around Z
+   *              (0 is +X, &pi;/2 is +Y, &pi; is -X and 3&pi;/2 is -Y)
+   * @param delta elevation (&delta;) above (XY) plane, from -&pi;/2 to +&pi;/2
+   * @see #getAlpha()
+   * @see #getDelta()
+   */
+  public Vector3D(double alpha, double delta) {
+    double cosDelta = FastMath.cos(delta);
+    this.x = FastMath.cos(alpha) * cosDelta;
+    this.y = FastMath.sin(alpha) * cosDelta;
+    this.z = FastMath.sin(delta);
+  }
+
+  /** Multiplicative constructor
+   * Build a vector from another one and a scale factor.
+   * The vector built will be a * u
+   * @param a scale factor
+   * @param u base (unscaled) vector
+   */
+  public Vector3D(double a, Vector3D u) {
+    this.x = a * u.x;
+    this.y = a * u.y;
+    this.z = a * u.z;
+  }
+
+  /** Linear constructor
+   * Build a vector from two other ones and corresponding scale factors.
+   * The vector built will be a1 * u1 + a2 * u2
+   * @param a1 first scale factor
+   * @param u1 first base (unscaled) vector
+   * @param a2 second scale factor
+   * @param u2 second base (unscaled) vector
+   */
+  public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2) {
+    this.x = a1 * u1.x + a2 * u2.x;
+    this.y = a1 * u1.y + a2 * u2.y;
+    this.z = a1 * u1.z + a2 * u2.z;
+  }
+
+  /** Linear constructor
+   * Build a vector from three other ones and corresponding scale factors.
+   * The vector built will be a1 * u1 + a2 * u2 + a3 * u3
+   * @param a1 first scale factor
+   * @param u1 first base (unscaled) vector
+   * @param a2 second scale factor
+   * @param u2 second base (unscaled) vector
+   * @param a3 third scale factor
+   * @param u3 third base (unscaled) vector
+   */
+  public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2,
+                  double a3, Vector3D u3) {
+    this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
+    this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y;
+    this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z;
+  }
+
+  /** Linear constructor
+   * Build a vector from four other ones and corresponding scale factors.
+   * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
+   * @param a1 first scale factor
+   * @param u1 first base (unscaled) vector
+   * @param a2 second scale factor
+   * @param u2 second base (unscaled) vector
+   * @param a3 third scale factor
+   * @param u3 third base (unscaled) vector
+   * @param a4 fourth scale factor
+   * @param u4 fourth base (unscaled) vector
+   */
+  public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2,
+                  double a3, Vector3D u3, double a4, Vector3D u4) {
+    this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
+    this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y + a4 * u4.y;
+    this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z + a4 * u4.z;
+  }
+
+  /** Get the abscissa of the vector.
+   * @return abscissa of the vector
+   * @see #Vector3D(double, double, double)
+   */
+  public double getX() {
+    return x;
+  }
+
+  /** Get the ordinate of the vector.
+   * @return ordinate of the vector
+   * @see #Vector3D(double, double, double)
+   */
+  public double getY() {
+    return y;
+  }
+
+  /** Get the height of the vector.
+   * @return height of the vector
+   * @see #Vector3D(double, double, double)
+   */
+  public double getZ() {
+    return z;
+  }
+
+  /** Get the L<sub>1</sub> norm for the vector.
+   * @return L<sub>1</sub> norm for the vector
+   */
+  public double getNorm1() {
+    return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z);
+  }
+
+  /** Get the L<sub>2</sub> norm for the vector.
+   * @return euclidian norm for the vector
+   */
+  public double getNorm() {
+    return FastMath.sqrt (x * x + y * y + z * z);
+  }
+
+  /** Get the square of the norm for the vector.
+   * @return square of the euclidian norm for the vector
+   */
+  public double getNormSq() {
+    return x * x + y * y + z * z;
+  }
+
+  /** Get the L<sub>&infin;</sub> norm for the vector.
+   * @return L<sub>&infin;</sub> norm for the vector
+   */
+  public double getNormInf() {
+    return FastMath.max(FastMath.max(FastMath.abs(x), FastMath.abs(y)), FastMath.abs(z));
+  }
+
+  /** Get the azimuth of the vector.
+   * @return azimuth (&alpha;) of the vector, between -&pi; and +&pi;
+   * @see #Vector3D(double, double)
+   */
+  public double getAlpha() {
+    return FastMath.atan2(y, x);
+  }
+
+  /** Get the elevation of the vector.
+   * @return elevation (&delta;) of the vector, between -&pi;/2 and +&pi;/2
+   * @see #Vector3D(double, double)
+   */
+  public double getDelta() {
+    return FastMath.asin(z / getNorm());
+  }
+
+  /** Add a vector to the instance.
+   * @param v vector to add
+   * @return a new vector
+   */
+  public Vector3D add(Vector3D v) {
+    return new Vector3D(x + v.x, y + v.y, z + v.z);
+  }
+
+  /** Add a scaled vector to the instance.
+   * @param factor scale factor to apply to v before adding it
+   * @param v vector to add
+   * @return a new vector
+   */
+  public Vector3D add(double factor, Vector3D v) {
+    return new Vector3D(x + factor * v.x, y + factor * v.y, z + factor * v.z);
+  }
+
+  /** Subtract a vector from the instance.
+   * @param v vector to subtract
+   * @return a new vector
+   */
+  public Vector3D subtract(Vector3D v) {
+    return new Vector3D(x - v.x, y - v.y, z - v.z);
+  }
+
+  /** Subtract a scaled vector from the instance.
+   * @param factor scale factor to apply to v before subtracting it
+   * @param v vector to subtract
+   * @return a new vector
+   */
+  public Vector3D subtract(double factor, Vector3D v) {
+    return new Vector3D(x - factor * v.x, y - factor * v.y, z - factor * v.z);
+  }
+
+  /** Get a normalized vector aligned with the instance.
+   * @return a new normalized vector
+   * @exception ArithmeticException if the norm is zero
+   */
+  public Vector3D normalize() {
+    double s = getNorm();
+    if (s == 0) {
+      throw MathRuntimeException.createArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
+    }
+    return scalarMultiply(1 / s);
+  }
+
+  /** Get a vector orthogonal to the instance.
+   * <p>There are an infinite number of normalized vectors orthogonal
+   * to the instance. This method picks up one of them almost
+   * arbitrarily. It is useful when one needs to compute a reference
+   * frame with one of the axes in a predefined direction. The
+   * following example shows how to build a frame having the k axis
+   * aligned with the known vector u :
+   * <pre><code>
+   *   Vector3D k = u.normalize();
+   *   Vector3D i = k.orthogonal();
+   *   Vector3D j = Vector3D.crossProduct(k, i);
+   * </code></pre></p>
+   * @return a new normalized vector orthogonal to the instance
+   * @exception ArithmeticException if the norm of the instance is null
+   */
+  public Vector3D orthogonal() {
+
+    double threshold = 0.6 * getNorm();
+    if (threshold == 0) {
+      throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM);
+    }
+
+    if ((x >= -threshold) && (x <= threshold)) {
+      double inverse  = 1 / FastMath.sqrt(y * y + z * z);
+      return new Vector3D(0, inverse * z, -inverse * y);
+    } else if ((y >= -threshold) && (y <= threshold)) {
+      double inverse  = 1 / FastMath.sqrt(x * x + z * z);
+      return new Vector3D(-inverse * z, 0, inverse * x);
+    }
+    double inverse  = 1 / FastMath.sqrt(x * x + y * y);
+    return new Vector3D(inverse * y, -inverse * x, 0);
+
+  }
+
+  /** Compute the angular separation between two vectors.
+   * <p>This method computes the angular separation between two
+   * vectors using the dot product for well separated vectors and the
+   * cross product for almost aligned vectors. This allows to have a
+   * good accuracy in all cases, even for vectors very close to each
+   * other.</p>
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return angular separation between v1 and v2
+   * @exception ArithmeticException if either vector has a null norm
+   */
+  public static double angle(Vector3D v1, Vector3D v2) {
+
+    double normProduct = v1.getNorm() * v2.getNorm();
+    if (normProduct == 0) {
+      throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM);
+    }
+
+    double dot = dotProduct(v1, v2);
+    double threshold = normProduct * 0.9999;
+    if ((dot < -threshold) || (dot > threshold)) {
+      // the vectors are almost aligned, compute using the sine
+      Vector3D v3 = crossProduct(v1, v2);
+      if (dot >= 0) {
+        return FastMath.asin(v3.getNorm() / normProduct);
+      }
+      return FastMath.PI - FastMath.asin(v3.getNorm() / normProduct);
+    }
+
+    // the vectors are sufficiently separated to use the cosine
+    return FastMath.acos(dot / normProduct);
+
+  }
+
+  /** Get the opposite of the instance.
+   * @return a new vector which is opposite to the instance
+   */
+  public Vector3D negate() {
+    return new Vector3D(-x, -y, -z);
+  }
+
+  /** Multiply the instance by a scalar
+   * @param a scalar
+   * @return a new vector
+   */
+  public Vector3D scalarMultiply(double a) {
+    return new Vector3D(a * x, a * y, a * z);
+  }
+
+  /**
+   * 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() {
+      return Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z);
+  }
+
+  /**
+   * 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() {
+      return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y) || Double.isInfinite(z));
+  }
+
+  /**
+   * Test for the equality of two 3D vectors.
+   * <p>
+   * If all coordinates of two 3D vectors are exactly the same, and none are
+   * <code>Double.NaN</code>, the two 3D 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
+   * 3D vector are equal to <code>Double.NaN</code>, the 3D vector is equal to
+   * {@link #NaN}.
+   * </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
+   *
+   */
+  @Override
+  public boolean equals(Object other) {
+
+    if (this == other) {
+      return true;
+    }
+
+    if (other instanceof Vector3D) {
+      final Vector3D rhs = (Vector3D)other;
+      if (rhs.isNaN()) {
+          return this.isNaN();
+      }
+
+      return (x == rhs.x) && (y == rhs.y) && (z == rhs.z);
+    }
+    return false;
+  }
+
+  /**
+   * Get a hashCode for the 3D vector.
+   * <p>
+   * All NaN values have the same hash code.</p>
+   *
+   * @return a hash code value for this object
+   */
+  @Override
+  public int hashCode() {
+      if (isNaN()) {
+          return 8;
+      }
+      return 31 * (23 * MathUtils.hash(x) +  19 * MathUtils.hash(y) +  MathUtils.hash(z));
+  }
+
+  /** Compute the dot-product of two vectors.
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return the dot product v1.v2
+   */
+  public static double dotProduct(Vector3D v1, Vector3D v2) {
+    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
+  }
+
+  /** Compute the cross-product of two vectors.
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return the cross product v1 ^ v2 as a new Vector
+   */
+  public static Vector3D crossProduct(Vector3D v1, Vector3D v2) {
+    return new Vector3D(v1.y * v2.z - v1.z * v2.y,
+                        v1.z * v2.x - v1.x * v2.z,
+                        v1.x * v2.y - v1.y * v2.x);
+  }
+
+  /** Compute the distance between two vectors according to the L<sub>1</sub> norm.
+   * <p>Calling this method is equivalent to calling:
+   * <code>v1.subtract(v2).getNorm1()</code> except that no intermediate
+   * vector is built</p>
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return the distance between v1 and v2 according to the L<sub>1</sub> norm
+   */
+  public static double distance1(Vector3D v1, Vector3D v2) {
+    final double dx = FastMath.abs(v2.x - v1.x);
+    final double dy = FastMath.abs(v2.y - v1.y);
+    final double dz = FastMath.abs(v2.z - v1.z);
+    return dx + dy + dz;
+  }
+
+  /** Compute the distance between two vectors according to the L<sub>2</sub> norm.
+   * <p>Calling this method is equivalent to calling:
+   * <code>v1.subtract(v2).getNorm()</code> except that no intermediate
+   * vector is built</p>
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return the distance between v1 and v2 according to the L<sub>2</sub> norm
+   */
+  public static double distance(Vector3D v1, Vector3D v2) {
+    final double dx = v2.x - v1.x;
+    final double dy = v2.y - v1.y;
+    final double dz = v2.z - v1.z;
+    return FastMath.sqrt(dx * dx + dy * dy + dz * dz);
+  }
+
+  /** Compute the distance between two vectors according to the L<sub>&infin;</sub> norm.
+   * <p>Calling this method is equivalent to calling:
+   * <code>v1.subtract(v2).getNormInf()</code> except that no intermediate
+   * vector is built</p>
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return the distance between v1 and v2 according to the L<sub>&infin;</sub> norm
+   */
+  public static double distanceInf(Vector3D v1, Vector3D v2) {
+    final double dx = FastMath.abs(v2.x - v1.x);
+    final double dy = FastMath.abs(v2.y - v1.y);
+    final double dz = FastMath.abs(v2.z - v1.z);
+    return FastMath.max(FastMath.max(dx, dy), dz);
+  }
+
+  /** Compute the square of the distance between two vectors.
+   * <p>Calling this method is equivalent to calling:
+   * <code>v1.subtract(v2).getNormSq()</code> except that no intermediate
+   * vector is built</p>
+   * @param v1 first vector
+   * @param v2 second vector
+   * @return the square of the distance between v1 and v2
+   */
+  public static double distanceSq(Vector3D v1, Vector3D v2) {
+    final double dx = v2.x - v1.x;
+    final double dy = v2.y - v1.y;
+    final double dz = v2.z - v1.z;
+    return dx * dx + dy * dy + dz * dz;
+  }
+
+  /** Get a string representation of this vector.
+   * @return a string representation of this vector
+   */
+  @Override
+  public String toString() {
+      return DEFAULT_FORMAT.format(this);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/geometry/Vector3DFormat.java b/src/main/java/org/apache/commons/math/geometry/Vector3DFormat.java
new file mode 100644
index 0000000..7400e20
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/Vector3DFormat.java
@@ -0,0 +1,343 @@
+/*
+ * 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.geometry;
+
+import java.text.FieldPosition;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.CompositeFormat;
+
+/**
+ * Formats a 3D vector in components list format "{x; y; z}".
+ * <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by
+ * any user-defined strings. The number format for components can be configured.</p>
+ * <p>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.</p>
+ *
+ * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $
+ */
+public class Vector3DFormat extends CompositeFormat {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -5447606608652576301L;
+
+    /** 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 final NumberFormat format;
+
+    /**
+     * Create an instance with default settings.
+     * <p>The instance uses the default prefix, suffix and separator:
+     * "{", "}", and "; " and the default number format for components.</p>
+     */
+    public Vector3DFormat() {
+        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 Vector3DFormat(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 Vector3DFormat(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 Vector3DFormat(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 3D vectors formats are available.
+     * <p>This is the same set as the {@link NumberFormat} set.</p>
+     * @return available 3D 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 3D vector format for the current locale.
+     * @return the default 3D vector format.
+     */
+    public static Vector3DFormat getInstance() {
+        return getInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns the default 3D vector format for the given locale.
+     * @param locale the specific locale used by the format.
+     * @return the 3D vector format specific to the given locale.
+     */
+    public static Vector3DFormat getInstance(final Locale locale) {
+        return new Vector3DFormat(getDefaultNumberFormat(locale));
+    }
+
+    /**
+     * This static method calls {@link #format(Object)} on a default instance of
+     * Vector3DFormat.
+     *
+     * @param v Vector3D object to format
+     * @return A formatted vector
+     */
+    public static String formatVector3D(Vector3D v) {
+        return getInstance().format(v);
+    }
+
+    /**
+     * Formats a {@link Vector3D} 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(Vector3D vector, StringBuffer toAppendTo,
+                               FieldPosition pos) {
+
+        pos.setBeginIndex(0);
+        pos.setEndIndex(0);
+
+        // format prefix
+        toAppendTo.append(prefix);
+
+        // format components
+        formatDouble(vector.getX(), format, toAppendTo, pos);
+        toAppendTo.append(separator);
+        formatDouble(vector.getY(), format, toAppendTo, pos);
+        toAppendTo.append(separator);
+        formatDouble(vector.getZ(), format, toAppendTo, pos);
+
+        // format suffix
+        toAppendTo.append(suffix);
+
+        return toAppendTo;
+
+    }
+
+    /**
+     * Formats a object to produce a string.
+     * <p><code>obj</code> must be a  {@link Vector3D} object. Any other type of
+     * object will result in an {@link IllegalArgumentException} being thrown.</p>
+     * @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 <code>obj</code> is not a valid type.
+     */
+    @Override
+    public StringBuffer format(Object obj, StringBuffer toAppendTo,
+                               FieldPosition pos) {
+
+        if (obj instanceof Vector3D) {
+            return format( (Vector3D)obj, toAppendTo, pos);
+        }
+
+        throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.CANNOT_FORMAT_INSTANCE_AS_3D_VECTOR,
+                                                                  obj.getClass().getName());
+
+    }
+
+    /**
+     * Parses a string to produce a {@link Vector3D} object.
+     * @param source the string to parse
+     * @return the parsed {@link Vector3D} object.
+     * @exception ParseException if the beginning of the specified string
+     *            cannot be parsed.
+     */
+    public Vector3D parse(String source) throws ParseException {
+        ParsePosition parsePosition = new ParsePosition(0);
+        Vector3D result = parse(source, parsePosition);
+        if (parsePosition.getIndex() == 0) {
+            throw MathRuntimeException.createParseException(
+                    parsePosition.getErrorIndex(),
+                    LocalizedFormats.UNPARSEABLE_3D_VECTOR, source);
+        }
+        return result;
+    }
+
+    /**
+     * Parses a string to produce a {@link Vector3D} object.
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed {@link Vector3D} object.
+     */
+    public Vector3D parse(String source, ParsePosition pos) {
+        int initialIndex = pos.getIndex();
+
+        // parse prefix
+        parseAndIgnoreWhitespace(source, pos);
+        if (!parseFixedstring(source, trimmedPrefix, pos)) {
+            return null;
+        }
+
+        // parse X component
+        parseAndIgnoreWhitespace(source, pos);
+        Number x = parseNumber(source, format, pos);
+        if (x == null) {
+            // invalid abscissa
+            // set index back to initial, error index should already be set
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse Y component
+        parseAndIgnoreWhitespace(source, pos);
+        if (!parseFixedstring(source, trimmedSeparator, pos)) {
+            return null;
+        }
+        parseAndIgnoreWhitespace(source, pos);
+        Number y = parseNumber(source, format, pos);
+        if (y == null) {
+            // invalid ordinate
+            // set index back to initial, error index should already be set
+            pos.setIndex(initialIndex);
+            return null;
+        }
+
+        // parse Z component
+        parseAndIgnoreWhitespace(source, pos);
+        if (!parseFixedstring(source, trimmedSeparator, pos)) {
+            return null;
+        }
+        parseAndIgnoreWhitespace(source, pos);
+        Number z = parseNumber(source, format, pos);
+        if (z == null) {
+            // invalid height
+            // 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;
+        }
+
+        return new Vector3D(x.doubleValue(), y.doubleValue(), z.doubleValue());
+
+    }
+
+    /**
+     * 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)
+     */
+    @Override
+    public Object parseObject(String source, ParsePosition pos) {
+        return parse(source, pos);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/geometry/package.html b/src/main/java/org/apache/commons/math/geometry/package.html
new file mode 100644
index 0000000..d528d4a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/geometry/package.html
@@ -0,0 +1,24 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 613610 $ -->
+<body>
+<p>
+This package provides basic 3D geometry components.
+</p>
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/linear/AbstractFieldMatrix.java b/src/main/java/org/apache/commons/math/linear/AbstractFieldMatrix.java
new file mode 100644
index 0000000..d35f25f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/AbstractFieldMatrix.java
@@ -0,0 +1,1139 @@
+/*
+ * 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;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Basic implementation of {@link FieldMatrix} methods regardless of the underlying storage.
+ * <p>All the methods implemented here use {@link #getEntry(int, int)} to access
+ * matrix elements. Derived class can provide faster implementations. </p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AbstractFieldMatrix<T extends FieldElement<T>> implements FieldMatrix<T> {
+
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+
+    /**
+     * Constructor for use with Serializable
+     */
+    protected AbstractFieldMatrix() {
+        field = null;
+    }
+
+    /**
+     * Creates a matrix with no data
+     * @param field field to which the elements belong
+     */
+    protected AbstractFieldMatrix(final Field<T> field) {
+        this.field = field;
+    }
+
+    /**
+     * Create a new FieldMatrix<T> with the supplied row and column dimensions.
+     *
+     * @param field field to which the elements belong
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not positive
+     */
+    protected AbstractFieldMatrix(final Field<T> field,
+                                  final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        if (rowDimension < 1 ) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, rowDimension, 1);
+        }
+        if (columnDimension < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, columnDimension, 1);
+        }
+        this.field = field;
+    }
+
+    /**
+     * Get the elements type from an array.
+     * @param <T> the type of the field elements
+     * @param d data array
+     * @return field to which array elements belong
+     * @exception IllegalArgumentException if array is empty
+     */
+    protected static <T extends FieldElement<T>> Field<T> extractField(final T[][] d)
+        throws IllegalArgumentException {
+        if (d.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+        if (d[0].length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+        return d[0][0].getField();
+    }
+
+    /**
+     * Get the elements type from an array.
+     * @param <T> the type of the field elements
+     * @param d data array
+     * @return field to which array elements belong
+     * @exception IllegalArgumentException if array is empty
+     */
+    protected static <T extends FieldElement<T>> Field<T> extractField(final T[] d)
+        throws IllegalArgumentException {
+        if (d.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+        return d[0].getField();
+    }
+
+    /** Build an array of elements.
+     * <p>
+     * Complete arrays are filled with field.getZero()
+     * </p>
+     * @param <T> the type of the field elements
+     * @param field field to which array elements belong
+     * @param rows number of rows
+     * @param columns number of columns (may be negative to build partial
+     * arrays in the same way <code>new Field[rows][]</code> works)
+     * @return a new array
+     */
+    @SuppressWarnings("unchecked")
+    protected static <T extends FieldElement<T>> T[][] buildArray(final Field<T> field,
+                                                                  final int rows,
+                                                                  final int columns) {
+        if (columns < 0) {
+            T[] dummyRow = (T[]) Array.newInstance(field.getZero().getClass(), 0);
+            return (T[][]) Array.newInstance(dummyRow.getClass(), rows);
+        }
+        T[][] array =
+            (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { rows, columns });
+        for (int i = 0; i < array.length; ++i) {
+            Arrays.fill(array[i], field.getZero());
+        }
+        return array;
+    }
+
+    /** Build an array of elements.
+     * <p>
+     * Arrays are filled with field.getZero()
+     * </p>
+     * @param <T> the type of the field elements
+     * @param field field to which array elements belong
+     * @param length of the array
+     * @return a new array
+     */
+    protected static <T extends FieldElement<T>> T[] buildArray(final Field<T> field,
+                                                                final int length) {
+        @SuppressWarnings("unchecked") // OK because field must be correct class
+        T[] array = (T[]) Array.newInstance(field.getZero().getClass(), length);
+        Arrays.fill(array, field.getZero());
+        return array;
+    }
+
+    /** {@inheritDoc} */
+    public Field<T> getField() {
+        return field;
+    }
+
+    /** {@inheritDoc} */
+    public abstract FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException;
+
+    /** {@inheritDoc} */
+    public abstract FieldMatrix<T> copy();
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException {
+
+        // safety check
+        checkAdditionCompatible(m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col).add(m.getEntry(row, col)));
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> subtract(final FieldMatrix<T> m) throws IllegalArgumentException {
+
+        // safety check
+        checkSubtractionCompatible(m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col)));
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> scalarAdd(final T d) {
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col).add(d));
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> scalarMultiply(final T d) {
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col).multiply(d));
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> multiply(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+
+        // safety check
+        checkMultiplicationCompatible(m);
+
+        final int nRows = getRowDimension();
+        final int nCols = m.getColumnDimension();
+        final int nSum  = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(nRows, nCols);
+        for (int row = 0; row < nRows; ++row) {
+            for (int col = 0; col < nCols; ++col) {
+                T sum = field.getZero();
+                for (int i = 0; i < nSum; ++i) {
+                    sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col)));
+                }
+                out.setEntry(row, col, sum);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> preMultiply(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        return m.multiply(this);
+    }
+
+    /** {@inheritDoc} */
+    public T[][] getData() {
+
+        final T[][] data = buildArray(field, getRowDimension(), getColumnDimension());
+
+        for (int i = 0; i < data.length; ++i) {
+            final T[] dataI = data[i];
+            for (int j = 0; j < dataI.length; ++j) {
+                dataI[j] = getEntry(i, j);
+            }
+        }
+
+        return data;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow,
+                                   final int startColumn, final int endColumn)
+        throws MatrixIndexException {
+
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+
+        final FieldMatrix<T> subMatrix =
+            createMatrix(endRow - startRow + 1, endColumn - startColumn + 1);
+        for (int i = startRow; i <= endRow; ++i) {
+            for (int j = startColumn; j <= endColumn; ++j) {
+                subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j));
+            }
+        }
+
+        return subMatrix;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getSubMatrix(final int[] selectedRows, final int[] selectedColumns)
+        throws MatrixIndexException {
+
+        // safety checks
+        checkSubMatrixIndex(selectedRows, selectedColumns);
+
+        // copy entries
+        final FieldMatrix<T> subMatrix =
+            createMatrix(selectedRows.length, selectedColumns.length);
+        subMatrix.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<T>(field.getZero()) {
+
+            /** {@inheritDoc} */
+            @Override
+            public T visit(final int row, final int column, final T value) {
+                return getEntry(selectedRows[row], selectedColumns[column]);
+            }
+
+        });
+
+        return subMatrix;
+
+    }
+
+    /** {@inheritDoc} */
+    public void copySubMatrix(final int startRow, final int endRow,
+                              final int startColumn, final int endColumn,
+                              final T[][] destination)
+        throws MatrixIndexException, IllegalArgumentException {
+
+        // safety checks
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        final int rowsCount    = endRow + 1 - startRow;
+        final int columnsCount = endColumn + 1 - startColumn;
+        if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    destination.length, destination[0].length,
+                    rowsCount, columnsCount);
+        }
+
+        // copy entries
+        walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) {
+
+            /** Initial row index. */
+            private int startRow;
+
+            /** Initial column index. */
+            private int startColumn;
+
+            /** {@inheritDoc} */
+            @Override
+            public void start(final int rows, final int columns,
+                              final int startRow, final int endRow,
+                              final int startColumn, final int endColumn) {
+                this.startRow    = startRow;
+                this.startColumn = startColumn;
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void visit(final int row, final int column, final T value) {
+                destination[row - startRow][column - startColumn] = value;
+            }
+
+        }, startRow, endRow, startColumn, endColumn);
+
+    }
+
+    /** {@inheritDoc} */
+    public void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
+        throws MatrixIndexException, IllegalArgumentException {
+
+        // safety checks
+        checkSubMatrixIndex(selectedRows, selectedColumns);
+        if ((destination.length < selectedRows.length) ||
+            (destination[0].length < selectedColumns.length)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    destination.length, destination[0].length,
+                    selectedRows.length, selectedColumns.length);
+        }
+
+        // copy entries
+        for (int i = 0; i < selectedRows.length; i++) {
+            final T[] destinationI = destination[i];
+            for (int j = 0; j < selectedColumns.length; j++) {
+                destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]);
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public void setSubMatrix(final T[][] subMatrix, final int row, final int column)
+        throws MatrixIndexException {
+
+        final int nRows = subMatrix.length;
+        if (nRows == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+
+        final int nCols = subMatrix[0].length;
+        if (nCols == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+
+        for (int r = 1; r < nRows; ++r) {
+            if (subMatrix[r].length != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                        nCols, subMatrix[r].length);
+            }
+        }
+
+        checkRowIndex(row);
+        checkColumnIndex(column);
+        checkRowIndex(nRows + row - 1);
+        checkColumnIndex(nCols + column - 1);
+
+        for (int i = 0; i < nRows; ++i) {
+            for (int j = 0; j < nCols; ++j) {
+                setEntry(row + i, column + j, subMatrix[i][j]);
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getRowMatrix(final int row)
+        throws MatrixIndexException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(1, nCols);
+        for (int i = 0; i < nCols; ++i) {
+            out.setEntry(0, i, getEntry(row, i));
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setRowMatrix(final int row, final FieldMatrix<T> matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        if ((matrix.getRowDimension() != 1) ||
+            (matrix.getColumnDimension() != nCols)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols);
+        }
+        for (int i = 0; i < nCols; ++i) {
+            setEntry(row, i, matrix.getEntry(0, i));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> getColumnMatrix(final int column)
+        throws MatrixIndexException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        final FieldMatrix<T> out = createMatrix(nRows, 1);
+        for (int i = 0; i < nRows; ++i) {
+            out.setEntry(i, 0, getEntry(i, column));
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setColumnMatrix(final int column, final FieldMatrix<T> matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        if ((matrix.getRowDimension() != nRows) ||
+            (matrix.getColumnDimension() != 1)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1);
+        }
+        for (int i = 0; i < nRows; ++i) {
+            setEntry(i, column, matrix.getEntry(i, 0));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> getRowVector(final int row)
+        throws MatrixIndexException {
+        return new ArrayFieldVector<T>(getRow(row), false);
+    }
+
+    /** {@inheritDoc} */
+    public void setRowVector(final int row, final FieldVector<T> vector)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        if (vector.getDimension() != nCols) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    1, vector.getDimension(), 1, nCols);
+        }
+        for (int i = 0; i < nCols; ++i) {
+            setEntry(row, i, vector.getEntry(i));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> getColumnVector(final int column)
+        throws MatrixIndexException {
+        return new ArrayFieldVector<T>(getColumn(column), false);
+    }
+
+    /** {@inheritDoc} */
+    public void setColumnVector(final int column, final FieldVector<T> vector)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        if (vector.getDimension() != nRows) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    vector.getDimension(), 1, nRows, 1);
+        }
+        for (int i = 0; i < nRows; ++i) {
+            setEntry(i, column, vector.getEntry(i));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public T[] getRow(final int row)
+        throws MatrixIndexException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        final T[] out = buildArray(field, nCols);
+        for (int i = 0; i < nCols; ++i) {
+            out[i] = getEntry(row, i);
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setRow(final int row, final T[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        if (array.length != nCols) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    1, array.length, 1, nCols);
+        }
+        for (int i = 0; i < nCols; ++i) {
+            setEntry(row, i, array[i]);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public T[] getColumn(final int column)
+        throws MatrixIndexException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        final T[] out = buildArray(field, nRows);
+        for (int i = 0; i < nRows; ++i) {
+            out[i] = getEntry(i, column);
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setColumn(final int column, final T[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        if (array.length != nRows) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    array.length, 1, nRows, 1);
+        }
+        for (int i = 0; i < nRows; ++i) {
+            setEntry(i, column, array[i]);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public abstract T getEntry(int row, int column)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public abstract void setEntry(int row, int column, T value)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public abstract void addToEntry(int row, int column, T increment)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public abstract void multiplyEntry(int row, int column, T factor)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> transpose() {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final FieldMatrix<T> out = createMatrix(nCols, nRows);
+        walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) {
+
+            /** {@inheritDoc} */
+            @Override
+            public void visit(final int row, final int column, final T value) {
+                out.setEntry(column, row, value);
+            }
+
+        });
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public boolean isSquare() {
+        return getColumnDimension() == getRowDimension();
+    }
+
+    /** {@inheritDoc} */
+    public abstract int getRowDimension();
+
+    /** {@inheritDoc} */
+    public abstract int getColumnDimension();
+
+    /** {@inheritDoc} */
+    public T getTrace()
+        throws NonSquareMatrixException {
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (nRows != nCols) {
+            throw new NonSquareMatrixException(nRows, nCols);
+       }
+        T trace = field.getZero();
+        for (int i = 0; i < nRows; ++i) {
+            trace = trace.add(getEntry(i, i));
+        }
+        return trace;
+    }
+
+    /** {@inheritDoc} */
+    public T[] operate(final T[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nCols) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nCols);
+        }
+
+        final T[] out = buildArray(field, nRows);
+        for (int row = 0; row < nRows; ++row) {
+            T sum = field.getZero();
+            for (int i = 0; i < nCols; ++i) {
+                sum = sum.add(getEntry(row, i).multiply(v[i]));
+            }
+            out[row] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> operate(final FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return new ArrayFieldVector<T>(operate(((ArrayFieldVector<T>) v).getDataRef()), false);
+        } catch (ClassCastException cce) {
+            final int nRows = getRowDimension();
+            final int nCols = getColumnDimension();
+            if (v.getDimension() != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        v.getDimension(), nCols);
+            }
+
+            final T[] out = buildArray(field, nRows);
+            for (int row = 0; row < nRows; ++row) {
+                T sum = field.getZero();
+                for (int i = 0; i < nCols; ++i) {
+                    sum = sum.add(getEntry(row, i).multiply(v.getEntry(i)));
+                }
+                out[row] = sum;
+            }
+
+            return new ArrayFieldVector<T>(out, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public T[] preMultiply(final T[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nRows);
+        }
+
+        final T[] out = buildArray(field, nCols);
+        for (int col = 0; col < nCols; ++col) {
+            T sum = field.getZero();
+            for (int i = 0; i < nRows; ++i) {
+                sum = sum.add(getEntry(i, col).multiply(v[i]));
+            }
+            out[col] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> preMultiply(final FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return new ArrayFieldVector<T>(preMultiply(((ArrayFieldVector<T>) v).getDataRef()), false);
+        } catch (ClassCastException cce) {
+
+            final int nRows = getRowDimension();
+            final int nCols = getColumnDimension();
+            if (v.getDimension() != nRows) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        v.getDimension(), nRows);
+            }
+
+            final T[] out = buildArray(field, nCols);
+            for (int col = 0; col < nCols; ++col) {
+                T sum = field.getZero();
+                for (int i = 0; i < nRows; ++i) {
+                    sum = sum.add(getEntry(i, col).multiply(v.getEntry(i)));
+                }
+                out[col] = sum;
+            }
+
+            return new ArrayFieldVector<T>(out);
+
+        }
+    }
+
+    /** {@inheritDoc} */
+    public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int row = 0; row < rows; ++row) {
+            for (int column = 0; column < columns; ++column) {
+                final T oldValue = getEntry(row, column);
+                final T newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int row = 0; row < rows; ++row) {
+            for (int column = 0; column < columns; ++column) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
+                            final int startRow, final int endRow,
+                            final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int row = startRow; row <= endRow; ++row) {
+            for (int column = startColumn; column <= endColumn; ++column) {
+                final T oldValue = getEntry(row, column);
+                final T newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int row = startRow; row <= endRow; ++row) {
+            for (int column = startColumn; column <= endColumn; ++column) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int column = 0; column < columns; ++column) {
+            for (int row = 0; row < rows; ++row) {
+                final T oldValue = getEntry(row, column);
+                final T newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int column = 0; column < columns; ++column) {
+            for (int row = 0; row < rows; ++row) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor,
+                               final int startRow, final int endRow,
+                               final int startColumn, final int endColumn)
+    throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int column = startColumn; column <= endColumn; ++column) {
+            for (int row = startRow; row <= endRow; ++row) {
+                final T oldValue = getEntry(row, column);
+                final T newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                               final int startRow, final int endRow,
+                               final int startColumn, final int endColumn)
+    throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int column = startColumn; column <= endColumn; ++column) {
+            for (int row = startRow; row <= endRow; ++row) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        return walkInRowOrder(visitor);
+    }
+
+    /** {@inheritDoc} */
+    public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        return walkInRowOrder(visitor);
+    }
+
+    /** {@inheritDoc} */
+    public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
+    }
+
+    /** {@inheritDoc} */
+    public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
+    }
+
+    /**
+     * Get a string representation for this matrix.
+     * @return a string representation for this matrix
+     */
+    @Override
+    public String toString() {
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final StringBuilder res = new StringBuilder();
+        String fullClassName = getClass().getName();
+        String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
+        res.append(shortClassName).append("{");
+
+        for (int i = 0; i < nRows; ++i) {
+            if (i > 0) {
+                res.append(",");
+            }
+            res.append("{");
+            for (int j = 0; j < nCols; ++j) {
+                if (j > 0) {
+                    res.append(",");
+                }
+                res.append(getEntry(i, j));
+            }
+            res.append("}");
+        }
+
+        res.append("}");
+        return res.toString();
+
+    }
+
+    /**
+     * Returns true iff <code>object</code> is a
+     * <code>FieldMatrix</code> instance with the same dimensions as this
+     * and all corresponding matrix entries are equal.
+     *
+     * @param object the object to test equality against.
+     * @return true if object equals this
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this ) {
+            return true;
+        }
+        if (object instanceof FieldMatrix<?> == false) {
+            return false;
+        }
+        FieldMatrix<?> m = (FieldMatrix<?>) object;
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
+            return false;
+        }
+        for (int row = 0; row < nRows; ++row) {
+            for (int col = 0; col < nCols; ++col) {
+                if (!getEntry(row, col).equals(m.getEntry(row, col))) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Computes a hashcode for the matrix.
+     *
+     * @return hashcode for matrix
+     */
+    @Override
+    public int hashCode() {
+        int ret = 322562;
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        ret = ret * 31 + nRows;
+        ret = ret * 31 + nCols;
+        for (int row = 0; row < nRows; ++row) {
+            for (int col = 0; col < nCols; ++col) {
+               ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * getEntry(row, col).hashCode();
+           }
+        }
+        return ret;
+    }
+
+    /**
+     * Check if a row index is valid.
+     * @param row row index to check
+     * @exception MatrixIndexException if index is not valid
+     */
+    protected void checkRowIndex(final int row) {
+        if (row < 0 || row >= getRowDimension()) {
+            throw new MatrixIndexException(LocalizedFormats.ROW_INDEX_OUT_OF_RANGE,
+                                           row, 0, getRowDimension() - 1);
+        }
+    }
+
+    /**
+     * Check if a column index is valid.
+     * @param column column index to check
+     * @exception MatrixIndexException if index is not valid
+     */
+    protected void checkColumnIndex(final int column)
+        throws MatrixIndexException {
+        if (column < 0 || column >= getColumnDimension()) {
+            throw new MatrixIndexException(LocalizedFormats.COLUMN_INDEX_OUT_OF_RANGE,
+                                           column, 0, getColumnDimension() - 1);
+        }
+    }
+
+    /**
+     * Check if submatrix ranges indices are valid.
+     * Rows and columns are indicated counting from 0 to n-1.
+     *
+     * @param startRow Initial row index
+     * @param endRow Final row index
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception MatrixIndexException  if the indices are not valid
+     */
+    protected void checkSubMatrixIndex(final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn) {
+        checkRowIndex(startRow);
+        checkRowIndex(endRow);
+        if (startRow > endRow) {
+            throw new MatrixIndexException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
+                                           startRow, endRow);
+        }
+
+        checkColumnIndex(startColumn);
+        checkColumnIndex(endColumn);
+        if (startColumn > endColumn) {
+            throw new MatrixIndexException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN,
+                                           startColumn, endColumn);
+        }
+
+
+    }
+
+    /**
+     * Check if submatrix ranges indices are valid.
+     * Rows and columns are indicated counting from 0 to n-1.
+     *
+     * @param selectedRows Array of row indices.
+     * @param selectedColumns Array of column indices.
+     * @exception MatrixIndexException if row or column selections are not valid
+     */
+    protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns) {
+        if (selectedRows.length * selectedColumns.length == 0) {
+            if (selectedRows.length == 0) {
+                throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY);
+            }
+            throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY);
+        }
+
+        for (final int row : selectedRows) {
+            checkRowIndex(row);
+        }
+        for (final int column : selectedColumns) {
+            checkColumnIndex(column);
+        }
+    }
+
+    /**
+     * Check if a matrix is addition compatible with the instance
+     * @param m matrix to check
+     * @exception IllegalArgumentException if matrix is not addition compatible with instance
+     */
+    protected void checkAdditionCompatible(final FieldMatrix<T> m) {
+        if ((getRowDimension()    != m.getRowDimension()) ||
+            (getColumnDimension() != m.getColumnDimension())) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_ADDITION_COMPATIBLE_MATRICES,
+                    getRowDimension(), getColumnDimension(),
+                    m.getRowDimension(), m.getColumnDimension());
+        }
+    }
+
+    /**
+     * Check if a matrix is subtraction compatible with the instance
+     * @param m matrix to check
+     * @exception IllegalArgumentException if matrix is not subtraction compatible with instance
+     */
+    protected void checkSubtractionCompatible(final FieldMatrix<T> m) {
+        if ((getRowDimension()    != m.getRowDimension()) ||
+            (getColumnDimension() != m.getColumnDimension())) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_SUBTRACTION_COMPATIBLE_MATRICES,
+                    getRowDimension(), getColumnDimension(),
+                    m.getRowDimension(), m.getColumnDimension());
+        }
+    }
+
+    /**
+     * Check if a matrix is multiplication compatible with the instance
+     * @param m matrix to check
+     * @exception IllegalArgumentException if matrix is not multiplication compatible with instance
+     */
+    protected void checkMultiplicationCompatible(final FieldMatrix<T> m) {
+        if (getColumnDimension() != m.getRowDimension()) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_MULTIPLICATION_COMPATIBLE_MATRICES,
+                    getRowDimension(), getColumnDimension(),
+                    m.getRowDimension(), m.getColumnDimension());
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/AbstractRealMatrix.java b/src/main/java/org/apache/commons/math/linear/AbstractRealMatrix.java
new file mode 100644
index 0000000..4bf7a82
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/AbstractRealMatrix.java
@@ -0,0 +1,1071 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Basic implementation of RealMatrix methods regardless of the underlying storage.
+ * <p>All the methods implemented here use {@link #getEntry(int, int)} to access
+ * matrix elements. Derived class can provide faster implementations. </p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AbstractRealMatrix implements RealMatrix {
+
+
+    /** Cached LU solver.
+     * @deprecated as of release 2.0, since all methods using this are deprecated
+     */
+    @Deprecated
+    private DecompositionSolver lu;
+
+    /**
+     * Creates a matrix with no data
+     */
+    protected AbstractRealMatrix() {
+        lu = null;
+    }
+
+    /**
+     * Create a new RealMatrix with the supplied row and column dimensions.
+     *
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not positive
+     */
+    protected AbstractRealMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        if (rowDimension < 1 ) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, rowDimension, 1);
+        }
+        if (columnDimension <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, columnDimension, 1);
+        }
+        lu = null;
+    }
+
+    /** {@inheritDoc} */
+    public abstract RealMatrix createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException;
+
+    /** {@inheritDoc} */
+    public abstract RealMatrix copy();
+
+    /** {@inheritDoc} */
+    public RealMatrix add(RealMatrix m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final RealMatrix out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col) + m.getEntry(row, col));
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix subtract(final RealMatrix m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkSubtractionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final RealMatrix out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col) - m.getEntry(row, col));
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix scalarAdd(final double d) {
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final RealMatrix out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col) + d);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix scalarMultiply(final double d) {
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final RealMatrix out = createMatrix(rowCount, columnCount);
+        for (int row = 0; row < rowCount; ++row) {
+            for (int col = 0; col < columnCount; ++col) {
+                out.setEntry(row, col, getEntry(row, col) * d);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix multiply(final RealMatrix m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkMultiplicationCompatible(this, m);
+
+        final int nRows = getRowDimension();
+        final int nCols = m.getColumnDimension();
+        final int nSum  = getColumnDimension();
+        final RealMatrix out = createMatrix(nRows, nCols);
+        for (int row = 0; row < nRows; ++row) {
+            for (int col = 0; col < nCols; ++col) {
+                double sum = 0;
+                for (int i = 0; i < nSum; ++i) {
+                    sum += getEntry(row, i) * m.getEntry(i, col);
+                }
+                out.setEntry(row, col, sum);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix preMultiply(final RealMatrix m)
+        throws IllegalArgumentException {
+        return m.multiply(this);
+    }
+
+    /** {@inheritDoc} */
+    public double[][] getData() {
+
+        final double[][] data = new double[getRowDimension()][getColumnDimension()];
+
+        for (int i = 0; i < data.length; ++i) {
+            final double[] dataI = data[i];
+            for (int j = 0; j < dataI.length; ++j) {
+                dataI[j] = getEntry(i, j);
+            }
+        }
+
+        return data;
+
+    }
+
+    /** {@inheritDoc} */
+    public double getNorm() {
+        return walkInColumnOrder(new RealMatrixPreservingVisitor() {
+
+            /** Last row index. */
+            private double endRow;
+
+            /** Sum of absolute values on one column. */
+            private double columnSum;
+
+            /** Maximal sum across all columns. */
+            private double maxColSum;
+
+            /** {@inheritDoc} */
+            public void start(final int rows, final int columns,
+                              final int startRow, final int endRow,
+                              final int startColumn, final int endColumn) {
+                this.endRow = endRow;
+                columnSum   = 0;
+                maxColSum   = 0;
+            }
+
+            /** {@inheritDoc} */
+            public void visit(final int row, final int column, final double value) {
+                columnSum += FastMath.abs(value);
+                if (row == endRow) {
+                    maxColSum = FastMath.max(maxColSum, columnSum);
+                    columnSum = 0;
+                }
+            }
+
+            /** {@inheritDoc} */
+            public double end() {
+                return maxColSum;
+            }
+
+        });
+    }
+
+    /** {@inheritDoc} */
+    public double getFrobeniusNorm() {
+        return walkInOptimizedOrder(new RealMatrixPreservingVisitor() {
+
+            /** Sum of squared entries. */
+            private double sum;
+
+            /** {@inheritDoc} */
+            public void start(final int rows, final int columns,
+                              final int startRow, final int endRow,
+                              final int startColumn, final int endColumn) {
+                sum = 0;
+            }
+
+            /** {@inheritDoc} */
+            public void visit(final int row, final int column, final double value) {
+                sum += value * value;
+            }
+
+            /** {@inheritDoc} */
+            public double end() {
+                return FastMath.sqrt(sum);
+            }
+
+        });
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getSubMatrix(final int startRow, final int endRow,
+                                   final int startColumn, final int endColumn)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+
+        final RealMatrix subMatrix =
+            createMatrix(endRow - startRow + 1, endColumn - startColumn + 1);
+        for (int i = startRow; i <= endRow; ++i) {
+            for (int j = startColumn; j <= endColumn; ++j) {
+                subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j));
+            }
+        }
+
+        return subMatrix;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getSubMatrix(final int[] selectedRows, final int[] selectedColumns)
+        throws MatrixIndexException {
+
+        // safety checks
+        MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns);
+
+        // copy entries
+        final RealMatrix subMatrix =
+            createMatrix(selectedRows.length, selectedColumns.length);
+        subMatrix.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() {
+
+            /** {@inheritDoc} */
+            @Override
+            public double visit(final int row, final int column, final double value) {
+                return getEntry(selectedRows[row], selectedColumns[column]);
+            }
+
+        });
+
+        return subMatrix;
+
+    }
+
+    /** {@inheritDoc} */
+    public void copySubMatrix(final int startRow, final int endRow,
+                              final int startColumn, final int endColumn,
+                              final double[][] destination)
+        throws MatrixIndexException, IllegalArgumentException {
+
+        // safety checks
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        final int rowsCount    = endRow + 1 - startRow;
+        final int columnsCount = endColumn + 1 - startColumn;
+        if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    destination.length, destination[0].length,
+                    rowsCount, columnsCount);
+        }
+
+        // copy entries
+        walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
+
+            /** Initial row index. */
+            private int startRow;
+
+            /** Initial column index. */
+            private int startColumn;
+
+            /** {@inheritDoc} */
+            @Override
+            public void start(final int rows, final int columns,
+                              final int startRow, final int endRow,
+                              final int startColumn, final int endColumn) {
+                this.startRow    = startRow;
+                this.startColumn = startColumn;
+            }
+
+            /** {@inheritDoc} */
+            @Override
+            public void visit(final int row, final int column, final double value) {
+                destination[row - startRow][column - startColumn] = value;
+            }
+
+        }, startRow, endRow, startColumn, endColumn);
+
+    }
+
+    /** {@inheritDoc} */
+    public void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination)
+        throws MatrixIndexException, IllegalArgumentException {
+
+        // safety checks
+        MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns);
+        if ((destination.length < selectedRows.length) ||
+            (destination[0].length < selectedColumns.length)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    destination.length, destination[0].length,
+                    selectedRows.length, selectedColumns.length);
+        }
+
+        // copy entries
+        for (int i = 0; i < selectedRows.length; i++) {
+            final double[] destinationI = destination[i];
+            for (int j = 0; j < selectedColumns.length; j++) {
+                destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]);
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
+        throws MatrixIndexException {
+
+        final int nRows = subMatrix.length;
+        if (nRows == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+
+        final int nCols = subMatrix[0].length;
+        if (nCols == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+
+        for (int r = 1; r < nRows; ++r) {
+            if (subMatrix[r].length != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                        nCols, subMatrix[r].length);
+            }
+        }
+
+        MatrixUtils.checkRowIndex(this, row);
+        MatrixUtils.checkColumnIndex(this, column);
+        MatrixUtils.checkRowIndex(this, nRows + row - 1);
+        MatrixUtils.checkColumnIndex(this, nCols + column - 1);
+
+        for (int i = 0; i < nRows; ++i) {
+            for (int j = 0; j < nCols; ++j) {
+                setEntry(row + i, column + j, subMatrix[i][j]);
+            }
+        }
+
+        lu = null;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getRowMatrix(final int row)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        final RealMatrix out = createMatrix(1, nCols);
+        for (int i = 0; i < nCols; ++i) {
+            out.setEntry(0, i, getEntry(row, i));
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setRowMatrix(final int row, final RealMatrix matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        if ((matrix.getRowDimension() != 1) ||
+            (matrix.getColumnDimension() != nCols)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols);
+        }
+        for (int i = 0; i < nCols; ++i) {
+            setEntry(row, i, matrix.getEntry(0, i));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getColumnMatrix(final int column)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        final RealMatrix out = createMatrix(nRows, 1);
+        for (int i = 0; i < nRows; ++i) {
+            out.setEntry(i, 0, getEntry(i, column));
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setColumnMatrix(final int column, final RealMatrix matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        if ((matrix.getRowDimension() != nRows) ||
+            (matrix.getColumnDimension() != 1)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1);
+        }
+        for (int i = 0; i < nRows; ++i) {
+            setEntry(i, column, matrix.getEntry(i, 0));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public RealVector getRowVector(final int row)
+        throws MatrixIndexException {
+        return new ArrayRealVector(getRow(row), false);
+    }
+
+    /** {@inheritDoc} */
+    public void setRowVector(final int row, final RealVector vector)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        if (vector.getDimension() != nCols) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    1, vector.getDimension(), 1, nCols);
+        }
+        for (int i = 0; i < nCols; ++i) {
+            setEntry(row, i, vector.getEntry(i));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public RealVector getColumnVector(final int column)
+        throws MatrixIndexException {
+        return new ArrayRealVector(getColumn(column), false);
+    }
+
+    /** {@inheritDoc} */
+    public void setColumnVector(final int column, final RealVector vector)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        if (vector.getDimension() != nRows) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    vector.getDimension(), 1, nRows, 1);
+        }
+        for (int i = 0; i < nRows; ++i) {
+            setEntry(i, column, vector.getEntry(i));
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public double[] getRow(final int row)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        final double[] out = new double[nCols];
+        for (int i = 0; i < nCols; ++i) {
+            out[i] = getEntry(row, i);
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setRow(final int row, final double[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        if (array.length != nCols) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    1, array.length, 1, nCols);
+        }
+        for (int i = 0; i < nCols; ++i) {
+            setEntry(row, i, array[i]);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public double[] getColumn(final int column)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        final double[] out = new double[nRows];
+        for (int i = 0; i < nRows; ++i) {
+            out[i] = getEntry(i, column);
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public void setColumn(final int column, final double[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        if (array.length != nRows) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    array.length, 1, nRows, 1);
+        }
+        for (int i = 0; i < nRows; ++i) {
+            setEntry(i, column, array[i]);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public abstract double getEntry(int row, int column)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public abstract void setEntry(int row, int column, double value)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public abstract void addToEntry(int row, int column, double increment)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public abstract void multiplyEntry(int row, int column, double factor)
+        throws MatrixIndexException;
+
+    /** {@inheritDoc} */
+    public RealMatrix transpose() {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final RealMatrix out = createMatrix(nCols, nRows);
+        walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
+
+            /** {@inheritDoc} */
+            @Override
+            public void visit(final int row, final int column, final double value) {
+                out.setEntry(column, row, value);
+            }
+
+        });
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public RealMatrix inverse()
+        throws InvalidMatrixException {
+        if (lu == null) {
+            lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver();
+        }
+        return lu.getInverse();
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double getDeterminant()
+        throws InvalidMatrixException {
+        return new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getDeterminant();
+    }
+
+    /** {@inheritDoc} */
+    public boolean isSquare() {
+        return getColumnDimension() == getRowDimension();
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public boolean isSingular() {
+        if (lu == null) {
+            lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver();
+       }
+        return !lu.isNonSingular();
+    }
+
+    /** {@inheritDoc} */
+    public abstract int getRowDimension();
+
+    /** {@inheritDoc} */
+    public abstract int getColumnDimension();
+
+    /** {@inheritDoc} */
+    public double getTrace()
+        throws NonSquareMatrixException {
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (nRows != nCols) {
+            throw new NonSquareMatrixException(nRows, nCols);
+       }
+        double trace = 0;
+        for (int i = 0; i < nRows; ++i) {
+            trace += getEntry(i, i);
+        }
+        return trace;
+    }
+
+    /** {@inheritDoc} */
+    public double[] operate(final double[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nCols) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nCols);
+        }
+
+        final double[] out = new double[nRows];
+        for (int row = 0; row < nRows; ++row) {
+            double sum = 0;
+            for (int i = 0; i < nCols; ++i) {
+                sum += getEntry(row, i) * v[i];
+            }
+            out[row] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealVector operate(final RealVector v)
+        throws IllegalArgumentException {
+        try {
+            return new ArrayRealVector(operate(((ArrayRealVector) v).getDataRef()), false);
+        } catch (ClassCastException cce) {
+            final int nRows = getRowDimension();
+            final int nCols = getColumnDimension();
+            if (v.getDimension() != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        v.getDimension(), nCols);
+            }
+
+            final double[] out = new double[nRows];
+            for (int row = 0; row < nRows; ++row) {
+                double sum = 0;
+                for (int i = 0; i < nCols; ++i) {
+                    sum += getEntry(row, i) * v.getEntry(i);
+                }
+                out[row] = sum;
+            }
+
+            return new ArrayRealVector(out, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public double[] preMultiply(final double[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nRows);
+        }
+
+        final double[] out = new double[nCols];
+        for (int col = 0; col < nCols; ++col) {
+            double sum = 0;
+            for (int i = 0; i < nRows; ++i) {
+                sum += getEntry(i, col) * v[i];
+            }
+            out[col] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealVector preMultiply(final RealVector v)
+        throws IllegalArgumentException {
+        try {
+            return new ArrayRealVector(preMultiply(((ArrayRealVector) v).getDataRef()), false);
+        } catch (ClassCastException cce) {
+
+            final int nRows = getRowDimension();
+            final int nCols = getColumnDimension();
+            if (v.getDimension() != nRows) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        v.getDimension(), nRows);
+            }
+
+            final double[] out = new double[nCols];
+            for (int col = 0; col < nCols; ++col) {
+                double sum = 0;
+                for (int i = 0; i < nRows; ++i) {
+                    sum += getEntry(i, col) * v.getEntry(i);
+                }
+                out[col] = sum;
+            }
+
+            return new ArrayRealVector(out);
+
+        }
+    }
+
+    /** {@inheritDoc} */
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int row = 0; row < rows; ++row) {
+            for (int column = 0; column < columns; ++column) {
+                final double oldValue = getEntry(row, column);
+                final double newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        lu = null;
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int row = 0; row < rows; ++row) {
+            for (int column = 0; column < columns; ++column) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int row = startRow; row <= endRow; ++row) {
+            for (int column = startColumn; column <= endColumn; ++column) {
+                final double oldValue = getEntry(row, column);
+                final double newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        lu = null;
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int row = startRow; row <= endRow; ++row) {
+            for (int column = startColumn; column <= endColumn; ++column) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInColumnOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int column = 0; column < columns; ++column) {
+            for (int row = 0; row < rows; ++row) {
+                final double oldValue = getEntry(row, column);
+                final double newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        lu = null;
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int column = 0; column < columns; ++column) {
+            for (int row = 0; row < rows; ++row) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInColumnOrder(final RealMatrixChangingVisitor visitor,
+                                    final int startRow, final int endRow,
+                                    final int startColumn, final int endColumn)
+    throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int column = startColumn; column <= endColumn; ++column) {
+            for (int row = startRow; row <= endRow; ++row) {
+                final double oldValue = getEntry(row, column);
+                final double newValue = visitor.visit(row, column, oldValue);
+                setEntry(row, column, newValue);
+            }
+        }
+        lu = null;
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor,
+                                    final int startRow, final int endRow,
+                                    final int startColumn, final int endColumn)
+    throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int column = startColumn; column <= endColumn; ++column) {
+            for (int row = startRow; row <= endRow; ++row) {
+                visitor.visit(row, column, getEntry(row, column));
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        return walkInRowOrder(visitor);
+    }
+
+    /** {@inheritDoc} */
+    public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        return walkInRowOrder(visitor);
+    }
+
+    /** {@inheritDoc} */
+    public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
+    }
+
+    /** {@inheritDoc} */
+    public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public double[] solve(final double[] b)
+        throws IllegalArgumentException, InvalidMatrixException {
+        if (lu == null) {
+            lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver();
+        }
+        return lu.solve(b);
+    }
+
+    /** {@inheritDoc} */
+    @Deprecated
+    public RealMatrix solve(final RealMatrix b)
+        throws IllegalArgumentException, InvalidMatrixException  {
+        if (lu == null) {
+            lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver();
+        }
+        return lu.solve(b);
+    }
+
+    /**
+     * Computes a new
+     * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
+     * LU decomposition</a> for this matrix, storing the result for use by other methods.
+     * <p>
+     * <strong>Implementation Note</strong>:<br>
+     * Uses <a href="http://www.damtp.cam.ac.uk/user/fdl/people/sd/lectures/nummeth98/linear.htm">
+     * Crout's algorithm</a>, with partial pivoting.</p>
+     * <p>
+     * <strong>Usage Note</strong>:<br>
+     * This method should rarely be invoked directly. Its only use is
+     * to force recomputation of the LU decomposition when changes have been
+     * made to the underlying data using direct array references. Changes
+     * made using setXxx methods will trigger recomputation when needed
+     * automatically.</p>
+     *
+     * @throws InvalidMatrixException if the matrix is non-square or singular.
+     * @deprecated as of release 2.0, replaced by {@link LUDecomposition}
+     */
+    @Deprecated
+    public void luDecompose()
+        throws InvalidMatrixException {
+        if (lu == null) {
+            lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver();
+        }
+    }
+
+    /**
+     * Get a string representation for this matrix.
+     * @return a string representation for this matrix
+     */
+    @Override
+    public String toString() {
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final StringBuilder res = new StringBuilder();
+        String fullClassName = getClass().getName();
+        String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
+        res.append(shortClassName).append("{");
+
+        for (int i = 0; i < nRows; ++i) {
+            if (i > 0) {
+                res.append(",");
+            }
+            res.append("{");
+            for (int j = 0; j < nCols; ++j) {
+                if (j > 0) {
+                    res.append(",");
+                }
+                res.append(getEntry(i, j));
+            }
+            res.append("}");
+        }
+
+        res.append("}");
+        return res.toString();
+
+    }
+
+    /**
+     * Returns true iff <code>object</code> is a
+     * <code>RealMatrix</code> instance with the same dimensions as this
+     * and all corresponding matrix entries are equal.
+     *
+     * @param object the object to test equality against.
+     * @return true if object equals this
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this ) {
+            return true;
+        }
+        if (object instanceof RealMatrix == false) {
+            return false;
+        }
+        RealMatrix m = (RealMatrix) object;
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
+            return false;
+        }
+        for (int row = 0; row < nRows; ++row) {
+            for (int col = 0; col < nCols; ++col) {
+                if (getEntry(row, col) != m.getEntry(row, col)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Computes a hashcode for the matrix.
+     *
+     * @return hashcode for matrix
+     */
+    @Override
+    public int hashCode() {
+        int ret = 7;
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        ret = ret * 31 + nRows;
+        ret = ret * 31 + nCols;
+        for (int row = 0; row < nRows; ++row) {
+            for (int col = 0; col < nCols; ++col) {
+               ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) *
+                   MathUtils.hash(getEntry(row, col));
+           }
+        }
+        return ret;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
new file mode 100644
index 0000000..e39c9ce
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
@@ -0,0 +1,932 @@
+/*
+ * 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.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.MathUnsupportedOperationException;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.analysis.BinaryFunction;
+import org.apache.commons.math.analysis.ComposableFunction;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class provides default basic implementations for many methods in the
+ * {@link RealVector} interface.
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.1
+ */
+public abstract class AbstractRealVector implements RealVector {
+
+    /**
+     * Check if instance and specified vectors have the same dimension.
+     * @param v vector to compare instance with
+     * @exception DimensionMismatchException if the vectors do not
+     * have the same dimension
+     */
+    protected void checkVectorDimensions(RealVector v) {
+        checkVectorDimensions(v.getDimension());
+    }
+
+    /**
+     * Check if instance dimension is equal to some expected value.
+     *
+     * @param n expected dimension.
+     * @exception DimensionMismatchException if the dimension is
+     * inconsistent with vector size
+     */
+    protected void checkVectorDimensions(int n)
+        throws DimensionMismatchException {
+        int d = getDimension();
+        if (d != n) {
+            throw new DimensionMismatchException(d, n);
+        }
+    }
+
+    /**
+     * Check if an index is valid.
+     * @param index index to check
+     * @exception MatrixIndexException if index is not valid
+     */
+    protected void checkIndex(final int index)
+        throws MatrixIndexException {
+        if (index < 0 || index >= getDimension()) {
+            throw new MatrixIndexException(LocalizedFormats.INDEX_OUT_OF_RANGE,
+                                           index, 0, getDimension() - 1);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void setSubVector(int index, RealVector v) throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + v.getDimension() - 1);
+        setSubVector(index, v.getData());
+    }
+
+    /** {@inheritDoc} */
+    public void setSubVector(int index, double[] v) throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + v.length - 1);
+        for (int i = 0; i < v.length; i++) {
+            setEntry(i + index, v[i]);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector add(double[] v) throws IllegalArgumentException {
+        double[] result = v.clone();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            result[e.getIndex()] += e.getValue();
+        }
+        return new ArrayRealVector(result, false);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector add(RealVector v) throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            double[] values = ((ArrayRealVector)v).getDataRef();
+            return add(values);
+        }
+        RealVector result = v.copy();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final int index = e.getIndex();
+            result.setEntry(index, e.getValue() + result.getEntry(index));
+        }
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    public RealVector subtract(double[] v) throws IllegalArgumentException {
+        double[] result = v.clone();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final int index = e.getIndex();
+            result[index] = e.getValue() - result[index];
+        }
+        return new ArrayRealVector(result, false);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector subtract(RealVector v) throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            double[] values = ((ArrayRealVector)v).getDataRef();
+            return add(values);
+        }
+        RealVector result = v.copy();
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final int index = e.getIndex();
+            v.setEntry(index, e.getValue() - result.getEntry(index));
+        }
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAdd(double d) {
+        return copy().mapAddToSelf(d);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAddToSelf(double d) {
+        if (d != 0) {
+            try {
+                return mapToSelf(BinaryFunction.ADD.fix1stArgument(d));
+            } catch (FunctionEvaluationException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public abstract AbstractRealVector copy();
+
+    /** {@inheritDoc} */
+    public double dotProduct(double[] v) throws IllegalArgumentException {
+        return dotProduct(new ArrayRealVector(v, false));
+    }
+
+    /** {@inheritDoc} */
+    public double dotProduct(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d += e.getValue() * v.getEntry(e.getIndex());
+        }
+        return d;
+    }
+
+    /** {@inheritDoc} */
+    public RealVector ebeDivide(double[] v) throws IllegalArgumentException {
+        return ebeDivide(new ArrayRealVector(v, false));
+    }
+
+    /** {@inheritDoc} */
+    public RealVector ebeMultiply(double[] v) throws IllegalArgumentException {
+        return ebeMultiply(new ArrayRealVector(v, false));
+    }
+
+    /** {@inheritDoc} */
+    public double getDistance(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final double diff = e.getValue() - v.getEntry(e.getIndex());
+            d += diff * diff;
+        }
+        return FastMath.sqrt(d);
+    }
+
+    /** {@inheritDoc} */
+    public double getNorm() {
+        double sum = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            final double value = e.getValue();
+            sum += value * value;
+        }
+        return FastMath.sqrt(sum);
+    }
+
+    /** {@inheritDoc} */
+    public double getL1Norm() {
+        double norm = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            norm += FastMath.abs(e.getValue());
+        }
+        return norm;
+    }
+
+    /** {@inheritDoc} */
+    public double getLInfNorm() {
+        double norm = 0;
+        Iterator<Entry> it = sparseIterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            norm = FastMath.max(norm, FastMath.abs(e.getValue()));
+        }
+        return norm;
+    }
+
+    /** {@inheritDoc} */
+    public double getDistance(double[] v) throws IllegalArgumentException {
+        return getDistance(new ArrayRealVector(v,false));
+    }
+
+    /** {@inheritDoc} */
+    public double getL1Distance(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d += FastMath.abs(e.getValue() - v.getEntry(e.getIndex()));
+        }
+        return d;
+    }
+
+    /** {@inheritDoc} */
+    public double getL1Distance(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d += FastMath.abs(e.getValue() - v[e.getIndex()]);
+        }
+        return d;
+    }
+
+    /** {@inheritDoc} */
+    public double getLInfDistance(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d = FastMath.max(FastMath.abs(e.getValue() - v.getEntry(e.getIndex())), d);
+        }
+        return d;
+    }
+
+    /** {@inheritDoc} */
+    public double getLInfDistance(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double d = 0;
+        Iterator<Entry> it = iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            d = FastMath.max(FastMath.abs(e.getValue() - v[e.getIndex()]), d);
+        }
+        return d;
+    }
+
+    /** Get the index of the minimum entry.
+     * @return index of the minimum entry or -1 if vector length is 0
+     * or all entries are NaN
+     */
+    public int getMinIndex() {
+        int minIndex    = -1;
+        double minValue = Double.POSITIVE_INFINITY;
+        Iterator<Entry> iterator = iterator();
+        while (iterator.hasNext()) {
+            final Entry entry = iterator.next();
+            if (entry.getValue() <= minValue) {
+                minIndex = entry.getIndex();
+                minValue = entry.getValue();
+            }
+        }
+        return minIndex;
+    }
+
+    /** Get the value of the minimum entry.
+     * @return value of the minimum entry or NaN if all entries are NaN
+     */
+    public double getMinValue() {
+        final int minIndex = getMinIndex();
+        return minIndex < 0 ? Double.NaN : getEntry(minIndex);
+    }
+
+    /** Get the index of the maximum entry.
+     * @return index of the maximum entry or -1 if vector length is 0
+     * or all entries are NaN
+     */
+    public int getMaxIndex() {
+        int maxIndex    = -1;
+        double maxValue = Double.NEGATIVE_INFINITY;
+        Iterator<Entry> iterator = iterator();
+        while (iterator.hasNext()) {
+            final Entry entry = iterator.next();
+            if (entry.getValue() >= maxValue) {
+                maxIndex = entry.getIndex();
+                maxValue = entry.getValue();
+            }
+        }
+        return maxIndex;
+    }
+
+    /** Get the value of the maximum entry.
+     * @return value of the maximum entry or NaN if all entries are NaN
+     */
+    public double getMaxValue() {
+        final int maxIndex = getMaxIndex();
+        return maxIndex < 0 ? Double.NaN : getEntry(maxIndex);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAbs() {
+        return copy().mapAbsToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAbsToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.ABS);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAcos() {
+        return copy().mapAcosToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAcosToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.ACOS);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAsin() {
+        return copy().mapAsinToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAsinToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.ASIN);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAtan() {
+        return copy().mapAtanToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapAtanToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.ATAN);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCbrt() {
+        return copy().mapCbrtToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCbrtToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.CBRT);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCeil() {
+        return copy().mapCeilToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCeilToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.CEIL);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCos() {
+        return copy().mapCosToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCosToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.COS);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCosh() {
+        return copy().mapCoshToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapCoshToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.COSH);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapDivide(double d) {
+        return copy().mapDivideToSelf(d);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapDivideToSelf(double d){
+        try {
+            return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d));
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapExp() {
+        return copy().mapExpToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapExpToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.EXP);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapExpm1() {
+        return copy().mapExpm1ToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapExpm1ToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.EXPM1);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapFloor() {
+        return copy().mapFloorToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapFloorToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.FLOOR);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapInv() {
+        return copy().mapInvToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapInvToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.INVERT);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapLog() {
+        return copy().mapLogToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapLogToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.LOG);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapLog10() {
+        return copy().mapLog10ToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapLog10ToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.LOG10);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapLog1p() {
+        return copy().mapLog1pToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapLog1pToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.LOG1P);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapMultiply(double d) {
+        return copy().mapMultiplyToSelf(d);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapMultiplyToSelf(double d){
+        try {
+            return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d));
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapPow(double d) {
+        return copy().mapPowToSelf(d);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapPowToSelf(double d){
+        try {
+            return mapToSelf(BinaryFunction.POW.fix2ndArgument(d));
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapRint() {
+        return copy().mapRintToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapRintToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.RINT);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSignum() {
+        return copy().mapSignumToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSignumToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.SIGNUM);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSin() {
+        return copy().mapSinToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSinToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.SIN);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSinh() {
+        return copy().mapSinhToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSinhToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.SINH);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSqrt() {
+        return copy().mapSqrtToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSqrtToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.SQRT);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSubtract(double d) {
+        return copy().mapSubtractToSelf(d);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapSubtractToSelf(double d){
+        return mapAddToSelf(-d);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapTan() {
+        return copy().mapTanToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapTanToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.TAN);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapTanh() {
+        return copy().mapTanhToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapTanhToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.TANH);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapUlp() {
+        return copy().mapUlpToSelf();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapUlpToSelf() {
+        try {
+            return mapToSelf(ComposableFunction.ULP);
+        } catch (FunctionEvaluationException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException {
+        RealMatrix product;
+        if (v instanceof SparseRealVector || this instanceof SparseRealVector) {
+            product = new OpenMapRealMatrix(this.getDimension(), v.getDimension());
+        } else {
+            product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension());
+        }
+        Iterator<Entry> thisIt = sparseIterator();
+        Entry thisE = null;
+        while (thisIt.hasNext() && (thisE = thisIt.next()) != null) {
+            Iterator<Entry> otherIt = v.sparseIterator();
+            Entry otherE = null;
+            while (otherIt.hasNext() && (otherE = otherIt.next()) != null) {
+                product.setEntry(thisE.getIndex(), otherE.getIndex(),
+                                 thisE.getValue() * otherE.getValue());
+            }
+        }
+
+        return product;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix outerProduct(double[] v) throws IllegalArgumentException {
+        return outerProduct(new ArrayRealVector(v, false));
+    }
+
+    /** {@inheritDoc} */
+    public RealVector projection(double[] v) throws IllegalArgumentException {
+        return projection(new ArrayRealVector(v, false));
+    }
+
+    /** {@inheritDoc} */
+    public void set(double value) {
+        Iterator<Entry> it = iterator();
+        Entry e = null;
+        while (it.hasNext() && (e = it.next()) != null) {
+            e.setValue(value);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public double[] toArray() {
+        int dim = getDimension();
+        double[] values = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            values[i] = getEntry(i);
+        }
+        return values;
+    }
+
+    /** {@inheritDoc} */
+    public double[] getData() {
+        return toArray();
+    }
+
+    /** {@inheritDoc} */
+    public RealVector unitVector() {
+        RealVector copy = copy();
+        copy.unitize();
+        return copy;
+    }
+
+    /** {@inheritDoc} */
+    public void unitize() {
+        mapDivideToSelf(getNorm());
+    }
+
+    /** {@inheritDoc} */
+    public Iterator<Entry> sparseIterator() {
+        return new SparseEntryIterator();
+    }
+
+    /** {@inheritDoc} */
+    public Iterator<Entry> iterator() {
+        final int dim = getDimension();
+        return new Iterator<Entry>() {
+
+            /** Current index. */
+            private int i = 0;
+
+            /** Current entry. */
+            private EntryImpl e = new EntryImpl();
+
+            /** {@inheritDoc} */
+            public boolean hasNext() {
+                return i < dim;
+            }
+
+            /** {@inheritDoc} */
+            public Entry next() {
+                e.setIndex(i++);
+                return e;
+            }
+
+            /** {@inheritDoc} */
+            public void remove() {
+                throw new MathUnsupportedOperationException();
+            }
+        };
+    }
+
+    /** {@inheritDoc} */
+    public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException {
+        return copy().mapToSelf(function);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException {
+        Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator();
+        Entry e;
+        while (it.hasNext() && (e = it.next()) != null) {
+            e.setValue(function.value(e.getValue()));
+        }
+        return this;
+    }
+
+    /** An entry in the vector. */
+    protected class EntryImpl extends Entry {
+
+        /** Simple constructor. */
+        public EntryImpl() {
+            setIndex(0);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public double getValue() {
+            return getEntry(getIndex());
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setValue(double newValue) {
+            setEntry(getIndex(), newValue);
+        }
+    }
+
+    /**
+     * This class should rare be used, but is here to provide
+     * a default implementation of sparseIterator(), which is implemented
+     * by walking over the entries, skipping those whose values are the default one.
+     *
+     * Concrete subclasses which are SparseVector implementations should
+     * make their own sparse iterator, not use this one.
+     *
+     * This implementation might be useful for ArrayRealVector, when expensive
+     * operations which preserve the default value are to be done on the entries,
+     * and the fraction of non-default values is small (i.e. someone took a
+     * SparseVector, and passed it into the copy-constructor of ArrayRealVector)
+     */
+    protected class SparseEntryIterator implements Iterator<Entry> {
+
+        /** Dimension of the vector. */
+        private final int dim;
+
+        /** last entry returned by {@link #next()} */
+        private EntryImpl current;
+
+        /** Next entry for {@link #next()} to return. */
+        private EntryImpl next;
+
+        /** Simple constructor. */
+        protected SparseEntryIterator() {
+            dim = getDimension();
+            current = new EntryImpl();
+            next = new EntryImpl();
+            if (next.getValue() == 0) {
+                advance(next);
+            }
+        }
+
+        /** Advance an entry up to the next nonzero one.
+         * @param e entry to advance
+         */
+        protected void advance(EntryImpl e) {
+            if (e == null) {
+                return;
+            }
+            do {
+                e.setIndex(e.getIndex() + 1);
+            } while (e.getIndex() < dim && e.getValue() == 0);
+            if (e.getIndex() >= dim) {
+                e.setIndex(-1);
+            }
+        }
+
+        /** {@inheritDoc} */
+        public boolean hasNext() {
+            return next.getIndex() >= 0;
+        }
+
+        /** {@inheritDoc} */
+        public Entry next() {
+            int index = next.getIndex();
+            if (index < 0) {
+                throw new NoSuchElementException();
+            }
+            current.setIndex(index);
+            advance(next);
+            return current;
+        }
+
+        /** {@inheritDoc} */
+        public void remove() {
+            throw new MathUnsupportedOperationException();
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/AnyMatrix.java b/src/main/java/org/apache/commons/math/linear/AnyMatrix.java
new file mode 100644
index 0000000..f435e2c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/AnyMatrix.java
@@ -0,0 +1,48 @@
+/*
+ * 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 very basic matrix operations.
+ * @version $Revision: 772119 $ $Date: 2009-05-06 11:43:28 +0200 (mer. 06 mai 2009) $
+ * @since 2.0
+ */
+public interface AnyMatrix {
+
+    /**
+     * Is this a square matrix?
+     * @return true if the matrix is square (rowDimension = columnDimension)
+     */
+    boolean isSquare();
+
+    /**
+     * Returns the number of rows in the matrix.
+     *
+     * @return rowDimension
+     */
+    int getRowDimension();
+
+    /**
+     * Returns the number of columns in the matrix.
+     *
+     * @return columnDimension
+     */
+    int getColumnDimension();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/Array2DRowFieldMatrix.java b/src/main/java/org/apache/commons/math/linear/Array2DRowFieldMatrix.java
new file mode 100644
index 0000000..fdbe24b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/Array2DRowFieldMatrix.java
@@ -0,0 +1,613 @@
+/*
+ * 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 org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Implementation of FieldMatrix<T> using a {@link FieldElement}[][] array to store entries.
+ * <p>
+ * As specified in the {@link FieldMatrix} interface, matrix element indexing
+ * is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</li></ul>
+ * </p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ */
+public class Array2DRowFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 7260756672015356458L;
+
+    /** Entries of the matrix */
+    protected T[][] data;
+
+    /**
+     * Creates a matrix with no data
+     * @param field field to which the elements belong
+     */
+    public Array2DRowFieldMatrix(final Field<T> field) {
+        super(field);
+    }
+
+    /**
+     * Create a new FieldMatrix<T> with the supplied row and column dimensions.
+     *
+     * @param field field to which the elements belong
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not
+     *  positive
+     */
+    public Array2DRowFieldMatrix(final Field<T> field,
+                           final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        super(field, rowDimension, columnDimension);
+        data = buildArray(field, rowDimension, columnDimension);
+    }
+
+    /**
+     * Create a new FieldMatrix<T> using the input array as the underlying
+     * data array.
+     * <p>The input array is copied, not referenced. This constructor has
+     * the same effect as calling {@link #Array2DRowFieldMatrix(FieldElement[][], boolean)}
+     * with the second argument set to <code>true</code>.</p>
+     *
+     * @param d data for new matrix
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #Array2DRowFieldMatrix(FieldElement[][], boolean)
+     */
+    public Array2DRowFieldMatrix(final T[][] d)
+        throws IllegalArgumentException, NullPointerException {
+        super(extractField(d));
+        copyIn(d);
+    }
+
+    /**
+     * Create a new FieldMatrix<T> using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * FieldMatrix<T> 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 matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #Array2DRowFieldMatrix(FieldElement[][])
+     */
+    public Array2DRowFieldMatrix(final T[][] d, final boolean copyArray)
+        throws IllegalArgumentException, NullPointerException {
+        super(extractField(d));
+        if (copyArray) {
+            copyIn(d);
+        } else {
+            if (d == null) {
+                throw new NullPointerException();
+            }
+            final int nRows = d.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+            final int nCols = d[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            for (int r = 1; r < nRows; r++) {
+                if (d[r].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[r].length);
+                }
+            }
+            data = d;
+        }
+    }
+
+    /**
+     * Create a new (column) FieldMatrix<T> using <code>v</code> as the
+     * data for the unique column of the <code>v.length x 1</code> matrix
+     * created.
+     * <p>The input array is copied, not referenced.</p>
+     *
+     * @param v column vector holding data for new matrix
+     */
+    public Array2DRowFieldMatrix(final T[] v) {
+        super(extractField(v));
+        final int nRows = v.length;
+        data = buildArray(getField(), nRows, 1);
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = v[row];
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        return new Array2DRowFieldMatrix<T>(getField(), rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> copy() {
+        return new Array2DRowFieldMatrix<T>(copyOut(), false);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> add(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        try {
+            return add((Array2DRowFieldMatrix<T>) m);
+        } catch (ClassCastException cce) {
+            return super.add(m);
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public Array2DRowFieldMatrix<T> add(final Array2DRowFieldMatrix<T> m)
+        throws IllegalArgumentException {
+
+        // safety check
+        checkAdditionCompatible(m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final T[][] outData = buildArray(getField(), rowCount, columnCount);
+        for (int row = 0; row < rowCount; row++) {
+            final T[] dataRow    = data[row];
+            final T[] mRow       = m.data[row];
+            final T[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col].add(mRow[col]);
+            }
+        }
+
+        return new Array2DRowFieldMatrix<T>(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> subtract(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        try {
+            return subtract((Array2DRowFieldMatrix<T>) m);
+        } catch (ClassCastException cce) {
+            return super.subtract(m);
+        }
+    }
+
+    /**
+     * Compute  this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public Array2DRowFieldMatrix<T> subtract(final Array2DRowFieldMatrix<T> m)
+        throws IllegalArgumentException {
+
+        // safety check
+        checkSubtractionCompatible(m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final T[][] outData = buildArray(getField(), rowCount, columnCount);
+        for (int row = 0; row < rowCount; row++) {
+            final T[] dataRow    = data[row];
+            final T[] mRow       = m.data[row];
+            final T[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col].subtract(mRow[col]);
+            }
+        }
+
+        return new Array2DRowFieldMatrix<T>(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> multiply(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        try {
+            return multiply((Array2DRowFieldMatrix<T>) m);
+        } catch (ClassCastException cce) {
+            return super.multiply(m);
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by <code>m</code>.
+     * @param m    matrix to postmultiply by
+     * @return     this*m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public Array2DRowFieldMatrix<T> multiply(final Array2DRowFieldMatrix<T> m)
+        throws IllegalArgumentException {
+
+        // safety check
+        checkMultiplicationCompatible(m);
+
+        final int nRows = this.getRowDimension();
+        final int nCols = m.getColumnDimension();
+        final int nSum = this.getColumnDimension();
+        final T[][] outData = buildArray(getField(), nRows, nCols);
+        for (int row = 0; row < nRows; row++) {
+            final T[] dataRow    = data[row];
+            final T[] outDataRow = outData[row];
+            for (int col = 0; col < nCols; col++) {
+                T sum = getField().getZero();
+                for (int i = 0; i < nSum; i++) {
+                    sum = sum.add(dataRow[i].multiply(m.data[i][col]));
+                }
+                outDataRow[col] = sum;
+            }
+        }
+
+        return new Array2DRowFieldMatrix<T>(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[][] getData() {
+        return copyOut();
+    }
+
+    /**
+     * Returns a reference to the underlying data array.
+     * <p>
+     * Does <strong>not</strong> make a fresh copy of the underlying data.</p>
+     *
+     * @return 2-dimensional array of entries
+     */
+    public T[][] getDataRef() {
+        return data;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubMatrix(final T[][] subMatrix, final int row, final int column)
+    throws MatrixIndexException {
+        if (data == null) {
+            if (row > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                      LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row);
+            }
+            if (column > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                      LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column);
+            }
+            final int nRows = subMatrix.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+
+            final int nCols = subMatrix[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            data = buildArray(getField(), subMatrix.length, nCols);
+            for (int i = 0; i < data.length; ++i) {
+                if (subMatrix[i].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[i].length);
+                }
+                System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
+            }
+        } else {
+            super.setSubMatrix(subMatrix, row, column);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T getEntry(final int row, final int column)
+        throws MatrixIndexException {
+        try {
+            return data[row][column];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(final int row, final int column, final T value)
+        throws MatrixIndexException {
+        try {
+            data[row][column] = value;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(final int row, final int column, final T increment)
+        throws MatrixIndexException {
+        try {
+            data[row][column] = data[row][column].add(increment);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(final int row, final int column, final T factor)
+        throws MatrixIndexException {
+        try {
+            data[row][column] = data[row][column].multiply(factor);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return (data == null) ? 0 : data.length;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[] operate(final T[] v)
+        throws IllegalArgumentException {
+        final int nRows = this.getRowDimension();
+        final int nCols = this.getColumnDimension();
+        if (v.length != nCols) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols);
+        }
+        final T[] out = buildArray(getField(), nRows);
+        for (int row = 0; row < nRows; row++) {
+            final T[] dataRow = data[row];
+            T sum = getField().getZero();
+            for (int i = 0; i < nCols; i++) {
+                sum = sum.add(dataRow[i].multiply(v[i]));
+            }
+            out[row] = sum;
+        }
+        return out;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[] preMultiply(final T[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows);
+        }
+
+        final T[] out = buildArray(getField(), nCols);
+        for (int col = 0; col < nCols; ++col) {
+            T sum = getField().getZero();
+            for (int i = 0; i < nRows; ++i) {
+                sum = sum.add(data[i][col].multiply(v[i]));
+            }
+            out[col] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int i = 0; i < rows; ++i) {
+            final T[] rowI = data[i];
+            for (int j = 0; j < columns; ++j) {
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int i = 0; i < rows; ++i) {
+            final T[] rowI = data[i];
+            for (int j = 0; j < columns; ++j) {
+                visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
+                            final int startRow, final int endRow,
+                            final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int i = startRow; i <= endRow; ++i) {
+            final T[] rowI = data[i];
+            for (int j = startColumn; j <= endColumn; ++j) {
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                            final int startRow, final int endRow,
+                            final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int i = startRow; i <= endRow; ++i) {
+            final T[] rowI = data[i];
+            for (int j = startColumn; j <= endColumn; ++j) {
+                visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int j = 0; j < columns; ++j) {
+            for (int i = 0; i < rows; ++i) {
+                final T[] rowI = data[i];
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int j = 0; j < columns; ++j) {
+            for (int i = 0; i < rows; ++i) {
+                visitor.visit(i, j, data[i][j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor,
+                               final int startRow, final int endRow,
+                               final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int j = startColumn; j <= endColumn; ++j) {
+            for (int i = startRow; i <= endRow; ++i) {
+                final T[] rowI = data[i];
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                               final int startRow, final int endRow,
+                               final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int j = startColumn; j <= endColumn; ++j) {
+            for (int i = startRow; i <= endRow; ++i) {
+                visitor.visit(i, j, data[i][j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Returns a fresh copy of the underlying data array.
+     *
+     * @return a copy of the underlying data array.
+     */
+    private T[][] copyOut() {
+        final int nRows = this.getRowDimension();
+        final T[][] out = buildArray(getField(), nRows, getColumnDimension());
+        // can't copy 2-d array in one shot, otherwise get row references
+        for (int i = 0; i < nRows; i++) {
+            System.arraycopy(data[i], 0, out[i], 0, data[i].length);
+        }
+        return out;
+    }
+
+    /**
+     * Replaces data with a fresh copy of the input array.
+     * <p>
+     * Verifies that the input array is rectangular and non-empty.</p>
+     *
+     * @param in data to copy in
+     * @throws IllegalArgumentException if input array is empty or not
+     *    rectangular
+     * @throws NullPointerException if input array is null
+     */
+    private void copyIn(final T[][] in) {
+        setSubMatrix(in, 0, 0);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/Array2DRowRealMatrix.java b/src/main/java/org/apache/commons/math/linear/Array2DRowRealMatrix.java
new file mode 100644
index 0000000..5034a47
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/Array2DRowRealMatrix.java
@@ -0,0 +1,621 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Implementation of RealMatrix using a double[][] array to store entries and
+ * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
+ * LU decomposition</a> to support linear system
+ * solution and inverse.
+ * <p>
+ * The LU decomposition is performed as needed, to support the following operations: <ul>
+ * <li>solve</li>
+ * <li>isSingular</li>
+ * <li>getDeterminant</li>
+ * <li>inverse</li> </ul></p>
+ * <p>
+ * <strong>Usage notes</strong>:<br>
+ * <ul><li>
+ * The LU decomposition is cached and reused on subsequent calls.
+ * If data are modified via references to the underlying array obtained using
+ * <code>getDataRef()</code>, then the stored LU decomposition will not be
+ * discarded.  In this case, you need to explicitly invoke
+ * <code>LUDecompose()</code> to recompute the decomposition
+ * before using any of the methods above.</li>
+ * <li>
+ * As specified in the {@link RealMatrix} interface, matrix element indexing
+ * is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</li></ul>
+ * </p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ */
+public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1067294169172445528L;
+
+    /** Entries of the matrix */
+    protected double data[][];
+
+    /**
+     * Creates a matrix with no data
+     */
+    public Array2DRowRealMatrix() {
+    }
+
+    /**
+     * Create a new RealMatrix with the supplied row and column dimensions.
+     *
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not
+     *  positive
+     */
+    public Array2DRowRealMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        super(rowDimension, columnDimension);
+        data = new double[rowDimension][columnDimension];
+    }
+
+    /**
+     * Create a new RealMatrix using the input array as the underlying
+     * data array.
+     * <p>The input array is copied, not referenced. This constructor has
+     * the same effect as calling {@link #Array2DRowRealMatrix(double[][], boolean)}
+     * with the second argument set to <code>true</code>.</p>
+     *
+     * @param d data for new matrix
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #Array2DRowRealMatrix(double[][], boolean)
+     */
+    public Array2DRowRealMatrix(final double[][] d)
+        throws IllegalArgumentException, NullPointerException {
+        copyIn(d);
+    }
+
+    /**
+     * Create a new RealMatrix using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * RealMatrix 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 matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #Array2DRowRealMatrix(double[][])
+     */
+    public Array2DRowRealMatrix(final double[][] d, final boolean copyArray)
+        throws IllegalArgumentException, NullPointerException {
+        if (copyArray) {
+            copyIn(d);
+        } else {
+            if (d == null) {
+                throw new NullPointerException();
+            }
+            final int nRows = d.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+            final int nCols = d[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            for (int r = 1; r < nRows; r++) {
+                if (d[r].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, d[r].length);
+                }
+            }
+            data = d;
+        }
+    }
+
+    /**
+     * Create a new (column) RealMatrix using <code>v</code> as the
+     * data for the unique column of the <code>v.length x 1</code> matrix
+     * created.
+     * <p>The input array is copied, not referenced.</p>
+     *
+     * @param v column vector holding data for new matrix
+     */
+    public Array2DRowRealMatrix(final double[] v) {
+        final int nRows = v.length;
+        data = new double[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = v[row];
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        return new Array2DRowRealMatrix(rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix copy() {
+        return new Array2DRowRealMatrix(copyOut(), false);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix add(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return add((Array2DRowRealMatrix) m);
+        } catch (ClassCastException cce) {
+            return super.add(m);
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public Array2DRowRealMatrix add(final Array2DRowRealMatrix m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final double[][] outData = new double[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final double[] dataRow    = data[row];
+            final double[] mRow       = m.data[row];
+            final double[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col] + mRow[col];
+            }
+        }
+
+        return new Array2DRowRealMatrix(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix subtract(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return subtract((Array2DRowRealMatrix) m);
+        } catch (ClassCastException cce) {
+            return super.subtract(m);
+        }
+    }
+
+    /**
+     * Compute  this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public Array2DRowRealMatrix subtract(final Array2DRowRealMatrix m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkSubtractionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final double[][] outData = new double[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final double[] dataRow    = data[row];
+            final double[] mRow       = m.data[row];
+            final double[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col] - mRow[col];
+            }
+        }
+
+        return new Array2DRowRealMatrix(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix multiply(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return multiply((Array2DRowRealMatrix) m);
+        } catch (ClassCastException cce) {
+            return super.multiply(m);
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by <code>m</code>.
+     * @param m    matrix to postmultiply by
+     * @return     this*m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkMultiplicationCompatible(this, m);
+
+        final int nRows = this.getRowDimension();
+        final int nCols = m.getColumnDimension();
+        final int nSum = this.getColumnDimension();
+        final double[][] outData = new double[nRows][nCols];
+        for (int row = 0; row < nRows; row++) {
+            final double[] dataRow    = data[row];
+            final double[] outDataRow = outData[row];
+            for (int col = 0; col < nCols; col++) {
+                double sum = 0;
+                for (int i = 0; i < nSum; i++) {
+                    sum += dataRow[i] * m.data[i][col];
+                }
+                outDataRow[col] = sum;
+            }
+        }
+
+        return new Array2DRowRealMatrix(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[][] getData() {
+        return copyOut();
+    }
+
+    /**
+     * Returns a reference to the underlying data array.
+     * <p>
+     * Does <strong>not</strong> make a fresh copy of the underlying data.</p>
+     *
+     * @return 2-dimensional array of entries
+     */
+    public double[][] getDataRef() {
+        return data;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
+    throws MatrixIndexException {
+        if (data == null) {
+            if (row > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                      LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row);
+            }
+            if (column > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                      LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column);
+            }
+            final int nRows = subMatrix.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+
+            final int nCols = subMatrix[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            data = new double[subMatrix.length][nCols];
+            for (int i = 0; i < data.length; ++i) {
+                if (subMatrix[i].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.DIFFERENT_ROWS_LENGTHS, nCols, subMatrix[i].length);
+                }
+                System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
+            }
+        } else {
+            super.setSubMatrix(subMatrix, row, column);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getEntry(final int row, final int column)
+        throws MatrixIndexException {
+        try {
+            return data[row][column];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(final int row, final int column, final double value)
+        throws MatrixIndexException {
+        try {
+            data[row][column] = value;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(final int row, final int column, final double increment)
+        throws MatrixIndexException {
+        try {
+            data[row][column] += increment;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(final int row, final int column, final double factor)
+        throws MatrixIndexException {
+        try {
+            data[row][column] *= factor;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                      LocalizedFormats.NO_SUCH_MATRIX_ENTRY, row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return (data == null) ? 0 : data.length;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] operate(final double[] v)
+        throws IllegalArgumentException {
+        final int nRows = this.getRowDimension();
+        final int nCols = this.getColumnDimension();
+        if (v.length != nCols) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nCols);
+        }
+        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[i];
+            }
+            out[row] = sum;
+        }
+        return out;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] preMultiply(final double[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.VECTOR_LENGTH_MISMATCH, v.length, nRows);
+        }
+
+        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[i];
+            }
+            out[col] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int i = 0; i < rows; ++i) {
+            final double[] rowI = data[i];
+            for (int j = 0; j < columns; ++j) {
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int i = 0; i < rows; ++i) {
+            final double[] rowI = data[i];
+            for (int j = 0; j < columns; ++j) {
+                visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int i = startRow; i <= endRow; ++i) {
+            final double[] rowI = data[i];
+            for (int j = startColumn; j <= endColumn; ++j) {
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int i = startRow; i <= endRow; ++i) {
+            final double[] rowI = data[i];
+            for (int j = startColumn; j <= endColumn; ++j) {
+                visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int j = 0; j < columns; ++j) {
+            for (int i = 0; i < rows; ++i) {
+                final double[] rowI = data[i];
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int j = 0; j < columns; ++j) {
+            for (int i = 0; i < rows; ++i) {
+                visitor.visit(i, j, data[i][j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixChangingVisitor visitor,
+                                    final int startRow, final int endRow,
+                                    final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int j = startColumn; j <= endColumn; ++j) {
+            for (int i = startRow; i <= endRow; ++i) {
+                final double[] rowI = data[i];
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor,
+                                    final int startRow, final int endRow,
+                                    final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int j = startColumn; j <= endColumn; ++j) {
+            for (int i = startRow; i <= endRow; ++i) {
+                visitor.visit(i, j, data[i][j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Returns a fresh copy of the underlying data array.
+     *
+     * @return a copy of the underlying data array.
+     */
+    private double[][] copyOut() {
+        final int nRows = this.getRowDimension();
+        final double[][] out = new double[nRows][this.getColumnDimension()];
+        // can't copy 2-d array in one shot, otherwise get row references
+        for (int i = 0; i < nRows; i++) {
+            System.arraycopy(data[i], 0, out[i], 0, data[i].length);
+        }
+        return out;
+    }
+
+    /**
+     * Replaces data with a fresh copy of the input array.
+     * <p>
+     * Verifies that the input array is rectangular and non-empty.</p>
+     *
+     * @param in data to copy in
+     * @throws IllegalArgumentException if input array is empty or not
+     *    rectangular
+     * @throws NullPointerException if input array is null
+     */
+    private void copyIn(final double[][] in) {
+        setSubMatrix(in, 0, 0);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java b/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java
new file mode 100644
index 0000000..eefce2f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/ArrayFieldVector.java
@@ -0,0 +1,869 @@
+/*
+ * 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.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;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * This class implements the {@link FieldVector} interface with a {@link FieldElement} array.
+ * @param <T> the type of the field elements
+ * @version $Revision: 1003997 $ $Date: 2010-10-03 18:45:55 +0200 (dim. 03 oct. 2010) $
+ * @since 2.0
+ */
+public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 7648186910365927050L;
+
+    /** Entries of the vector. */
+    protected T[] data;
+
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+
+    /**
+     * 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
+     * #ArrayFieldVector(ArrayFieldVector, ArrayFieldVector)} constructor
+     * or one of the <code>append</code> methods ({@link #append(FieldElement[])},
+     * {@link #add(FieldVector)}, {@link #append(ArrayFieldVector)}) to gather data
+     * into this vector.</p>
+     * @param field field to which the elements belong
+     */
+    public ArrayFieldVector(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 ArrayFieldVector(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 ArrayFieldVector(int size, T preset) {
+        this(preset.getField(), size);
+        Arrays.fill(data, preset);
+    }
+
+    /**
+     * Construct a vector from an array, copying the input array.
+     * <p>
+     * This constructor needs a non-empty {@code d} array to retrieve
+     * the field from its first element. This implies it cannot build
+     * 0 length vectors. To build vectors from any size, one should
+     * use the {@link #ArrayFieldVector(Field, FieldElement[])} constructor.
+     * </p>
+     * @param d array of Ts.
+     * @throws IllegalArgumentException if <code>d</code> is empty
+     * @see #ArrayFieldVector(Field, FieldElement[])
+     */
+    public ArrayFieldVector(T[] d)
+        throws IllegalArgumentException {
+        try {
+            field = d[0].getField();
+            data = d.clone();
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
+        }
+    }
+
+    /**
+     * Construct a vector from an array, copying the input array.
+     * @param field field to which the elements belong
+     * @param d array of Ts.
+     * @see #ArrayFieldVector(FieldElement[])
+     */
+    public ArrayFieldVector(Field<T> field, T[] d) {
+        this.field = field;
+        data = d.clone();
+    }
+
+    /**
+     * Create a new ArrayFieldVector using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * ArrayFieldVector 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>
+     * <p>
+     * This constructor needs a non-empty {@code d} array to retrieve
+     * the field from its first element. This implies it cannot build
+     * 0 length vectors. To build vectors from any size, one should
+     * use the {@link #ArrayFieldVector(Field, FieldElement[], boolean)} constructor.
+     * </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 #ArrayFieldVector(FieldElement[])
+     * @see #ArrayFieldVector(Field, FieldElement[], boolean)
+     */
+    public ArrayFieldVector(T[] d, boolean copyArray)
+        throws NullPointerException, IllegalArgumentException {
+        if (d.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
+        }
+        field = d[0].getField();
+        data = copyArray ? d.clone() :  d;
+    }
+
+    /**
+     * Create a new ArrayFieldVector using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * ArrayFieldVector 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 field field to which the elements belong
+     * @param d data for new vector
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @see #ArrayFieldVector(FieldElement[], boolean)
+     */
+    public ArrayFieldVector(Field<T> field, T[] d, boolean copyArray) {
+        this.field = field;
+        data = copyArray ? d.clone() :  d;
+    }
+
+    /**
+     * 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 ArrayFieldVector(T[] d, int pos, int size) {
+        if (d.length < pos + size) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY,
+                    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 ArrayFieldVector(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 ArrayFieldVector(ArrayFieldVector<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 ArrayFieldVector(ArrayFieldVector<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 ArrayFieldVector(ArrayFieldVector<T> v1, ArrayFieldVector<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 ArrayFieldVector(ArrayFieldVector<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 ArrayFieldVector(T[] v1, ArrayFieldVector<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.
+     * <p>
+     * This constructor needs at least one non-empty array to retrieve
+     * the field from its first element. This implies it cannot build
+     * 0 length vectors. To build vectors from any size, one should
+     * use the {@link #ArrayFieldVector(Field, FieldElement[], FieldElement[])} constructor.
+     * </p>
+     * @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
+     * @see #ArrayFieldVector(Field, FieldElement[], FieldElement[])
+     */
+    public ArrayFieldVector(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(
+                      LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
+        }
+    }
+
+    /**
+     * Construct a vector by appending one vector to another vector.
+     * @param field field to which the elements belong
+     * @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)
+     * @see #ArrayFieldVector(FieldElement[], FieldElement[])
+     */
+    public ArrayFieldVector(Field<T> field, T[] v1, T[] v2) {
+        if (v1.length + v2.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT);
+        }
+        data = buildArray(v1.length + v2.length);
+        System.arraycopy(v1, 0, data, 0, v1.length);
+        System.arraycopy(v2, 0, data, v1.length, v2.length);
+        this.field = data[0].getField();
+    }
+
+    /** Build an array of elements.
+     * @param length size of the array to build
+     * @return a new array
+     */
+    @SuppressWarnings("unchecked") // field is of type T
+    private T[] buildArray(final int length) {
+        return (T[]) Array.newInstance(field.getZero().getClass(), length);
+    }
+
+    /** {@inheritDoc} */
+    public Field<T> getField() {
+        return field;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> copy() {
+        return new ArrayFieldVector<T>(this, true);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
+        try {
+            return add((ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<T> add(ArrayFieldVector<T> v)
+        throws IllegalArgumentException {
+        return (ArrayFieldVector<T>) add(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> subtract(FieldVector<T> v) throws IllegalArgumentException {
+        try {
+            return subtract((ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<T> subtract(ArrayFieldVector<T> v)
+        throws IllegalArgumentException {
+        return (ArrayFieldVector<T>) subtract(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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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((ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<T> ebeMultiply(ArrayFieldVector<T> v)
+        throws IllegalArgumentException {
+        return (ArrayFieldVector<T>) ebeMultiply(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeDivide(FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return ebeDivide((ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<T> ebeDivide(ArrayFieldVector<T> v)
+        throws IllegalArgumentException {
+        return (ArrayFieldVector<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((ArrayFieldVector<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(ArrayFieldVector<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 ArrayFieldVector<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 ArrayFieldVector<T> projection(ArrayFieldVector<T> v) {
+        return (ArrayFieldVector<T>) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> outerProduct(FieldVector<T> v)
+        throws IllegalArgumentException {
+        try {
+            return outerProduct((ArrayFieldVector<T>) v);
+        } catch (ClassCastException cce) {
+            checkVectorDimensions(v);
+            final int m = data.length;
+            final FieldMatrix<T> out = new Array2DRowFieldMatrix<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(ArrayFieldVector<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 Array2DRowFieldMatrix<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((ArrayFieldVector<T>) v);
+        } catch (ClassCastException cce) {
+            return new ArrayFieldVector<T>(this,new ArrayFieldVector<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 ArrayFieldVector<T> append(ArrayFieldVector<T> v) {
+        return new ArrayFieldVector<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 ArrayFieldVector<T>(out);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(T[] in) {
+        return new ArrayFieldVector<T>(this, in);
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> getSubVector(int index, int n) {
+        ArrayFieldVector<T> out = new ArrayFieldVector<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, (ArrayFieldVector<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, ArrayFieldVector<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(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    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
+     *
+     */
+    @Override
+    public boolean equals(Object other) {
+
+      if (this == other) {
+        return true;
+      }
+
+      if (other == null) {
+        return false;
+      }
+
+      try {
+          @SuppressWarnings("unchecked") // May fail, but we ignore ClassCastException
+          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(LocalizedFormats.INDEX_OUT_OF_RANGE,
+                                           index, 0, getDimension() - 1);
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java b/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java
new file mode 100644
index 0000000..9f15a6e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/ArrayRealVector.java
@@ -0,0 +1,1228 @@
+/*
+ * 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 java.util.Iterator;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements the {@link RealVector} interface with a double array.
+ * @version $Revision: 1003993 $ $Date: 2010-10-03 18:39:16 +0200 (dim. 03 oct. 2010) $
+ * @since 2.0
+ */
+public class ArrayRealVector extends AbstractRealVector implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -1097961340710804027L;
+
+    /** Default format. */
+    private static final RealVectorFormat DEFAULT_FORMAT =
+        RealVectorFormat.getInstance();
+
+    /** Entries of the vector. */
+    protected double data[];
+
+    /**
+     * 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
+     * #ArrayRealVector(ArrayRealVector, ArrayRealVector)} constructor
+     * or one of the <code>append</code> method ({@link #append(double)}, {@link
+     * #append(double[])}, {@link #append(ArrayRealVector)}) to gather data
+     * into this vector.</p>
+     */
+    public ArrayRealVector() {
+        data = new double[0];
+    }
+
+    /**
+     * Construct a (size)-length vector of zeros.
+     * @param size size of the vector
+     */
+    public ArrayRealVector(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 ArrayRealVector(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 ArrayRealVector(double[] d) {
+        data = d.clone();
+    }
+
+    /**
+     * Create a new ArrayRealVector using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * ArrayRealVector 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
+     * @see #ArrayRealVector(double[])
+     */
+    public ArrayRealVector(double[] d, boolean copyArray) {
+        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 ArrayRealVector(double[] d, int pos, int size) {
+        if (d.length < pos + size) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY, pos, size, 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 ArrayRealVector(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 ArrayRealVector(Double[] d, int pos, int size) {
+        if (d.length < pos + size) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.POSITION_SIZE_MISMATCH_INPUT_ARRAY, pos, size, 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 ArrayRealVector(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 ArrayRealVector(ArrayRealVector v) {
+        this(v, true);
+    }
+
+    /**
+     * 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 ArrayRealVector(ArrayRealVector 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 ArrayRealVector(ArrayRealVector v1, ArrayRealVector 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);
+    }
+
+    /**
+     * 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 ArrayRealVector(ArrayRealVector v1, RealVector v2) {
+        final int l1 = v1.data.length;
+        final int l2 = v2.getDimension();
+        data = new double[l1 + l2];
+        System.arraycopy(v1.data, 0, data, 0, l1);
+        for (int i = 0; i < l2; ++i) {
+            data[l1 + i] = v2.getEntry(i);
+        }
+    }
+
+    /**
+     * 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 ArrayRealVector(RealVector v1, ArrayRealVector v2) {
+        final int l1 = v1.getDimension();
+        final int l2 = v2.data.length;
+        data = new double[l1 + l2];
+        for (int i = 0; i < l1; ++i) {
+            data[i] = v1.getEntry(i);
+        }
+        System.arraycopy(v2.data, 0, data, l1, l2);
+    }
+
+    /**
+     * 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 ArrayRealVector(ArrayRealVector v1, double[] v2) {
+        final int l1 = v1.getDimension();
+        final int l2 = v2.length;
+        data = new double[l1 + l2];
+        System.arraycopy(v1.data, 0, data, 0, l1);
+        System.arraycopy(v2, 0, data, l1, l2);
+    }
+
+    /**
+     * 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 ArrayRealVector(double[] v1, ArrayRealVector v2) {
+        final int l1 = v1.length;
+        final int l2 = v2.getDimension();
+        data = new double[l1 + l2];
+        System.arraycopy(v1, 0, data, 0, l1);
+        System.arraycopy(v2.data, 0, data, l1, l2);
+    }
+
+    /**
+     * 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 ArrayRealVector(double[] v1, double[] v2) {
+        final int l1 = v1.length;
+        final int l2 = v2.length;
+        data = new double[l1 + l2];
+        System.arraycopy(v1, 0, data, 0, l1);
+        System.arraycopy(v2, 0, data, l1, l2);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public AbstractRealVector copy() {
+        return new ArrayRealVector(this, true);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector add(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return add((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double[] out = data.clone();
+            Iterator<Entry> it = v.sparseIterator();
+            Entry e;
+            while (it.hasNext() && (e = it.next()) != null) {
+                out[e.getIndex()] += e.getValue();
+            }
+            return new ArrayRealVector(out, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector add(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double[] out = data.clone();
+        for (int i = 0; i < data.length; i++) {
+            out[i] += v[i];
+        }
+        return new ArrayRealVector(out, false);
+    }
+
+    /**
+     * 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 ArrayRealVector add(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return (ArrayRealVector) add(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector subtract(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return subtract((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double[] out = data.clone();
+            Iterator<Entry> it = v.sparseIterator();
+            Entry e;
+            while(it.hasNext() && (e = it.next()) != null) {
+                out[e.getIndex()] -= e.getValue();
+            }
+            return new ArrayRealVector(out, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector subtract(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double[] out = data.clone();
+        for (int i = 0; i < data.length; i++) {
+            out[i] -= v[i];
+        }
+        return new ArrayRealVector(out, false);
+    }
+
+    /**
+     * 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 ArrayRealVector subtract(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return (ArrayRealVector) subtract(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapAddToSelf(double d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i] + d;
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapSubtractToSelf(double d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i] - d;
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapMultiplyToSelf(double d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i] * d;
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapDivideToSelf(double d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = data[i] / d;
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapPowToSelf(double d) {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.pow(data[i], d);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapExpToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.exp(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapExpm1ToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.expm1(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapLogToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.log(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapLog10ToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.log10(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapLog1pToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.log1p(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapCoshToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.cosh(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapSinhToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.sinh(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapTanhToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.tanh(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapCosToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.cos(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapSinToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.sin(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapTanToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.tan(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapAcosToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.acos(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapAsinToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.asin(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapAtanToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.atan(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapInvToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = 1.0 / data[i];
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapAbsToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.abs(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapSqrtToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.sqrt(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapCbrtToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.cbrt(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapCeilToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.ceil(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapFloorToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.floor(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapRintToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.rint(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapSignumToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.signum(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector mapUlpToSelf() {
+        for (int i = 0; i < data.length; i++) {
+            data[i] = FastMath.ulp(data[i]);
+        }
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    public RealVector ebeMultiply(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return ebeMultiply((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double[] out = data.clone();
+            for (int i = 0; i < data.length; i++) {
+                out[i] *= v.getEntry(i);
+            }
+            return new ArrayRealVector(out, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector ebeMultiply(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double[] out = data.clone();
+        for (int i = 0; i < data.length; i++) {
+            out[i] *= v[i];
+        }
+        return new ArrayRealVector(out, false);
+    }
+
+    /**
+     * 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 ArrayRealVector ebeMultiply(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return (ArrayRealVector) ebeMultiply(v.data);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector ebeDivide(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return ebeDivide((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double[] out = data.clone();
+            for (int i = 0; i < data.length; i++) {
+                out[i] /= v.getEntry(i);
+            }
+            return new ArrayRealVector(out, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector ebeDivide(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double[] out = data.clone();
+        for (int i = 0; i < data.length; i++) {
+                out[i] /= v[i];
+        }
+        return new ArrayRealVector(out, false);
+    }
+
+    /**
+     * 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 ArrayRealVector ebeDivide(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return (ArrayRealVector) ebeDivide(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] 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 double[] getDataRef() {
+        return data;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double dotProduct(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return dotProduct((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double dot = 0;
+            Iterator<Entry> it = v.sparseIterator();
+            Entry e;
+            while(it.hasNext() && (e = it.next()) != null) {
+                dot += data[e.getIndex()] * e.getValue();
+            }
+            return dot;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double dotProduct(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double dot = 0;
+        for (int i = 0; i < data.length; i++) {
+            dot += data[i] * 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 double dotProduct(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return dotProduct(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNorm() {
+        double sum = 0;
+        for (double a : data) {
+            sum += a * a;
+        }
+        return FastMath.sqrt(sum);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getL1Norm() {
+        double sum = 0;
+        for (double a : data) {
+            sum += FastMath.abs(a);
+        }
+        return sum;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getLInfNorm() {
+        double max = 0;
+        for (double a : data) {
+            max = FastMath.max(max, FastMath.abs(a));
+        }
+        return max;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getDistance(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return getDistance((ArrayRealVector) v);
+        } else {
+            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 FastMath.sqrt(sum);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getDistance(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double sum = 0;
+        for (int i = 0; i < data.length; ++i) {
+            final double delta = data[i] - v[i];
+            sum += delta * delta;
+        }
+        return FastMath.sqrt(sum);
+    }
+
+   /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with the
+     * L<sub>2</sub> norm, i.e. the square root of the sum of
+     * elements differences, or euclidian distance.</p>
+     * @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(ArrayRealVector)
+     * @see #getLInfDistance(ArrayRealVector)
+     * @see #getNorm()
+     */
+    public double getDistance(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return getDistance(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getL1Distance(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return getL1Distance((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double sum = 0;
+            for (int i = 0; i < data.length; ++i) {
+                final double delta = data[i] - v.getEntry(i);
+                sum += FastMath.abs(delta);
+            }
+            return sum;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getL1Distance(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double sum = 0;
+        for (int i = 0; i < data.length; ++i) {
+            final double delta = data[i] - v[i];
+            sum += FastMath.abs(delta);
+        }
+        return sum;
+    }
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>1</sub> norm, i.e. the sum of the absolute values of
+     * elements differences.</p>
+     * @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(ArrayRealVector)
+     * @see #getLInfDistance(ArrayRealVector)
+     * @see #getNorm()
+     */
+    public double getL1Distance(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return getL1Distance(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getLInfDistance(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return getLInfDistance((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            double max = 0;
+            for (int i = 0; i < data.length; ++i) {
+                final double delta = data[i] - v.getEntry(i);
+                max = FastMath.max(max, FastMath.abs(delta));
+            }
+            return max;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getLInfDistance(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double max = 0;
+        for (int i = 0; i < data.length; ++i) {
+            final double delta = data[i] - v[i];
+            max = FastMath.max(max, FastMath.abs(delta));
+        }
+        return max;
+    }
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>&infin;</sub> norm, i.e. the max of the absolute values of
+     * elements differences.</p>
+     * @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(ArrayRealVector)
+     * @see #getLInfDistance(ArrayRealVector)
+     * @see #getNorm()
+     */
+    public double getLInfDistance(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return getLInfDistance(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector unitVector() throws ArithmeticException {
+        final double norm = getNorm();
+        if (norm == 0) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM);
+        }
+        return mapDivide(norm);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void unitize() throws ArithmeticException {
+        final double norm = getNorm();
+        if (norm == 0) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
+        }
+        mapDivideToSelf(norm);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector projection(RealVector v) {
+        return v.mapMultiply(dotProduct(v) / v.dotProduct(v));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector projection(double[] v) {
+        return projection(new ArrayRealVector(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 ArrayRealVector projection(ArrayRealVector v) {
+        return (ArrayRealVector) v.mapMultiply(dotProduct(v) / v.dotProduct(v));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix outerProduct(RealVector v)
+        throws IllegalArgumentException {
+        if (v instanceof ArrayRealVector) {
+            return outerProduct((ArrayRealVector) v);
+        } else {
+            checkVectorDimensions(v);
+            final int m = data.length;
+            final RealMatrix out = MatrixUtils.createRealMatrix(m, m);
+            for (int i = 0; i < data.length; i++) {
+                for (int j = 0; j < data.length; j++) {
+                    out.setEntry(i, j, data[i] * 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 RealMatrix outerProduct(ArrayRealVector v)
+        throws IllegalArgumentException {
+        return outerProduct(v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix outerProduct(double[] v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        final int m = data.length;
+        final RealMatrix out = MatrixUtils.createRealMatrix(m, m);
+        for (int i = 0; i < data.length; i++) {
+            for (int j = 0; j < data.length; j++) {
+                out.setEntry(i, j, data[i] * v[j]);
+            }
+        }
+        return 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 new ArrayRealVector(this, (ArrayRealVector) v);
+        } catch (ClassCastException cce) {
+            return new ArrayRealVector(this, v);
+        }
+    }
+
+    /**
+     * Construct a vector by appending a vector to this vector.
+     * @param v vector to append to this one.
+     * @return a new vector
+     */
+    public ArrayRealVector append(ArrayRealVector v) {
+        return new ArrayRealVector(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 ArrayRealVector(out, false);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector append(double[] in) {
+        return new ArrayRealVector(this, in);
+    }
+
+    /** {@inheritDoc} */
+    public RealVector getSubVector(int index, int n) {
+        ArrayRealVector out = new ArrayRealVector(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, double value) {
+        try {
+            data[index] = value;
+        } catch (IndexOutOfBoundsException e) {
+            checkIndex(index);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubVector(int index, RealVector v) {
+        try {
+            try {
+                set(index, (ArrayRealVector) 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} */
+    @Override
+    public void setSubVector(int index, double[] 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, ArrayRealVector v)
+        throws MatrixIndexException {
+        setSubVector(index, v.data);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void set(double value) {
+        Arrays.fill(data, value);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] toArray(){
+        return data.clone();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    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
+     */
+    @Override
+    protected 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
+     */
+    @Override
+    protected void checkVectorDimensions(int n)
+        throws IllegalArgumentException {
+        if (data.length != n) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    data.length, n);
+        }
+    }
+
+    /**
+     * 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.
+     * <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 vector objects are equal, false if
+     *         object is null, not an instance of RealVector, or
+     *         not equal to this RealVector instance
+     *
+     */
+    @Override
+    public boolean equals(Object other) {
+
+      if (this == other) {
+        return true;
+      }
+
+      if (other == null || !(other instanceof RealVector)) {
+        return false;
+      }
+
+
+      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 (data[i] != rhs.getEntry(i)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    /**
+     * 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() {
+        if (isNaN()) {
+            return 9;
+        }
+        return MathUtils.hash(data);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/BiDiagonalTransformer.java b/src/main/java/org/apache/commons/math/linear/BiDiagonalTransformer.java
new file mode 100644
index 0000000..78230de
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/BiDiagonalTransformer.java
@@ -0,0 +1,381 @@
+/*
+ * 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 org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Class transforming any matrix to bi-diagonal shape.
+ * <p>Any m &times; n matrix A can be written as the product of three matrices:
+ * A = U &times; B &times; V<sup>T</sup> with U an m &times; m orthogonal matrix,
+ * B an m &times; n bi-diagonal matrix (lower diagonal if m &lt; n, upper diagonal
+ * otherwise), and V an n &times; n orthogonal matrix.</p>
+ * <p>Transformation to bi-diagonal shape is often not a goal by itself, but it is
+ * an intermediate step in more general decomposition algorithms like {@link
+ * SingularValueDecomposition Singular Value Decomposition}. This class is therefore
+ * intended for internal use by the library and is not public. As a consequence of
+ * this explicitly limited scope, many methods directly returns references to
+ * internal arrays, not copies.</p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+class BiDiagonalTransformer {
+
+    /** Householder vectors. */
+    private final double householderVectors[][];
+
+    /** Main diagonal. */
+    private final double[] main;
+
+    /** Secondary diagonal. */
+    private final double[] secondary;
+
+    /** Cached value of U. */
+    private RealMatrix cachedU;
+
+    /** Cached value of B. */
+    private RealMatrix cachedB;
+
+    /** Cached value of V. */
+    private RealMatrix cachedV;
+
+    /**
+     * Build the transformation to bi-diagonal shape of a matrix.
+     * @param matrix the matrix to transform.
+     */
+    public BiDiagonalTransformer(RealMatrix matrix) {
+
+        final int m = matrix.getRowDimension();
+        final int n = matrix.getColumnDimension();
+        final int p = FastMath.min(m, n);
+        householderVectors = matrix.getData();
+        main      = new double[p];
+        secondary = new double[p - 1];
+        cachedU   = null;
+        cachedB   = null;
+        cachedV   = null;
+
+        // transform matrix
+        if (m >= n) {
+            transformToUpperBiDiagonal();
+        } else {
+            transformToLowerBiDiagonal();
+        }
+
+    }
+
+    /**
+     * Returns the matrix U of the transform.
+     * <p>U is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the U matrix
+     */
+    public RealMatrix getU() {
+
+        if (cachedU == null) {
+
+            final int m = householderVectors.length;
+            final int n = householderVectors[0].length;
+            final int p = main.length;
+            final int diagOffset    = (m >= n) ? 0 : 1;
+            final double[] diagonal = (m >= n) ? main : secondary;
+            cachedU = MatrixUtils.createRealMatrix(m, m);
+
+            // fill up the part of the matrix not affected by Householder transforms
+            for (int k = m - 1; k >= p; --k) {
+                cachedU.setEntry(k, k, 1);
+            }
+
+            // build up first part of the matrix by applying Householder transforms
+            for (int k = p - 1; k >= diagOffset; --k) {
+                final double[] hK = householderVectors[k];
+                cachedU.setEntry(k, k, 1);
+                if (hK[k - diagOffset] != 0.0) {
+                    for (int j = k; j < m; ++j) {
+                        double alpha = 0;
+                        for (int i = k; i < m; ++i) {
+                            alpha -= cachedU.getEntry(i, j) * householderVectors[i][k - diagOffset];
+                        }
+                        alpha /= diagonal[k - diagOffset] * hK[k - diagOffset];
+
+                        for (int i = k; i < m; ++i) {
+                            cachedU.addToEntry(i, j, -alpha * householderVectors[i][k - diagOffset]);
+                        }
+                    }
+                }
+            }
+            if (diagOffset > 0) {
+                cachedU.setEntry(0, 0, 1);
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedU;
+
+    }
+
+    /**
+     * Returns the bi-diagonal matrix B of the transform.
+     * @return the B matrix
+     */
+    public RealMatrix getB() {
+
+        if (cachedB == null) {
+
+            final int m = householderVectors.length;
+            final int n = householderVectors[0].length;
+            cachedB = MatrixUtils.createRealMatrix(m, n);
+            for (int i = 0; i < main.length; ++i) {
+                cachedB.setEntry(i, i, main[i]);
+                if (m < n) {
+                    if (i > 0) {
+                        cachedB.setEntry(i, i - 1, secondary[i - 1]);
+                    }
+                } else {
+                    if (i < main.length - 1) {
+                        cachedB.setEntry(i, i + 1, secondary[i]);
+                    }
+                }
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedB;
+
+    }
+
+    /**
+     * Returns the matrix V of the transform.
+     * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the V matrix
+     */
+    public RealMatrix getV() {
+
+        if (cachedV == null) {
+
+            final int m = householderVectors.length;
+            final int n = householderVectors[0].length;
+            final int p = main.length;
+            final int diagOffset    = (m >= n) ? 1 : 0;
+            final double[] diagonal = (m >= n) ? secondary : main;
+            cachedV = MatrixUtils.createRealMatrix(n, n);
+
+            // fill up the part of the matrix not affected by Householder transforms
+            for (int k = n - 1; k >= p; --k) {
+                cachedV.setEntry(k, k, 1);
+            }
+
+            // build up first part of the matrix by applying Householder transforms
+            for (int k = p - 1; k >= diagOffset; --k) {
+                final double[] hK = householderVectors[k - diagOffset];
+                cachedV.setEntry(k, k, 1);
+                if (hK[k] != 0.0) {
+                    for (int j = k; j < n; ++j) {
+                        double beta = 0;
+                        for (int i = k; i < n; ++i) {
+                            beta -= cachedV.getEntry(i, j) * hK[i];
+                        }
+                        beta /= diagonal[k - diagOffset] * hK[k];
+
+                        for (int i = k; i < n; ++i) {
+                            cachedV.addToEntry(i, j, -beta * hK[i]);
+                        }
+                    }
+                }
+            }
+            if (diagOffset > 0) {
+                cachedV.setEntry(0, 0, 1);
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedV;
+
+    }
+
+    /**
+     * Get the Householder vectors of the transform.
+     * <p>Note that since this class is only intended for internal use,
+     * it returns directly a reference to its internal arrays, not a copy.</p>
+     * @return the main diagonal elements of the B matrix
+     */
+    double[][] getHouseholderVectorsRef() {
+        return householderVectors;
+    }
+
+    /**
+     * Get the main diagonal elements of the matrix B of the transform.
+     * <p>Note that since this class is only intended for internal use,
+     * it returns directly a reference to its internal arrays, not a copy.</p>
+     * @return the main diagonal elements of the B matrix
+     */
+    double[] getMainDiagonalRef() {
+        return main;
+    }
+
+    /**
+     * Get the secondary diagonal elements of the matrix B of the transform.
+     * <p>Note that since this class is only intended for internal use,
+     * it returns directly a reference to its internal arrays, not a copy.</p>
+     * @return the secondary diagonal elements of the B matrix
+     */
+    double[] getSecondaryDiagonalRef() {
+        return secondary;
+    }
+
+    /**
+     * Check if the matrix is transformed to upper bi-diagonal.
+     * @return true if the matrix is transformed to upper bi-diagonal
+     */
+    boolean isUpperBiDiagonal() {
+        return householderVectors.length >=  householderVectors[0].length;
+    }
+
+    /**
+     * Transform original matrix to upper bi-diagonal form.
+     * <p>Transformation is done using alternate Householder transforms
+     * on columns and rows.</p>
+     */
+    private void transformToUpperBiDiagonal() {
+
+        final int m = householderVectors.length;
+        final int n = householderVectors[0].length;
+        for (int k = 0; k < n; k++) {
+
+            //zero-out a column
+            double xNormSqr = 0;
+            for (int i = k; i < m; ++i) {
+                final double c = householderVectors[i][k];
+                xNormSqr += c * c;
+            }
+            final double[] hK = householderVectors[k];
+            final double a = (hK[k] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr);
+            main[k] = a;
+            if (a != 0.0) {
+                hK[k] -= a;
+                for (int j = k + 1; j < n; ++j) {
+                    double alpha = 0;
+                    for (int i = k; i < m; ++i) {
+                        final double[] hI = householderVectors[i];
+                        alpha -= hI[j] * hI[k];
+                    }
+                    alpha /= a * householderVectors[k][k];
+                    for (int i = k; i < m; ++i) {
+                        final double[] hI = householderVectors[i];
+                        hI[j] -= alpha * hI[k];
+                    }
+                }
+            }
+
+            if (k < n - 1) {
+                //zero-out a row
+                xNormSqr = 0;
+                for (int j = k + 1; j < n; ++j) {
+                    final double c = hK[j];
+                    xNormSqr += c * c;
+                }
+                final double b = (hK[k + 1] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr);
+                secondary[k] = b;
+                if (b != 0.0) {
+                    hK[k + 1] -= b;
+                    for (int i = k + 1; i < m; ++i) {
+                        final double[] hI = householderVectors[i];
+                        double beta = 0;
+                        for (int j = k + 1; j < n; ++j) {
+                            beta -= hI[j] * hK[j];
+                        }
+                        beta /= b * hK[k + 1];
+                        for (int j = k + 1; j < n; ++j) {
+                            hI[j] -= beta * hK[j];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+    /**
+     * Transform original matrix to lower bi-diagonal form.
+     * <p>Transformation is done using alternate Householder transforms
+     * on rows and columns.</p>
+     */
+    private void transformToLowerBiDiagonal() {
+
+        final int m = householderVectors.length;
+        final int n = householderVectors[0].length;
+        for (int k = 0; k < m; k++) {
+
+            //zero-out a row
+            final double[] hK = householderVectors[k];
+            double xNormSqr = 0;
+            for (int j = k; j < n; ++j) {
+                final double c = hK[j];
+                xNormSqr += c * c;
+            }
+            final double a = (hK[k] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr);
+            main[k] = a;
+            if (a != 0.0) {
+                hK[k] -= a;
+                for (int i = k + 1; i < m; ++i) {
+                    final double[] hI = householderVectors[i];
+                    double alpha = 0;
+                    for (int j = k; j < n; ++j) {
+                        alpha -= hI[j] * hK[j];
+                    }
+                    alpha /= a * householderVectors[k][k];
+                    for (int j = k; j < n; ++j) {
+                        hI[j] -= alpha * hK[j];
+                    }
+                }
+            }
+
+            if (k < m - 1) {
+                //zero-out a column
+                final double[] hKp1 = householderVectors[k + 1];
+                xNormSqr = 0;
+                for (int i = k + 1; i < m; ++i) {
+                    final double c = householderVectors[i][k];
+                    xNormSqr += c * c;
+                }
+                final double b = (hKp1[k] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr);
+                secondary[k] = b;
+                if (b != 0.0) {
+                    hKp1[k] -= b;
+                    for (int j = k + 1; j < n; ++j) {
+                        double beta = 0;
+                        for (int i = k + 1; i < m; ++i) {
+                            final double[] hI = householderVectors[i];
+                            beta -= hI[j] * hI[k];
+                        }
+                        beta /= b * hKp1[k];
+                        for (int i = k + 1; i < m; ++i) {
+                            final double[] hI = householderVectors[i];
+                            hI[j] -= beta * hI[k];
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/BigMatrix.java b/src/main/java/org/apache/commons/math/linear/BigMatrix.java
new file mode 100644
index 0000000..5ea3d3e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/BigMatrix.java
@@ -0,0 +1,331 @@
+/*
+ * 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.math.BigDecimal;
+
+/**
+ * Interface defining a real-valued matrix with basic algebraic operations, using
+ * BigDecimal representations for the entries.
+ * <p>
+ * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</p>
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @deprecated as of 2.0, replaced by {@link FieldMatrix} with a {@link
+ * org.apache.commons.math.util.BigReal} parameter
+ */
+@Deprecated
+public interface BigMatrix extends AnyMatrix {
+
+    /**
+     * Returns a (deep) copy of this.
+     *
+     * @return matrix copy
+     */
+    BigMatrix copy();
+
+    /**
+     * Compute the sum of this and m.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @exception  IllegalArgumentException if m is not the same size as this
+     */
+    BigMatrix add(BigMatrix m) throws IllegalArgumentException;
+
+    /**
+     * Compute this minus m.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @exception  IllegalArgumentException if m is not the same size as this
+     */
+    BigMatrix subtract(BigMatrix m) throws IllegalArgumentException;
+
+     /**
+     * Returns the result of adding d to each entry of this.
+     *
+     * @param d    value to be added to each entry
+     * @return     d + this
+     */
+    BigMatrix scalarAdd(BigDecimal d);
+
+    /**
+     * Returns the result multiplying each entry of this by d.
+     *
+     * @param d    value to multiply all entries by
+     * @return     d * this
+     */
+    BigMatrix scalarMultiply(BigDecimal d);
+
+    /**
+     * Returns the result of postmultiplying this by m.
+     *
+     * @param m    matrix to postmultiply by
+     * @return     this * m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    BigMatrix multiply(BigMatrix m) throws IllegalArgumentException;
+
+    /**
+     * Returns the result premultiplying this by <code>m</code>.
+     * @param m    matrix to premultiply by
+     * @return     m * this
+     * @throws     IllegalArgumentException
+     *             if rowDimension(this) != columnDimension(m)
+     */
+    BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException;
+
+    /**
+     * Returns matrix entries as a two-dimensional array.
+     *
+     * @return    2-dimensional array of entries
+     */
+    BigDecimal[][] getData();
+
+    /**
+     * Returns matrix entries as a two-dimensional array.
+     *
+     * @return    2-dimensional array of entries
+     */
+    double [][] getDataAsDoubleArray();
+
+    /***
+     * Gets the rounding mode
+     * @return the rounding mode
+     */
+    int getRoundingMode();
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
+     * maximum absolute row sum norm</a> of the matrix.
+     *
+     * @return norm
+     */
+    BigDecimal getNorm();
+
+    /**
+     * Gets a submatrix. Rows and columns are indicated
+     * counting from 0 to n-1.
+     *
+     * @param startRow Initial row index
+     * @param endRow Final row index
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @return The subMatrix containing the data of the
+     *         specified rows and columns
+     * @exception MatrixIndexException  if the indices are not valid
+     */
+    BigMatrix getSubMatrix(int startRow, int endRow, int startColumn,
+            int endColumn) throws MatrixIndexException;
+
+    /**
+     * Gets a submatrix. Rows and columns are indicated
+     * counting from 0 to n-1.
+     *
+     * @param selectedRows Array of row indices.
+     * @param selectedColumns Array of column indices.
+     * @return The subMatrix containing the data in the
+     *         specified rows and columns
+     * @exception MatrixIndexException if row or column selections are not valid
+     */
+    BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
+    throws MatrixIndexException;
+
+    /**
+     * Returns the entries in row number <code>row</code>
+     * as a row matrix.  Row indices start at 0.
+     *
+     * @param row the row to be fetched
+     * @return row matrix
+     * @throws MatrixIndexException if the specified row index is invalid
+     */
+    BigMatrix getRowMatrix(int row) throws MatrixIndexException;
+
+    /**
+     * Returns the entries in column number <code>column</code>
+     * as a column matrix.  Column indices start at 0.
+     *
+     * @param column the column to be fetched
+     * @return column matrix
+     * @throws MatrixIndexException if the specified column index is invalid
+     */
+    BigMatrix getColumnMatrix(int column) throws MatrixIndexException;
+
+    /**
+     * Returns the entries in row number <code>row</code> as an array.
+     * <p>
+     * Row indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= row < rowDimension.</code></p>
+     *
+     * @param row the row to be fetched
+     * @return array of entries in the row
+     * @throws MatrixIndexException if the specified row index is not valid
+     */
+    BigDecimal[] getRow(int row) throws MatrixIndexException;
+
+    /**
+     * Returns the entries in row number <code>row</code> as an array
+     * of double values.
+     * <p>
+     * Row indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= row < rowDimension.</code></p>
+     *
+     * @param row the row to be fetched
+     * @return array of entries in the row
+     * @throws MatrixIndexException if the specified row index is not valid
+     */
+    double [] getRowAsDoubleArray(int row) throws MatrixIndexException;
+
+    /**
+     * Returns the entries in column number <code>col</code> as an array.
+     * <p>
+     * Column indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= column < columnDimension.</code></p>
+     *
+     * @param col the column to be fetched
+     * @return array of entries in the column
+     * @throws MatrixIndexException if the specified column index is not valid
+     */
+    BigDecimal[] getColumn(int col) throws MatrixIndexException;
+
+    /**
+     * Returns the entries in column number <code>col</code> as an array
+     * of double values.
+     * <p>
+     * Column indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= column < columnDimension.</code></p>
+     *
+     * @param col the column to be fetched
+     * @return array of entries in the column
+     * @throws MatrixIndexException if the specified column index is not valid
+     */
+    double [] getColumnAsDoubleArray(int col) throws MatrixIndexException;
+
+    /**
+     * Returns the entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be fetched
+     * @param column  column location of entry to be fetched
+     * @return matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     */
+    BigDecimal getEntry(int row, int column) throws MatrixIndexException;
+
+    /**
+     * Returns the entry in the specified row and column as a double.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be fetched
+     * @param column  column location of entry to be fetched
+     * @return matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     */
+    double getEntryAsDouble(int row, int column) throws MatrixIndexException;
+
+    /**
+     * Returns the transpose of this matrix.
+     *
+     * @return transpose matrix
+     */
+    BigMatrix transpose();
+
+    /**
+     * Returns the inverse of this matrix.
+     *
+     * @return inverse matrix
+     * @throws org.apache.commons.math.linear.InvalidMatrixException if
+     *     this is not invertible
+     */
+    BigMatrix inverse() throws InvalidMatrixException;
+
+    /**
+     * Returns the determinant of this matrix.
+     *
+     * @return determinant
+      *@throws org.apache.commons.math.linear.InvalidMatrixException if
+      *    matrix is not square
+     */
+    BigDecimal getDeterminant() throws InvalidMatrixException;
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
+     * trace</a> of the matrix (the sum of the elements on the main diagonal).
+     *
+     * @return trace
+     */
+    BigDecimal getTrace();
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @param v the vector to operate on
+     * @return this*v
+     * @throws IllegalArgumentException if columnDimension != v.size()
+     */
+    BigDecimal[] operate(BigDecimal[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
+     *
+     * @param v the row vector to premultiply by
+     * @return v*this
+     * @throws IllegalArgumentException if rowDimension != v.size()
+     */
+    BigDecimal[] preMultiply(BigDecimal[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns the solution vector for a linear system with coefficient
+     * matrix = this and constant vector = <code>b</code>.
+     *
+     * @param b  constant vector
+     * @return vector of solution values to AX = b, where A is *this
+     * @throws IllegalArgumentException if this.rowDimension != b.length
+     * @throws org.apache.commons.math.linear.InvalidMatrixException if this matrix is not square or is singular
+     */
+    BigDecimal[] solve(BigDecimal[] b) throws IllegalArgumentException, InvalidMatrixException;
+
+    /**
+     * Returns a matrix of (column) solution vectors for linear systems with
+     * coefficient matrix = this and constant vectors = columns of
+     * <code>b</code>.
+     *
+     * @param b  matrix of constant vectors forming RHS of linear systems to
+     * to solve
+     * @return matrix of solution vectors
+     * @throws IllegalArgumentException if this.rowDimension != row dimension
+     * @throws org.apache.commons.math.linear.InvalidMatrixException if this matrix is not square or is singular
+     */
+    BigMatrix solve(BigMatrix b) throws IllegalArgumentException, InvalidMatrixException;
+}
+
diff --git a/src/main/java/org/apache/commons/math/linear/BigMatrixImpl.java b/src/main/java/org/apache/commons/math/linear/BigMatrixImpl.java
new file mode 100644
index 0000000..80643a0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/BigMatrixImpl.java
@@ -0,0 +1,1505 @@
+/*
+ * 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.math.BigDecimal;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Implementation of {@link BigMatrix} using a BigDecimal[][] array to store entries
+ * and <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
+ * LU decompostion</a> to support linear system
+ * solution and inverse.
+ * <p>
+ * The LU decompostion is performed as needed, to support the following operations: <ul>
+ * <li>solve</li>
+ * <li>isSingular</li>
+ * <li>getDeterminant</li>
+ * <li>inverse</li> </ul></p>
+ * <p>
+* <strong>Usage notes</strong>:<br>
+ * <ul><li>
+ * The LU decomposition is stored and reused on subsequent calls.  If matrix
+ * data are modified using any of the public setXxx methods, the saved
+ * decomposition is discarded.  If data are modified via references to the
+ * underlying array obtained using <code>getDataRef()</code>, then the stored
+ * LU decomposition will not be discarded.  In this case, you need to
+ * explicitly invoke <code>LUDecompose()</code> to recompute the decomposition
+ * before using any of the methods above.</li>
+ * <li>
+ * As specified in the {@link BigMatrix} interface, matrix element indexing
+ * is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</li></ul></p>
+ *
+ * @deprecated as of 2.0, replaced by {@link Array2DRowFieldMatrix} with a {@link
+ * org.apache.commons.math.util.BigReal} parameter
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ */
+@Deprecated
+public class BigMatrixImpl implements BigMatrix, Serializable {
+
+    /** BigDecimal 0 */
+    static final BigDecimal ZERO = new BigDecimal(0);
+
+    /** BigDecimal 1 */
+    static final BigDecimal ONE = new BigDecimal(1);
+
+    /** Bound to determine effective singularity in LU decomposition */
+    private static final BigDecimal TOO_SMALL = new BigDecimal(10E-12);
+
+    /** Serialization id */
+    private static final long serialVersionUID = -1011428905656140431L;
+
+    /** Entries of the matrix */
+    protected BigDecimal data[][] = null;
+
+    /** Entries of cached LU decomposition.
+     *  All updates to data (other than luDecompose()) *must* set this to null
+     */
+    protected BigDecimal lu[][] = null;
+
+    /** Permutation associated with LU decomposition */
+    protected int[] permutation = null;
+
+    /** Parity of the permutation associated with the LU decomposition */
+    protected int parity = 1;
+
+    /** Rounding mode for divisions **/
+    private int roundingMode = BigDecimal.ROUND_HALF_UP;
+
+    /*** BigDecimal scale ***/
+    private int scale = 64;
+
+    /**
+     * Creates a matrix with no data
+     */
+    public BigMatrixImpl() {
+    }
+
+    /**
+     * Create a new BigMatrix with the supplied row and column dimensions.
+     *
+     * @param rowDimension      the number of rows in the new matrix
+     * @param columnDimension   the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not
+     *  positive
+     */
+    public BigMatrixImpl(int rowDimension, int columnDimension) {
+        if (rowDimension < 1 ) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, rowDimension, 1);
+        }
+        if (columnDimension < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_DIMENSION, columnDimension, 1);
+        }
+        data = new BigDecimal[rowDimension][columnDimension];
+        lu = null;
+    }
+
+    /**
+     * Create a new BigMatrix using <code>d</code> as the underlying
+     * data array.
+     * <p>The input array is copied, not referenced. This constructor has
+     * the same effect as calling {@link #BigMatrixImpl(BigDecimal[][], boolean)}
+     * with the second argument set to <code>true</code>.</p>
+     *
+     * @param d data for new matrix
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     */
+    public BigMatrixImpl(BigDecimal[][] d) {
+        this.copyIn(d);
+        lu = null;
+    }
+
+    /**
+     * Create a new BigMatrix using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * BigMatrix 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 matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #BigMatrixImpl(BigDecimal[][])
+     */
+    public BigMatrixImpl(BigDecimal[][] d, boolean copyArray) {
+        if (copyArray) {
+            copyIn(d);
+        } else {
+            if (d == null) {
+                throw new NullPointerException();
+            }
+            final int nRows = d.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+
+            final int nCols = d[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            for (int r = 1; r < nRows; r++) {
+                if (d[r].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                          nCols, d[r].length);
+                }
+            }
+            data = d;
+        }
+        lu = null;
+    }
+
+    /**
+     * Create a new BigMatrix using <code>d</code> as the underlying
+     * data array.
+     * <p>Since the underlying array will hold <code>BigDecimal</code>
+     * instances, it will be created.</p>
+     *
+     * @param d data for new matrix
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     */
+    public BigMatrixImpl(double[][] d) {
+        final int nRows = d.length;
+        if (nRows == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+
+        final int nCols = d[0].length;
+        if (nCols == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+        for (int row = 1; row < nRows; row++) {
+            if (d[row].length != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                      nCols, d[row].length);
+            }
+        }
+        this.copyIn(d);
+        lu = null;
+    }
+
+    /**
+     * Create a new BigMatrix using the values represented by the strings in
+     * <code>d</code> as the underlying data array.
+     *
+     * @param d data for new matrix
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     */
+    public BigMatrixImpl(String[][] d) {
+        final int nRows = d.length;
+        if (nRows == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+
+        final int nCols = d[0].length;
+        if (nCols == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+        for (int row = 1; row < nRows; row++) {
+            if (d[row].length != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                      nCols, d[row].length);
+            }
+        }
+        this.copyIn(d);
+        lu = null;
+    }
+
+    /**
+     * Create a new (column) BigMatrix using <code>v</code> as the
+     * data for the unique column of the <code>v.length x 1</code> matrix
+     * created.
+     * <p>
+     * The input array is copied, not referenced.</p>
+     *
+     * @param v column vector holding data for new matrix
+     */
+    public BigMatrixImpl(BigDecimal[] v) {
+        final int nRows = v.length;
+        data = new BigDecimal[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = v[row];
+        }
+    }
+
+    /**
+     * Create a new BigMatrix which is a copy of this.
+     *
+     * @return  the cloned matrix
+     */
+    public BigMatrix copy() {
+        return new BigMatrixImpl(this.copyOut(), false);
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BigMatrix add(BigMatrix m) throws IllegalArgumentException {
+        try {
+            return add((BigMatrixImpl) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkAdditionCompatible(this, m);
+
+            final int rowCount    = getRowDimension();
+            final int columnCount = getColumnDimension();
+            final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount];
+            for (int row = 0; row < rowCount; row++) {
+                final BigDecimal[] dataRow    = data[row];
+                final BigDecimal[] outDataRow = outData[row];
+                for (int col = 0; col < columnCount; col++) {
+                    outDataRow[col] = dataRow[col].add(m.getEntry(row, col));
+                }
+            }
+            return new BigMatrixImpl(outData, false);
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BigMatrixImpl add(BigMatrixImpl m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final BigDecimal[] dataRow    = data[row];
+            final BigDecimal[] mRow       = m.data[row];
+            final BigDecimal[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col].add(mRow[col]);
+            }
+        }
+        return new BigMatrixImpl(outData, false);
+    }
+
+    /**
+     * Compute  this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BigMatrix subtract(BigMatrix m) throws IllegalArgumentException {
+        try {
+            return subtract((BigMatrixImpl) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkSubtractionCompatible(this, m);
+
+            final int rowCount    = getRowDimension();
+            final int columnCount = getColumnDimension();
+            final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount];
+            for (int row = 0; row < rowCount; row++) {
+                final BigDecimal[] dataRow    = data[row];
+                final BigDecimal[] outDataRow = outData[row];
+                for (int col = 0; col < columnCount; col++) {
+                    outDataRow[col] = dataRow[col].subtract(getEntry(row, col));
+                }
+            }
+            return new BigMatrixImpl(outData, false);
+        }
+    }
+
+    /**
+     * Compute  this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BigMatrixImpl subtract(BigMatrixImpl m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkSubtractionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final BigDecimal[] dataRow    = data[row];
+            final BigDecimal[] mRow       = m.data[row];
+            final BigDecimal[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col].subtract(mRow[col]);
+            }
+        }
+        return new BigMatrixImpl(outData, false);
+    }
+
+    /**
+     * Returns the result of adding d to each entry of this.
+     *
+     * @param d    value to be added to each entry
+     * @return     d + this
+     */
+    public BigMatrix scalarAdd(BigDecimal d) {
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final BigDecimal[] dataRow    = data[row];
+            final BigDecimal[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col].add(d);
+            }
+        }
+        return new BigMatrixImpl(outData, false);
+    }
+
+    /**
+     * Returns the result of multiplying each entry of this by <code>d</code>
+     * @param d  value to multiply all entries by
+     * @return d * this
+     */
+    public BigMatrix scalarMultiply(BigDecimal d) {
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final BigDecimal[] dataRow    = data[row];
+            final BigDecimal[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col].multiply(d);
+            }
+        }
+        return new BigMatrixImpl(outData, false);
+    }
+
+    /**
+     * Returns the result of postmultiplying this by <code>m</code>.
+     * @param m    matrix to postmultiply by
+     * @return     this*m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public BigMatrix multiply(BigMatrix m) throws IllegalArgumentException {
+        try {
+            return multiply((BigMatrixImpl) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkMultiplicationCompatible(this, m);
+
+            final int nRows = this.getRowDimension();
+            final int nCols = m.getColumnDimension();
+            final int nSum = this.getColumnDimension();
+            final BigDecimal[][] outData = new BigDecimal[nRows][nCols];
+            for (int row = 0; row < nRows; row++) {
+                final BigDecimal[] dataRow    = data[row];
+                final BigDecimal[] outDataRow = outData[row];
+                for (int col = 0; col < nCols; col++) {
+                    BigDecimal sum = ZERO;
+                    for (int i = 0; i < nSum; i++) {
+                        sum = sum.add(dataRow[i].multiply(m.getEntry(i, col)));
+                    }
+                    outDataRow[col] = sum;
+                }
+            }
+            return new BigMatrixImpl(outData, false);
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by <code>m</code>.
+     * @param m    matrix to postmultiply by
+     * @return     this*m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public BigMatrixImpl multiply(BigMatrixImpl m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkMultiplicationCompatible(this, m);
+
+        final int nRows = this.getRowDimension();
+        final int nCols = m.getColumnDimension();
+        final int nSum = this.getColumnDimension();
+        final BigDecimal[][] outData = new BigDecimal[nRows][nCols];
+        for (int row = 0; row < nRows; row++) {
+            final BigDecimal[] dataRow    = data[row];
+            final BigDecimal[] outDataRow = outData[row];
+            for (int col = 0; col < nCols; col++) {
+                BigDecimal sum = ZERO;
+                for (int i = 0; i < nSum; i++) {
+                    sum = sum.add(dataRow[i].multiply(m.data[i][col]));
+                }
+                outDataRow[col] = sum;
+            }
+        }
+        return new BigMatrixImpl(outData, false);
+    }
+
+    /**
+     * Returns the result premultiplying this by <code>m</code>.
+     * @param m    matrix to premultiply by
+     * @return     m * this
+     * @throws     IllegalArgumentException
+     *             if rowDimension(this) != columnDimension(m)
+     */
+    public BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException {
+        return m.multiply(this);
+    }
+
+    /**
+     * Returns matrix entries as a two-dimensional array.
+     * <p>
+     * Makes a fresh copy of the underlying data.</p>
+     *
+     * @return    2-dimensional array of entries
+     */
+    public BigDecimal[][] getData() {
+        return copyOut();
+    }
+
+    /**
+     * Returns matrix entries as a two-dimensional array.
+     * <p>
+     * Makes a fresh copy of the underlying data converted to
+     * <code>double</code> values.</p>
+     *
+     * @return    2-dimensional array of entries
+     */
+    public double[][] getDataAsDoubleArray() {
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final double d[][] = new double[nRows][nCols];
+        for (int i = 0; i < nRows; i++) {
+            for (int j = 0; j < nCols; j++) {
+                d[i][j] = data[i][j].doubleValue();
+            }
+        }
+        return d;
+    }
+
+    /**
+     * Returns a reference to the underlying data array.
+     * <p>
+     * Does not make a fresh copy of the underlying data.</p>
+     *
+     * @return 2-dimensional array of entries
+     */
+    public BigDecimal[][] getDataRef() {
+        return data;
+    }
+
+    /***
+     * Gets the rounding mode for division operations
+     * The default is {@link java.math.BigDecimal#ROUND_HALF_UP}
+     * @see BigDecimal
+     * @return the rounding mode.
+     */
+    public int getRoundingMode() {
+        return roundingMode;
+    }
+
+    /***
+     * Sets the rounding mode for decimal divisions.
+     * @see BigDecimal
+     * @param roundingMode rounding mode for decimal divisions
+     */
+    public void setRoundingMode(int roundingMode) {
+        this.roundingMode = roundingMode;
+    }
+
+    /***
+     * Sets the scale for division operations.
+     * The default is 64
+     * @see BigDecimal
+     * @return the scale
+     */
+    public int getScale() {
+        return scale;
+    }
+
+    /***
+     * Sets the scale for division operations.
+     * @see BigDecimal
+     * @param scale scale for division operations
+     */
+    public void setScale(int scale) {
+        this.scale = scale;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
+     * maximum absolute row sum norm</a> of the matrix.
+     *
+     * @return norm
+     */
+    public BigDecimal getNorm() {
+        BigDecimal maxColSum = ZERO;
+        for (int col = 0; col < this.getColumnDimension(); col++) {
+            BigDecimal sum = ZERO;
+            for (int row = 0; row < this.getRowDimension(); row++) {
+                sum = sum.add(data[row][col].abs());
+            }
+            maxColSum = maxColSum.max(sum);
+        }
+        return maxColSum;
+    }
+
+    /**
+     * Gets a submatrix. Rows and columns are indicated
+     * counting from 0 to n-1.
+     *
+     * @param startRow Initial row index
+     * @param endRow Final row index
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @return The subMatrix containing the data of the
+     *         specified rows and columns
+     * @exception MatrixIndexException if row or column selections are not valid
+     */
+    public BigMatrix getSubMatrix(int startRow, int endRow,
+                                  int startColumn, int endColumn)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkRowIndex(this, startRow);
+        MatrixUtils.checkRowIndex(this, endRow);
+        if (startRow > endRow) {
+            throw new MatrixIndexException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
+                                           startRow, endRow);
+        }
+
+        MatrixUtils.checkColumnIndex(this, startColumn);
+        MatrixUtils.checkColumnIndex(this, endColumn);
+        if (startColumn > endColumn) {
+            throw new MatrixIndexException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN,
+                                           startColumn, endColumn);
+        }
+
+        final BigDecimal[][] subMatrixData =
+            new BigDecimal[endRow - startRow + 1][endColumn - startColumn + 1];
+        for (int i = startRow; i <= endRow; i++) {
+            System.arraycopy(data[i], startColumn,
+                             subMatrixData[i - startRow], 0,
+                             endColumn - startColumn + 1);
+        }
+
+        return new BigMatrixImpl(subMatrixData, false);
+
+    }
+
+    /**
+     * Gets a submatrix. Rows and columns are indicated
+     * counting from 0 to n-1.
+     *
+     * @param selectedRows Array of row indices must be non-empty
+     * @param selectedColumns Array of column indices must be non-empty
+     * @return The subMatrix containing the data in the
+     *     specified rows and columns
+     * @exception MatrixIndexException  if supplied row or column index arrays
+     *     are not valid
+     */
+    public BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
+        throws MatrixIndexException {
+
+        if (selectedRows.length * selectedColumns.length == 0) {
+            if (selectedRows.length == 0) {
+                throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY);
+            }
+            throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY);
+        }
+
+        final BigDecimal[][] subMatrixData =
+            new BigDecimal[selectedRows.length][selectedColumns.length];
+        try  {
+            for (int i = 0; i < selectedRows.length; i++) {
+                final BigDecimal[] subI = subMatrixData[i];
+                final BigDecimal[] dataSelectedI = data[selectedRows[i]];
+                for (int j = 0; j < selectedColumns.length; j++) {
+                    subI[j] = dataSelectedI[selectedColumns[j]];
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // we redo the loop with checks enabled
+            // in order to generate an appropriate message
+            for (final int row : selectedRows) {
+                MatrixUtils.checkRowIndex(this, row);
+            }
+            for (final int column : selectedColumns) {
+                MatrixUtils.checkColumnIndex(this, column);
+            }
+        }
+        return new BigMatrixImpl(subMatrixData, false);
+    }
+
+    /**
+     * Replace the submatrix starting at <code>row, column</code> using data in
+     * the input <code>subMatrix</code> array. Indexes are 0-based.
+     * <p>
+     * Example:<br>
+     * Starting with <pre>
+     * 1  2  3  4
+     * 5  6  7  8
+     * 9  0  1  2
+     * </pre>
+     * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
+     * <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
+     * 1  2  3  4
+     * 5  3  4  8
+     * 9  5  6  2
+     * </pre></p>
+     *
+     * @param subMatrix  array containing the submatrix replacement data
+     * @param row  row coordinate of the top, left element to be replaced
+     * @param column  column coordinate of the top, left element to be replaced
+     * @throws MatrixIndexException  if subMatrix does not fit into this
+     *    matrix from element in (row, column)
+     * @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>subMatrix</code> is null
+     * @since 1.1
+     */
+    public void setSubMatrix(BigDecimal[][] subMatrix, int row, int column)
+    throws MatrixIndexException {
+
+        final int nRows = subMatrix.length;
+        if (nRows == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+
+        final int nCols = subMatrix[0].length;
+        if (nCols == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+
+        for (int r = 1; r < nRows; r++) {
+            if (subMatrix[r].length != nCols) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                      nCols, subMatrix[r].length);
+            }
+        }
+
+        if (data == null) {
+            if (row > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                        LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET,
+                        row);
+            }
+            if (column > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                        LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET,
+                        column);
+            }
+            data = new BigDecimal[nRows][nCols];
+            System.arraycopy(subMatrix, 0, data, 0, subMatrix.length);
+        } else {
+            MatrixUtils.checkRowIndex(this, row);
+            MatrixUtils.checkColumnIndex(this, column);
+            MatrixUtils.checkRowIndex(this, nRows + row - 1);
+            MatrixUtils.checkColumnIndex(this, nCols + column - 1);
+        }
+        for (int i = 0; i < nRows; i++) {
+            System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols);
+        }
+
+        lu = null;
+
+    }
+
+    /**
+     * Returns the entries in row number <code>row</code>
+     * as a row matrix.  Row indices start at 0.
+     *
+     * @param row the row to be fetched
+     * @return row matrix
+     * @throws MatrixIndexException if the specified row index is invalid
+     */
+    public BigMatrix getRowMatrix(int row) throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        final int ncols = this.getColumnDimension();
+        final BigDecimal[][] out = new BigDecimal[1][ncols];
+        System.arraycopy(data[row], 0, out[0], 0, ncols);
+        return new BigMatrixImpl(out, false);
+    }
+
+    /**
+     * Returns the entries in column number <code>column</code>
+     * as a column matrix.  Column indices start at 0.
+     *
+     * @param column the column to be fetched
+     * @return column matrix
+     * @throws MatrixIndexException if the specified column index is invalid
+     */
+    public BigMatrix getColumnMatrix(int column) throws MatrixIndexException {
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = this.getRowDimension();
+        final BigDecimal[][] out = new BigDecimal[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            out[row][0] = data[row][column];
+        }
+        return new BigMatrixImpl(out, false);
+    }
+
+    /**
+     * Returns the entries in row number <code>row</code> as an array.
+     * <p>
+     * Row indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= row < rowDimension.</code></p>
+     *
+     * @param row the row to be fetched
+     * @return array of entries in the row
+     * @throws MatrixIndexException if the specified row index is not valid
+     */
+    public BigDecimal[] getRow(int row) throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        final int ncols = this.getColumnDimension();
+        final BigDecimal[] out = new BigDecimal[ncols];
+        System.arraycopy(data[row], 0, out, 0, ncols);
+        return out;
+    }
+
+     /**
+     * Returns the entries in row number <code>row</code> as an array
+     * of double values.
+     * <p>
+     * Row indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= row < rowDimension.</code></p>
+     *
+     * @param row the row to be fetched
+     * @return array of entries in the row
+     * @throws MatrixIndexException if the specified row index is not valid
+     */
+    public double[] getRowAsDoubleArray(int row) throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        final int ncols = this.getColumnDimension();
+        final double[] out = new double[ncols];
+        for (int i=0;i<ncols;i++) {
+            out[i] = data[row][i].doubleValue();
+        }
+        return out;
+    }
+
+     /**
+     * Returns the entries in column number <code>col</code> as an array.
+     * <p>
+     * Column indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= column < columnDimension.</code></p>
+     *
+     * @param col the column to be fetched
+     * @return array of entries in the column
+     * @throws MatrixIndexException if the specified column index is not valid
+     */
+    public BigDecimal[] getColumn(int col) throws MatrixIndexException {
+        MatrixUtils.checkColumnIndex(this, col);
+        final int nRows = this.getRowDimension();
+        final BigDecimal[] out = new BigDecimal[nRows];
+        for (int i = 0; i < nRows; i++) {
+            out[i] = data[i][col];
+        }
+        return out;
+    }
+
+    /**
+     * Returns the entries in column number <code>col</code> as an array
+     * of double values.
+     * <p>
+     * Column indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= column < columnDimension.</code></p>
+     *
+     * @param col the column to be fetched
+     * @return array of entries in the column
+     * @throws MatrixIndexException if the specified column index is not valid
+     */
+    public double[] getColumnAsDoubleArray(int col) throws MatrixIndexException {
+        MatrixUtils.checkColumnIndex(this, col);
+        final int nrows = this.getRowDimension();
+        final double[] out = new double[nrows];
+        for (int i=0;i<nrows;i++) {
+            out[i] = data[i][col].doubleValue();
+        }
+        return out;
+    }
+
+     /**
+     * Returns the entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be fetched
+     * @param column  column location of entry to be fetched
+     * @return matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     */
+    public BigDecimal getEntry(int row, int column)
+    throws MatrixIndexException {
+        try {
+            return data[row][column];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /**
+     * Returns the entry in the specified row and column as a double.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be fetched
+     * @param column  column location of entry to be fetched
+     * @return matrix entry in row,column
+     * @throws MatrixIndexException if the row
+     * or column index is not valid
+     */
+    public double getEntryAsDouble(int row, int column) throws MatrixIndexException {
+        return getEntry(row,column).doubleValue();
+    }
+
+    /**
+     * Returns the transpose matrix.
+     *
+     * @return transpose matrix
+     */
+    public BigMatrix transpose() {
+        final int nRows = this.getRowDimension();
+        final int nCols = this.getColumnDimension();
+        final BigDecimal[][] outData = new BigDecimal[nCols][nRows];
+        for (int row = 0; row < nRows; row++) {
+            final BigDecimal[] dataRow = data[row];
+            for (int col = 0; col < nCols; col++) {
+                outData[col][row] = dataRow[col];
+            }
+        }
+        return new BigMatrixImpl(outData, false);
+    }
+
+    /**
+     * Returns the inverse matrix if this matrix is invertible.
+     *
+     * @return inverse matrix
+     * @throws InvalidMatrixException if this is not invertible
+     */
+    public BigMatrix inverse() throws InvalidMatrixException {
+        return solve(MatrixUtils.createBigIdentityMatrix(getRowDimension()));
+    }
+
+    /**
+     * Returns the determinant of this matrix.
+     *
+     * @return determinant
+     * @throws InvalidMatrixException if matrix is not square
+     */
+    public BigDecimal getDeterminant() throws InvalidMatrixException {
+        if (!isSquare()) {
+            throw new NonSquareMatrixException(getRowDimension(), getColumnDimension());
+        }
+        if (isSingular()) {   // note: this has side effect of attempting LU decomp if lu == null
+            return ZERO;
+        } else {
+            BigDecimal det = (parity == 1) ? ONE : ONE.negate();
+            for (int i = 0; i < getRowDimension(); i++) {
+                det = det.multiply(lu[i][i]);
+            }
+            return det;
+        }
+    }
+
+     /**
+     * Is this a square matrix?
+     * @return true if the matrix is square (rowDimension = columnDimension)
+     */
+    public boolean isSquare() {
+        return getColumnDimension() == getRowDimension();
+    }
+
+    /**
+     * Is this a singular matrix?
+     * @return true if the matrix is singular
+     */
+    public boolean isSingular() {
+        if (lu == null) {
+            try {
+                luDecompose();
+                return false;
+            } catch (InvalidMatrixException ex) {
+                return true;
+            }
+        } else { // LU decomp must have been successfully performed
+            return false; // so the matrix is not singular
+        }
+    }
+
+    /**
+     * Returns the number of rows in the matrix.
+     *
+     * @return rowDimension
+     */
+    public int getRowDimension() {
+        return data.length;
+    }
+
+    /**
+     * Returns the number of columns in the matrix.
+     *
+     * @return columnDimension
+     */
+    public int getColumnDimension() {
+        return data[0].length;
+    }
+
+     /**
+     * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
+     * trace</a> of the matrix (the sum of the elements on the main diagonal).
+     *
+     * @return trace
+     *
+     * @throws IllegalArgumentException if this matrix is not square.
+     */
+    public BigDecimal getTrace() throws IllegalArgumentException {
+        if (!isSquare()) {
+            throw new NonSquareMatrixException(getRowDimension(), getColumnDimension());
+        }
+        BigDecimal trace = data[0][0];
+        for (int i = 1; i < this.getRowDimension(); i++) {
+            trace = trace.add(data[i][i]);
+        }
+        return trace;
+    }
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @param v the vector to operate on
+     * @return this*v
+     * @throws IllegalArgumentException if columnDimension != v.size()
+     */
+    public BigDecimal[] operate(BigDecimal[] v) throws IllegalArgumentException {
+        if (v.length != getColumnDimension()) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, getColumnDimension() );
+        }
+        final int nRows = this.getRowDimension();
+        final int nCols = this.getColumnDimension();
+        final BigDecimal[] out = new BigDecimal[nRows];
+        for (int row = 0; row < nRows; row++) {
+            BigDecimal sum = ZERO;
+            for (int i = 0; i < nCols; i++) {
+                sum = sum.add(data[row][i].multiply(v[i]));
+            }
+            out[row] = sum;
+        }
+        return out;
+    }
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @param v the vector to operate on
+     * @return this*v
+     * @throws IllegalArgumentException if columnDimension != v.size()
+     */
+    public BigDecimal[] operate(double[] v) throws IllegalArgumentException {
+        final BigDecimal bd[] = new BigDecimal[v.length];
+        for (int i = 0; i < bd.length; i++) {
+            bd[i] = new BigDecimal(v[i]);
+        }
+        return operate(bd);
+    }
+
+    /**
+     * Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
+     *
+     * @param v the row vector to premultiply by
+     * @return v*this
+     * @throws IllegalArgumentException if rowDimension != v.size()
+     */
+    public BigDecimal[] preMultiply(BigDecimal[] v) throws IllegalArgumentException {
+        final int nRows = this.getRowDimension();
+        if (v.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nRows );
+        }
+        final int nCols = this.getColumnDimension();
+        final BigDecimal[] out = new BigDecimal[nCols];
+        for (int col = 0; col < nCols; col++) {
+            BigDecimal sum = ZERO;
+            for (int i = 0; i < nRows; i++) {
+                sum = sum.add(data[i][col].multiply(v[i]));
+            }
+            out[col] = sum;
+        }
+        return out;
+    }
+
+    /**
+     * Returns a matrix of (column) solution vectors for linear systems with
+     * coefficient matrix = this and constant vectors = columns of
+     * <code>b</code>.
+     *
+     * @param b  array of constants forming RHS of linear systems to
+     * to solve
+     * @return solution array
+     * @throws IllegalArgumentException if this.rowDimension != row dimension
+     * @throws InvalidMatrixException if this matrix is not square or is singular
+     */
+    public BigDecimal[] solve(BigDecimal[] b) throws IllegalArgumentException, InvalidMatrixException {
+        final int nRows = this.getRowDimension();
+        if (b.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    b.length, nRows);
+        }
+        final BigMatrix bMatrix = new BigMatrixImpl(b);
+        final BigDecimal[][] solution = ((BigMatrixImpl) (solve(bMatrix))).getDataRef();
+        final BigDecimal[] out = new BigDecimal[nRows];
+        for (int row = 0; row < nRows; row++) {
+            out[row] = solution[row][0];
+        }
+        return out;
+    }
+
+    /**
+     * Returns a matrix of (column) solution vectors for linear systems with
+     * coefficient matrix = this and constant vectors = columns of
+     * <code>b</code>.
+     *
+     * @param b  array of constants forming RHS of linear systems to
+     * to solve
+     * @return solution array
+     * @throws IllegalArgumentException if this.rowDimension != row dimension
+     * @throws InvalidMatrixException if this matrix is not square or is singular
+     */
+    public BigDecimal[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException {
+        final BigDecimal bd[] = new BigDecimal[b.length];
+        for (int i = 0; i < bd.length; i++) {
+            bd[i] = new BigDecimal(b[i]);
+        }
+        return solve(bd);
+    }
+
+    /**
+     * Returns a matrix of (column) solution vectors for linear systems with
+     * coefficient matrix = this and constant vectors = columns of
+     * <code>b</code>.
+     *
+     * @param b  matrix of constant vectors forming RHS of linear systems to
+     * to solve
+     * @return matrix of solution vectors
+     * @throws IllegalArgumentException if this.rowDimension != row dimension
+     * @throws InvalidMatrixException if this matrix is not square or is singular
+     */
+    public BigMatrix solve(BigMatrix b) throws IllegalArgumentException, InvalidMatrixException  {
+        if (b.getRowDimension() != getRowDimension()) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    b.getRowDimension(), b.getColumnDimension(), getRowDimension(), "n");
+        }
+        if (!isSquare()) {
+            throw new NonSquareMatrixException(getRowDimension(), getColumnDimension());
+        }
+        if (this.isSingular()) { // side effect: compute LU decomp
+            throw new SingularMatrixException();
+        }
+
+        final int nCol = this.getColumnDimension();
+        final int nColB = b.getColumnDimension();
+        final int nRowB = b.getRowDimension();
+
+        // Apply permutations to b
+        final BigDecimal[][] bp = new BigDecimal[nRowB][nColB];
+        for (int row = 0; row < nRowB; row++) {
+            final BigDecimal[] bpRow = bp[row];
+            for (int col = 0; col < nColB; col++) {
+                bpRow[col] = b.getEntry(permutation[row], col);
+            }
+        }
+
+        // Solve LY = b
+        for (int col = 0; col < nCol; col++) {
+            for (int i = col + 1; i < nCol; i++) {
+                final BigDecimal[] bpI = bp[i];
+                final BigDecimal[] luI = lu[i];
+                for (int j = 0; j < nColB; j++) {
+                    bpI[j] = bpI[j].subtract(bp[col][j].multiply(luI[col]));
+                }
+            }
+        }
+
+        // Solve UX = Y
+        for (int col = nCol - 1; col >= 0; col--) {
+            final BigDecimal[] bpCol = bp[col];
+            final BigDecimal luDiag = lu[col][col];
+            for (int j = 0; j < nColB; j++) {
+                bpCol[j] = bpCol[j].divide(luDiag, scale, roundingMode);
+            }
+            for (int i = 0; i < col; i++) {
+                final BigDecimal[] bpI = bp[i];
+                final BigDecimal[] luI = lu[i];
+                for (int j = 0; j < nColB; j++) {
+                    bpI[j] = bpI[j].subtract(bp[col][j].multiply(luI[col]));
+                }
+            }
+        }
+
+        return new BigMatrixImpl(bp, false);
+
+    }
+
+    /**
+     * Computes a new
+     * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
+     * LU decompostion</a> for this matrix, storing the result for use by other methods.
+     * <p>
+     * <strong>Implementation Note</strong>:<br>
+     * Uses <a href="http://www.damtp.cam.ac.uk/user/fdl/people/sd/lectures/nummeth98/linear.htm">
+     * Crout's algortithm</a>, with partial pivoting.</p>
+     * <p>
+     * <strong>Usage Note</strong>:<br>
+     * This method should rarely be invoked directly. Its only use is
+     * to force recomputation of the LU decomposition when changes have been
+     * made to the underlying data using direct array references. Changes
+     * made using setXxx methods will trigger recomputation when needed
+     * automatically.</p>
+     *
+     * @throws InvalidMatrixException if the matrix is non-square or singular.
+     */
+    public void luDecompose() throws InvalidMatrixException {
+
+        final int nRows = this.getRowDimension();
+        final int nCols = this.getColumnDimension();
+        if (nRows != nCols) {
+            throw new NonSquareMatrixException(getRowDimension(), getColumnDimension());
+        }
+        lu = this.getData();
+
+        // Initialize permutation array and parity
+        permutation = new int[nRows];
+        for (int row = 0; row < nRows; row++) {
+            permutation[row] = row;
+        }
+        parity = 1;
+
+        // Loop over columns
+        for (int col = 0; col < nCols; col++) {
+
+            BigDecimal sum = ZERO;
+
+            // upper
+            for (int row = 0; row < col; row++) {
+                final BigDecimal[] 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 max = col; // permutation row
+            BigDecimal largest = ZERO;
+            for (int row = col; row < nRows; row++) {
+                final BigDecimal[] 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;
+
+                // maintain best permutation choice
+                if (sum.abs().compareTo(largest) == 1) {
+                    largest = sum.abs();
+                    max = row;
+                }
+            }
+
+            // Singularity check
+            if (lu[max][col].abs().compareTo(TOO_SMALL) <= 0) {
+                lu = null;
+                throw new SingularMatrixException();
+            }
+
+            // Pivot if necessary
+            if (max != col) {
+                BigDecimal tmp = ZERO;
+                for (int i = 0; i < nCols; i++) {
+                    tmp = lu[max][i];
+                    lu[max][i] = lu[col][i];
+                    lu[col][i] = tmp;
+                }
+                int temp = permutation[max];
+                permutation[max] = permutation[col];
+                permutation[col] = temp;
+                parity = -parity;
+            }
+
+            // Divide the lower elements by the "winning" diagonal elt.
+            final BigDecimal luDiag = lu[col][col];
+            for (int row = col + 1; row < nRows; row++) {
+                final BigDecimal[] luRow = lu[row];
+                luRow[col] = luRow[col].divide(luDiag, scale, roundingMode);
+            }
+
+        }
+
+    }
+
+    /**
+     * Get a string representation for this matrix.
+     * @return a string representation for this matrix
+     */
+    @Override
+    public String toString() {
+        StringBuilder res = new StringBuilder();
+        res.append("BigMatrixImpl{");
+        if (data != null) {
+            for (int i = 0; i < data.length; i++) {
+                if (i > 0) {
+                    res.append(",");
+                }
+                res.append("{");
+                for (int j = 0; j < data[0].length; j++) {
+                    if (j > 0) {
+                        res.append(",");
+                    }
+                    res.append(data[i][j]);
+                }
+                res.append("}");
+            }
+        }
+        res.append("}");
+        return res.toString();
+    }
+
+    /**
+     * Returns true iff <code>object</code> is a
+     * <code>BigMatrixImpl</code> instance with the same dimensions as this
+     * and all corresponding matrix entries are equal.  BigDecimal.equals
+     * is used to compare corresponding entries.
+     *
+     * @param object the object to test equality against.
+     * @return true if object equals this
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this ) {
+            return true;
+        }
+        if (object instanceof BigMatrixImpl == false) {
+            return false;
+        }
+        final BigMatrix m = (BigMatrix) object;
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) {
+            return false;
+        }
+        for (int row = 0; row < nRows; row++) {
+            final BigDecimal[] dataRow = data[row];
+            for (int col = 0; col < nCols; col++) {
+                if (!dataRow[col].equals(m.getEntry(row, col))) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Computes a hashcode for the matrix.
+     *
+     * @return hashcode for matrix
+     */
+    @Override
+    public int hashCode() {
+        int ret = 7;
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        ret = ret * 31 + nRows;
+        ret = ret * 31 + nCols;
+        for (int row = 0; row < nRows; row++) {
+            final BigDecimal[] dataRow = data[row];
+            for (int col = 0; col < nCols; col++) {
+                ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) *
+                dataRow[col].hashCode();
+            }
+        }
+        return ret;
+    }
+
+    //------------------------ Protected methods
+
+    /**
+     *  Returns the LU decomposition as a BigMatrix.
+     *  Returns a fresh copy of the cached LU matrix if this has been computed;
+     *  otherwise the composition is computed and cached for use by other methods.
+     *  Since a copy is returned in either case, changes to the returned matrix do not
+     *  affect the LU decomposition property.
+     * <p>
+     * The matrix returned is a compact representation of the LU decomposition.
+     * Elements below the main diagonal correspond to entries of the "L" matrix;
+     * elements on and above the main diagonal correspond to entries of the "U"
+     * matrix.</p>
+     * <p>
+     * Example: <pre>
+     *
+     *     Returned matrix                L                  U
+     *         2  3  1                   1  0  0            2  3  1
+     *         5  4  6                   5  1  0            0  4  6
+     *         1  7  8                   1  7  1            0  0  8
+     * </pre>
+     *
+     * The L and U matrices satisfy the matrix equation LU = permuteRows(this), <br>
+     *  where permuteRows reorders the rows of the matrix to follow the order determined
+     *  by the <a href=#getPermutation()>permutation</a> property.</p>
+     *
+     * @return LU decomposition matrix
+     * @throws InvalidMatrixException if the matrix is non-square or singular.
+     */
+    protected BigMatrix getLUMatrix() throws InvalidMatrixException {
+        if (lu == null) {
+            luDecompose();
+        }
+        return new BigMatrixImpl(lu);
+    }
+
+    /**
+     * Returns the permutation associated with the lu decomposition.
+     * The entries of the array represent a permutation of the numbers 0, ... , nRows - 1.
+     * <p>
+     * Example:
+     * permutation = [1, 2, 0] means current 2nd row is first, current third row is second
+     * and current first row is last.</p>
+     * <p>
+     * Returns a fresh copy of the array.</p>
+     *
+     * @return the permutation
+     */
+    protected int[] getPermutation() {
+        final int[] out = new int[permutation.length];
+        System.arraycopy(permutation, 0, out, 0, permutation.length);
+        return out;
+    }
+
+    //------------------------ Private methods
+
+    /**
+     * Returns a fresh copy of the underlying data array.
+     *
+     * @return a copy of the underlying data array.
+     */
+    private BigDecimal[][] copyOut() {
+        final int nRows = this.getRowDimension();
+        final BigDecimal[][] out = new BigDecimal[nRows][this.getColumnDimension()];
+        // can't copy 2-d array in one shot, otherwise get row references
+        for (int i = 0; i < nRows; i++) {
+            System.arraycopy(data[i], 0, out[i], 0, data[i].length);
+        }
+        return out;
+    }
+
+    /**
+     * Replaces data with a fresh copy of the input array.
+     * <p>
+     * Verifies that the input array is rectangular and non-empty.</p>
+     *
+     * @param in data to copy in
+     * @throws IllegalArgumentException if input array is emtpy or not
+     *    rectangular
+     * @throws NullPointerException if input array is null
+     */
+    private void copyIn(BigDecimal[][] in) {
+        setSubMatrix(in,0,0);
+    }
+
+    /**
+     * Replaces data with a fresh copy of the input array.
+     *
+     * @param in data to copy in
+     */
+    private void copyIn(double[][] in) {
+        final int nRows = in.length;
+        final int nCols = in[0].length;
+        data = new BigDecimal[nRows][nCols];
+        for (int i = 0; i < nRows; i++) {
+            final BigDecimal[] dataI = data[i];
+            final double[] inI = in[i];
+            for (int j = 0; j < nCols; j++) {
+                dataI[j] = new BigDecimal(inI[j]);
+            }
+        }
+        lu = null;
+    }
+
+    /**
+     * Replaces data with BigDecimals represented by the strings in the input
+     * array.
+     *
+     * @param in data to copy in
+     */
+    private void copyIn(String[][] in) {
+        final int nRows = in.length;
+        final int nCols = in[0].length;
+        data = new BigDecimal[nRows][nCols];
+        for (int i = 0; i < nRows; i++) {
+            final BigDecimal[] dataI = data[i];
+            final String[] inI = in[i];
+            for (int j = 0; j < nCols; j++) {
+                dataI[j] = new BigDecimal(inI[j]);
+            }
+        }
+        lu = null;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/BlockFieldMatrix.java b/src/main/java/org/apache/commons/math/linear/BlockFieldMatrix.java
new file mode 100644
index 0000000..35ae1c2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/BlockFieldMatrix.java
@@ -0,0 +1,1670 @@
+/*
+ * 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 org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Cache-friendly implementation of FieldMatrix using a flat arrays to store
+ * square blocks of the matrix.
+ * <p>
+ * This implementation is specially designed to be cache-friendly. Square blocks are
+ * stored as small arrays and allow efficient traversal of data both in row major direction
+ * and columns major direction, one block at a time. This greatly increases performances
+ * for algorithms that use crossed directions loops like multiplication or transposition.
+ * </p>
+ * <p>
+ * The size of square blocks is a static parameter. It may be tuned according to the cache
+ * size of the target computer processor. As a rule of thumbs, it should be the largest
+ * value that allows three blocks to be simultaneously cached (this is necessary for example
+ * for matrix multiplication). The default value is to use 36x36 blocks.
+ * </p>
+ * <p>
+ * The regular blocks represent {@link #BLOCK_SIZE} x {@link #BLOCK_SIZE} squares. Blocks
+ * at right hand side and bottom side which may be smaller to fit matrix dimensions. The square
+ * blocks are flattened in row major order in single dimension arrays which are therefore
+ * {@link #BLOCK_SIZE}<sup>2</sup> elements long for regular blocks. The blocks are themselves
+ * organized in row major order.
+ * </p>
+ * <p>
+ * As an example, for a block size of 36x36, a 100x60 matrix would be stored in 6 blocks.
+ * Block 0 would be a Field[1296] array holding the upper left 36x36 square, block 1 would be
+ * a Field[1296] array holding the upper center 36x36 square, block 2 would be a Field[1008]
+ * array holding the upper right 36x28 rectangle, block 3 would be a Field[864] array holding
+ * the lower left 24x36 rectangle, block 4 would be a Field[864] array holding the lower center
+ * 24x36 rectangle and block 5 would be a Field[672] array holding the lower right 24x28
+ * rectangle.
+ * </p>
+ * <p>
+ * The layout complexity overhead versus simple mapping of matrices to java
+ * arrays is negligible for small matrices (about 1%). The gain from cache efficiency leads
+ * to up to 3-fold improvements for matrices of moderate to large size.
+ * </p>
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> implements Serializable {
+
+    /** Block size. */
+    public static final int BLOCK_SIZE = 36;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -4602336630143123183L;
+
+    /** Blocks of matrix entries. */
+    private final T blocks[][];
+
+    /** Number of rows of the matrix. */
+    private final int rows;
+
+    /** Number of columns of the matrix. */
+    private final int columns;
+
+    /** Number of block rows of the matrix. */
+    private final int blockRows;
+
+    /** Number of block columns of the matrix. */
+    private final int blockColumns;
+
+    /**
+     * Create a new matrix with the supplied row and column dimensions.
+     *
+     * @param field field to which the elements belong
+     * @param rows  the number of rows in the new matrix
+     * @param columns  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not
+     *  positive
+     */
+    public BlockFieldMatrix(final Field<T> field, final int rows, final int columns)
+        throws IllegalArgumentException {
+
+        super(field, rows, columns);
+        this.rows    = rows;
+        this.columns = columns;
+
+        // number of blocks
+        blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        // allocate storage blocks, taking care of smaller ones at right and bottom
+        blocks = createBlocksLayout(field, rows, columns);
+
+    }
+
+    /**
+     * Create a new dense matrix copying entries from raw layout data.
+     * <p>The input array <em>must</em> already be in raw layout.</p>
+     * <p>Calling this constructor is equivalent to call:
+     * <pre>matrix = new BlockFieldMatrix<T>(getField(), rawData.length, rawData[0].length,
+     *                                   toBlocksLayout(rawData), false);</pre>
+     * </p>
+     * @param rawData data for new matrix, in raw layout
+     *
+     * @exception IllegalArgumentException if <code>blockData</code> shape is
+     * inconsistent with block layout
+     * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean)
+     */
+    public BlockFieldMatrix(final T[][] rawData)
+        throws IllegalArgumentException {
+        this(rawData.length, rawData[0].length, toBlocksLayout(rawData), false);
+    }
+
+    /**
+     * Create a new dense matrix copying entries from block layout data.
+     * <p>The input array <em>must</em> already be in blocks layout.</p>
+     * @param rows  the number of rows in the new matrix
+     * @param columns  the number of columns in the new matrix
+     * @param blockData data for new matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     *
+     * @exception IllegalArgumentException if <code>blockData</code> shape is
+     * inconsistent with block layout
+     * @see #createBlocksLayout(Field, int, int)
+     * @see #toBlocksLayout(FieldElement[][])
+     * @see #BlockFieldMatrix(FieldElement[][])
+     */
+    public BlockFieldMatrix(final int rows, final int columns,
+                            final T[][] blockData, final boolean copyArray)
+        throws IllegalArgumentException {
+
+        super(extractField(blockData), rows, columns);
+        this.rows    = rows;
+        this.columns = columns;
+
+        // number of blocks
+        blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        if (copyArray) {
+            // allocate storage blocks, taking care of smaller ones at right and bottom
+            blocks = buildArray(getField(), blockRows * blockColumns, -1);
+        } else {
+            // reference existing array
+            blocks = blockData;
+        }
+
+        int index = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock, ++index) {
+                if (blockData[index].length != iHeight * blockWidth(jBlock)) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.WRONG_BLOCK_LENGTH,
+                            blockData[index].length, iHeight * blockWidth(jBlock));
+                }
+                if (copyArray) {
+                    blocks[index] = blockData[index].clone();
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Convert a data array from raw layout to blocks layout.
+     * <p>
+     * Raw layout is the straightforward layout where element at row i and
+     * column j is in array element <code>rawData[i][j]</code>. Blocks layout
+     * is the layout used in {@link BlockFieldMatrix} instances, where the matrix
+     * is split in square blocks (except at right and bottom side where blocks may
+     * be rectangular to fit matrix size) and each block is stored in a flattened
+     * one-dimensional array.
+     * </p>
+     * <p>
+     * This method creates an array in blocks layout from an input array in raw layout.
+     * It can be used to provide the array argument of the {@link
+     * #BlockFieldMatrix(int, int, FieldElement[][], boolean)}
+     * constructor.
+     * </p>
+     * @param <T> the type of the field elements
+     * @param rawData data array in raw layout
+     * @return a new data array containing the same entries but in blocks layout
+     * @exception IllegalArgumentException if <code>rawData</code> is not rectangular
+     *  (not all rows have the same length)
+     * @see #createBlocksLayout(Field, int, int)
+     * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean)
+     */
+    public static <T extends FieldElement<T>> T[][] toBlocksLayout(final T[][] rawData)
+        throws IllegalArgumentException {
+
+        final int rows         = rawData.length;
+        final int columns      = rawData[0].length;
+        final int blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        // safety checks
+        for (int i = 0; i < rawData.length; ++i) {
+            final int length = rawData[i].length;
+            if (length != columns) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                        columns, length);
+            }
+        }
+
+        // convert array
+        final Field<T> field = extractField(rawData);
+        final T[][] blocks = buildArray(field, blockRows * blockColumns, -1);
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart  = iBlock * BLOCK_SIZE;
+            final int pEnd    = FastMath.min(pStart + BLOCK_SIZE, rows);
+            final int iHeight = pEnd - pStart;
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final int jWidth = qEnd - qStart;
+
+                // allocate new block
+                final T[] block = buildArray(field, iHeight * jWidth);
+                blocks[blockIndex] = block;
+
+                // copy data
+                int index = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    System.arraycopy(rawData[p], qStart, block, index, jWidth);
+                    index += jWidth;
+                }
+
+                ++blockIndex;
+
+            }
+        }
+
+        return blocks;
+
+    }
+
+    /**
+     * Create a data array in blocks layout.
+     * <p>
+     * This method can be used to create the array argument of the {@link
+     * #BlockFieldMatrix(int, int, FieldElement[][], boolean)}
+     * constructor.
+     * </p>
+     * @param <T> the type of the field elements
+     * @param field field to which the elements belong
+     * @param rows  the number of rows in the new matrix
+     * @param columns  the number of columns in the new matrix
+     * @return a new data array in blocks layout
+     * @see #toBlocksLayout(FieldElement[][])
+     * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean)
+     */
+    public static <T extends FieldElement<T>> T[][] createBlocksLayout(final Field<T> field,
+                                                                       final int rows, final int columns) {
+
+        final int blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        final T[][] blocks = buildArray(field, blockRows * blockColumns, -1);
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart  = iBlock * BLOCK_SIZE;
+            final int pEnd    = FastMath.min(pStart + BLOCK_SIZE, rows);
+            final int iHeight = pEnd - pStart;
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final int jWidth = qEnd - qStart;
+                blocks[blockIndex] = buildArray(field, iHeight * jWidth);
+                ++blockIndex;
+            }
+        }
+
+        return blocks;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        return new BlockFieldMatrix<T>(getField(), rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> copy() {
+
+        // create an empty matrix
+        BlockFieldMatrix<T> copied = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+        // copy the blocks
+        for (int i = 0; i < blocks.length; ++i) {
+            System.arraycopy(blocks[i], 0, copied.blocks[i], 0, blocks[i].length);
+        }
+
+        return copied;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> add(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        try {
+            return add((BlockFieldMatrix<T>) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            checkAdditionCompatible(m);
+
+            final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+            // perform addition block-wise, to ensure good cache behavior
+            int blockIndex = 0;
+            for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+                for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+
+                    // perform addition on the current block
+                    final T[] outBlock = out.blocks[blockIndex];
+                    final T[] tBlock   = blocks[blockIndex];
+                    final int      pStart   = iBlock * BLOCK_SIZE;
+                    final int      pEnd     = FastMath.min(pStart + BLOCK_SIZE, rows);
+                    final int      qStart   = jBlock * BLOCK_SIZE;
+                    final int      qEnd     = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    int k = 0;
+                    for (int p = pStart; p < pEnd; ++p) {
+                        for (int q = qStart; q < qEnd; ++q) {
+                            outBlock[k] = tBlock[k].add(m.getEntry(p, q));
+                            ++k;
+                        }
+                    }
+
+                    // go to next block
+                    ++blockIndex;
+
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BlockFieldMatrix<T> add(final BlockFieldMatrix<T> m)
+        throws IllegalArgumentException {
+
+        // safety check
+        checkAdditionCompatible(m);
+
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+        // perform addition block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final T[] outBlock = out.blocks[blockIndex];
+            final T[] tBlock   = blocks[blockIndex];
+            final T[] mBlock   = m.blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k].add(mBlock[k]);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> subtract(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        try {
+            return subtract((BlockFieldMatrix<T>) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            checkSubtractionCompatible(m);
+
+            final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+            // perform subtraction block-wise, to ensure good cache behavior
+            int blockIndex = 0;
+            for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+                for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+
+                    // perform subtraction on the current block
+                    final T[] outBlock = out.blocks[blockIndex];
+                    final T[] tBlock   = blocks[blockIndex];
+                    final int      pStart   = iBlock * BLOCK_SIZE;
+                    final int      pEnd     = FastMath.min(pStart + BLOCK_SIZE, rows);
+                    final int      qStart   = jBlock * BLOCK_SIZE;
+                    final int      qEnd     = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    int k = 0;
+                    for (int p = pStart; p < pEnd; ++p) {
+                        for (int q = qStart; q < qEnd; ++q) {
+                            outBlock[k] = tBlock[k].subtract(m.getEntry(p, q));
+                            ++k;
+                        }
+                    }
+
+                    // go to next block
+                    ++blockIndex;
+
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Compute this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this - m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BlockFieldMatrix<T> subtract(final BlockFieldMatrix<T> m)
+        throws IllegalArgumentException {
+
+        // safety check
+        checkSubtractionCompatible(m);
+
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+        // perform subtraction block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final T[] outBlock = out.blocks[blockIndex];
+            final T[] tBlock   = blocks[blockIndex];
+            final T[] mBlock   = m.blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k].subtract(mBlock[k]);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> scalarAdd(final T d)
+        throws IllegalArgumentException {
+
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+        // perform subtraction block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final T[] outBlock = out.blocks[blockIndex];
+            final T[] tBlock   = blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k].add(d);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> scalarMultiply(final T d)
+        throws IllegalArgumentException {
+
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns);
+
+        // perform subtraction block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final T[] outBlock = out.blocks[blockIndex];
+            final T[] tBlock   = blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k].multiply(d);
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> multiply(final FieldMatrix<T> m)
+        throws IllegalArgumentException {
+        try {
+            return multiply((BlockFieldMatrix<T>) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            checkMultiplicationCompatible(m);
+
+            final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, m.getColumnDimension());
+            final T zero = getField().getZero();
+
+            // perform multiplication block-wise, to ensure good cache behavior
+            int blockIndex = 0;
+            for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+
+                final int pStart = iBlock * BLOCK_SIZE;
+                final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+
+                for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+
+                    final int qStart = jBlock * BLOCK_SIZE;
+                    final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, m.getColumnDimension());
+
+                    // select current block
+                    final T[] outBlock = out.blocks[blockIndex];
+
+                    // perform multiplication on current block
+                    for (int kBlock = 0; kBlock < blockColumns; ++kBlock) {
+                        final int kWidth      = blockWidth(kBlock);
+                        final T[] tBlock = blocks[iBlock * blockColumns + kBlock];
+                        final int rStart      = kBlock * BLOCK_SIZE;
+                        int k = 0;
+                        for (int p = pStart; p < pEnd; ++p) {
+                            final int lStart = (p - pStart) * kWidth;
+                            final int lEnd   = lStart + kWidth;
+                            for (int q = qStart; q < qEnd; ++q) {
+                                T sum = zero;
+                                int r = rStart;
+                                for (int l = lStart; l < lEnd; ++l) {
+                                    sum = sum.add(tBlock[l].multiply(m.getEntry(r, q)));
+                                    ++r;
+                                }
+                                outBlock[k] = outBlock[k].add(sum);
+                                ++k;
+                            }
+                        }
+                    }
+
+                    // go to next block
+                    ++blockIndex;
+
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by m.
+     *
+     * @param m    matrix to postmultiply by
+     * @return     this * m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public BlockFieldMatrix<T> multiply(BlockFieldMatrix<T> m) throws IllegalArgumentException {
+
+        // safety check
+        checkMultiplicationCompatible(m);
+
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, m.columns);
+        final T zero = getField().getZero();
+
+        // perform multiplication block-wise, to ensure good cache behavior
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+
+            for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+                final int jWidth = out.blockWidth(jBlock);
+                final int jWidth2 = jWidth  + jWidth;
+                final int jWidth3 = jWidth2 + jWidth;
+                final int jWidth4 = jWidth3 + jWidth;
+
+                // select current block
+                final T[] outBlock = out.blocks[blockIndex];
+
+                // perform multiplication on current block
+                for (int kBlock = 0; kBlock < blockColumns; ++kBlock) {
+                    final int kWidth = blockWidth(kBlock);
+                    final T[] tBlock = blocks[iBlock * blockColumns + kBlock];
+                    final T[] mBlock = m.blocks[kBlock * m.blockColumns + jBlock];
+                    int k = 0;
+                    for (int p = pStart; p < pEnd; ++p) {
+                        final int lStart = (p - pStart) * kWidth;
+                        final int lEnd   = lStart + kWidth;
+                        for (int nStart = 0; nStart < jWidth; ++nStart) {
+                            T sum = zero;
+                            int l = lStart;
+                            int n = nStart;
+                            while (l < lEnd - 3) {
+                                sum = sum.
+                                      add(tBlock[l].multiply(mBlock[n])).
+                                      add(tBlock[l + 1].multiply(mBlock[n + jWidth])).
+                                      add(tBlock[l + 2].multiply(mBlock[n + jWidth2])).
+                                      add(tBlock[l + 3].multiply(mBlock[n + jWidth3]));
+                                l += 4;
+                                n += jWidth4;
+                            }
+                            while (l < lEnd) {
+                                sum = sum.add(tBlock[l++].multiply(mBlock[n]));
+                                n += jWidth;
+                            }
+                            outBlock[k] = outBlock[k].add(sum);
+                            ++k;
+                        }
+                    }
+                }
+
+                // go to next block
+                ++blockIndex;
+
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[][] getData() {
+
+        final T[][] data = buildArray(getField(), getRowDimension(), getColumnDimension());
+        final int lastColumns = columns - (blockColumns - 1) * BLOCK_SIZE;
+
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            int regularPos   = 0;
+            int lastPos      = 0;
+            for (int p = pStart; p < pEnd; ++p) {
+                final T[] dataP = data[p];
+                int blockIndex = iBlock * blockColumns;
+                int dataPos    = 0;
+                for (int jBlock = 0; jBlock < blockColumns - 1; ++jBlock) {
+                    System.arraycopy(blocks[blockIndex++], regularPos, dataP, dataPos, BLOCK_SIZE);
+                    dataPos += BLOCK_SIZE;
+                }
+                System.arraycopy(blocks[blockIndex], lastPos, dataP, dataPos, lastColumns);
+                regularPos += BLOCK_SIZE;
+                lastPos    += lastColumns;
+            }
+        }
+
+        return data;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow,
+                                   final int startColumn, final int endColumn)
+        throws MatrixIndexException {
+
+        // safety checks
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+
+        // create the output matrix
+        final BlockFieldMatrix<T> out =
+            new BlockFieldMatrix<T>(getField(), endRow - startRow + 1, endColumn - startColumn + 1);
+
+        // compute blocks shifts
+        final int blockStartRow    = startRow    / BLOCK_SIZE;
+        final int rowsShift        = startRow    % BLOCK_SIZE;
+        final int blockStartColumn = startColumn / BLOCK_SIZE;
+        final int columnsShift     = startColumn % BLOCK_SIZE;
+
+        // perform extraction block-wise, to ensure good cache behavior
+        int pBlock = blockStartRow;
+        for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+            final int iHeight = out.blockHeight(iBlock);
+            int qBlock = blockStartColumn;
+            for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+                final int jWidth = out.blockWidth(jBlock);
+
+                // handle one block of the output matrix
+                final int      outIndex = iBlock * out.blockColumns + jBlock;
+                final T[] outBlock = out.blocks[outIndex];
+                final int      index    = pBlock * blockColumns + qBlock;
+                final int      width    = blockWidth(qBlock);
+
+                final int heightExcess = iHeight + rowsShift - BLOCK_SIZE;
+                final int widthExcess  = jWidth + columnsShift - BLOCK_SIZE;
+                if (heightExcess > 0) {
+                    // the submatrix block spans on two blocks rows from the original matrix
+                    if (widthExcess > 0) {
+                        // the submatrix block spans on two blocks columns from the original matrix
+                        final int width2 = blockWidth(qBlock + 1);
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, BLOCK_SIZE,
+                                      columnsShift, BLOCK_SIZE,
+                                      outBlock, jWidth, 0, 0);
+                        copyBlockPart(blocks[index + 1], width2,
+                                      rowsShift, BLOCK_SIZE,
+                                      0, widthExcess,
+                                      outBlock, jWidth, 0, jWidth - widthExcess);
+                        copyBlockPart(blocks[index + blockColumns], width,
+                                      0, heightExcess,
+                                      columnsShift, BLOCK_SIZE,
+                                      outBlock, jWidth, iHeight - heightExcess, 0);
+                        copyBlockPart(blocks[index + blockColumns + 1], width2,
+                                      0, heightExcess,
+                                      0, widthExcess,
+                                      outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess);
+                    } else {
+                        // the submatrix block spans on one block column from the original matrix
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, BLOCK_SIZE,
+                                      columnsShift, jWidth + columnsShift,
+                                      outBlock, jWidth, 0, 0);
+                        copyBlockPart(blocks[index + blockColumns], width,
+                                      0, heightExcess,
+                                      columnsShift, jWidth + columnsShift,
+                                      outBlock, jWidth, iHeight - heightExcess, 0);
+                    }
+                } else {
+                    // the submatrix block spans on one block row from the original matrix
+                    if (widthExcess > 0) {
+                        // the submatrix block spans on two blocks columns from the original matrix
+                        final int width2 = blockWidth(qBlock + 1);
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, iHeight + rowsShift,
+                                      columnsShift, BLOCK_SIZE,
+                                      outBlock, jWidth, 0, 0);
+                        copyBlockPart(blocks[index + 1], width2,
+                                      rowsShift, iHeight + rowsShift,
+                                      0, widthExcess,
+                                      outBlock, jWidth, 0, jWidth - widthExcess);
+                    } else {
+                        // the submatrix block spans on one block column from the original matrix
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, iHeight + rowsShift,
+                                      columnsShift, jWidth + columnsShift,
+                                      outBlock, jWidth, 0, 0);
+                    }
+               }
+
+                ++qBlock;
+            }
+
+            ++pBlock;
+
+        }
+
+        return out;
+
+    }
+
+    /**
+     * Copy a part of a block into another one
+     * <p>This method can be called only when the specified part fits in both
+     * blocks, no verification is done here.</p>
+     * @param srcBlock source block
+     * @param srcWidth source block width ({@link #BLOCK_SIZE} or smaller)
+     * @param srcStartRow start row in the source block
+     * @param srcEndRow end row (exclusive) in the source block
+     * @param srcStartColumn start column in the source block
+     * @param srcEndColumn end column (exclusive) in the source block
+     * @param dstBlock destination block
+     * @param dstWidth destination block width ({@link #BLOCK_SIZE} or smaller)
+     * @param dstStartRow start row in the destination block
+     * @param dstStartColumn start column in the destination block
+     */
+    private void copyBlockPart(final T[] srcBlock, final int srcWidth,
+                               final int srcStartRow, final int srcEndRow,
+                               final int srcStartColumn, final int srcEndColumn,
+                               final T[] dstBlock, final int dstWidth,
+                               final int dstStartRow, final int dstStartColumn) {
+        final int length = srcEndColumn - srcStartColumn;
+        int srcPos = srcStartRow * srcWidth + srcStartColumn;
+        int dstPos = dstStartRow * dstWidth + dstStartColumn;
+        for (int srcRow = srcStartRow; srcRow < srcEndRow; ++srcRow) {
+            System.arraycopy(srcBlock, srcPos, dstBlock, dstPos, length);
+            srcPos += srcWidth;
+            dstPos += dstWidth;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubMatrix(final T[][] subMatrix, final int row, final int column)
+        throws MatrixIndexException {
+
+        // safety checks
+        final int refLength = subMatrix[0].length;
+        if (refLength < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+        final int endRow    = row + subMatrix.length - 1;
+        final int endColumn = column + refLength - 1;
+        checkSubMatrixIndex(row, endRow, column, endColumn);
+        for (final T[] subRow : subMatrix) {
+            if (subRow.length != refLength) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                        refLength, subRow.length);
+            }
+        }
+
+        // compute blocks bounds
+        final int blockStartRow    = row / BLOCK_SIZE;
+        final int blockEndRow      = (endRow + BLOCK_SIZE) / BLOCK_SIZE;
+        final int blockStartColumn = column / BLOCK_SIZE;
+        final int blockEndColumn   = (endColumn + BLOCK_SIZE) / BLOCK_SIZE;
+
+        // perform copy block-wise, to ensure good cache behavior
+        for (int iBlock = blockStartRow; iBlock < blockEndRow; ++iBlock) {
+            final int iHeight  = blockHeight(iBlock);
+            final int firstRow = iBlock * BLOCK_SIZE;
+            final int iStart   = FastMath.max(row,    firstRow);
+            final int iEnd     = FastMath.min(endRow + 1, firstRow + iHeight);
+
+            for (int jBlock = blockStartColumn; jBlock < blockEndColumn; ++jBlock) {
+                final int jWidth      = blockWidth(jBlock);
+                final int firstColumn = jBlock * BLOCK_SIZE;
+                final int jStart      = FastMath.max(column,    firstColumn);
+                final int jEnd        = FastMath.min(endColumn + 1, firstColumn + jWidth);
+                final int jLength     = jEnd - jStart;
+
+                // handle one block, row by row
+                final T[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int i = iStart; i < iEnd; ++i) {
+                    System.arraycopy(subMatrix[i - row], jStart - column,
+                                     block, (i - firstRow) * jWidth + (jStart - firstColumn),
+                                     jLength);
+                }
+
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> getRowMatrix(final int row)
+        throws MatrixIndexException {
+
+        checkRowIndex(row);
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), 1, columns);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outBlockIndex = 0;
+        int outIndex      = 0;
+        T[] outBlock = out.blocks[outBlockIndex];
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            final int available  = outBlock.length - outIndex;
+            if (jWidth > available) {
+                System.arraycopy(block, iRow * jWidth, outBlock, outIndex, available);
+                outBlock = out.blocks[++outBlockIndex];
+                System.arraycopy(block, iRow * jWidth, outBlock, 0, jWidth - available);
+                outIndex = jWidth - available;
+            } else {
+                System.arraycopy(block, iRow * jWidth, outBlock, outIndex, jWidth);
+                outIndex += jWidth;
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRowMatrix(final int row, final FieldMatrix<T> matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setRowMatrix(row, (BlockFieldMatrix<T>) matrix);
+        } catch (ClassCastException cce) {
+            super.setRowMatrix(row, matrix);
+        }
+    }
+
+    /**
+     * Sets the entries in row number <code>row</code>
+     * as a row matrix.  Row indices start at 0.
+     *
+     * @param row the row to be set
+     * @param matrix row matrix (must have one row and the same number of columns
+     * as the instance)
+     * @throws MatrixIndexException if the specified row index is invalid
+     * @throws InvalidMatrixException if the matrix dimensions do not match one
+     * instance row
+     */
+    public void setRowMatrix(final int row, final BlockFieldMatrix<T> matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        if ((matrix.getRowDimension() != 1) ||
+            (matrix.getColumnDimension() != nCols)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(),
+                    1, nCols);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock = row / BLOCK_SIZE;
+        final int iRow   = row - iBlock * BLOCK_SIZE;
+        int mBlockIndex  = 0;
+        int mIndex       = 0;
+        T[] mBlock  = matrix.blocks[mBlockIndex];
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            final int available  = mBlock.length - mIndex;
+            if (jWidth > available) {
+                System.arraycopy(mBlock, mIndex, block, iRow * jWidth, available);
+                mBlock = matrix.blocks[++mBlockIndex];
+                System.arraycopy(mBlock, 0, block, iRow * jWidth, jWidth - available);
+                mIndex = jWidth - available;
+            } else {
+                System.arraycopy(mBlock, mIndex, block, iRow * jWidth, jWidth);
+                mIndex += jWidth;
+           }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> getColumnMatrix(final int column)
+        throws MatrixIndexException {
+
+        checkColumnIndex(column);
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, 1);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outBlockIndex = 0;
+        int outIndex      = 0;
+        T[] outBlock = out.blocks[outBlockIndex];
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                if (outIndex >= outBlock.length) {
+                    outBlock = out.blocks[++outBlockIndex];
+                    outIndex = 0;
+                }
+                outBlock[outIndex++] = block[i * jWidth + jColumn];
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setColumnMatrix(final int column, final FieldMatrix<T> matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setColumnMatrix(column, (BlockFieldMatrix<T>) matrix);
+        } catch (ClassCastException cce) {
+            super.setColumnMatrix(column, matrix);
+        }
+    }
+
+    /**
+     * Sets the entries in column number <code>column</code>
+     * as a column matrix.  Column indices start at 0.
+     *
+     * @param column the column to be set
+     * @param matrix column matrix (must have one column and the same number of rows
+     * as the instance)
+     * @throws MatrixIndexException if the specified column index is invalid
+     * @throws InvalidMatrixException if the matrix dimensions do not match one
+     * instance column
+     */
+    void setColumnMatrix(final int column, final BlockFieldMatrix<T> matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        if ((matrix.getRowDimension() != nRows) ||
+            (matrix.getColumnDimension() != 1)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(),
+                    nRows, 1);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int mBlockIndex = 0;
+        int mIndex      = 0;
+        T[] mBlock = matrix.blocks[mBlockIndex];
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                if (mIndex >= mBlock.length) {
+                    mBlock = matrix.blocks[++mBlockIndex];
+                    mIndex = 0;
+                }
+                block[i * jWidth + jColumn] = mBlock[mIndex++];
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldVector<T> getRowVector(final int row)
+        throws MatrixIndexException {
+
+        checkRowIndex(row);
+        final T[] outData = buildArray(getField(), columns);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outIndex      = 0;
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            System.arraycopy(block, iRow * jWidth, outData, outIndex, jWidth);
+            outIndex += jWidth;
+        }
+
+        return new ArrayFieldVector<T>(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRowVector(final int row, final FieldVector<T> vector)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setRow(row, ((ArrayFieldVector<T>) vector).getDataRef());
+        } catch (ClassCastException cce) {
+            super.setRowVector(row, vector);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldVector<T> getColumnVector(final int column)
+        throws MatrixIndexException {
+
+        checkColumnIndex(column);
+        final T[] outData = buildArray(getField(), rows);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outIndex      = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                outData[outIndex++] = block[i * jWidth + jColumn];
+            }
+        }
+
+        return new ArrayFieldVector<T>(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setColumnVector(final int column, final FieldVector<T> vector)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setColumn(column, ((ArrayFieldVector<T>) vector).getDataRef());
+        } catch (ClassCastException cce) {
+            super.setColumnVector(column, vector);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[] getRow(final int row)
+        throws MatrixIndexException {
+
+        checkRowIndex(row);
+        final T[] out = buildArray(getField(), columns);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outIndex      = 0;
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            System.arraycopy(block, iRow * jWidth, out, outIndex, jWidth);
+            outIndex += jWidth;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRow(final int row, final T[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkRowIndex(row);
+        final int nCols = getColumnDimension();
+        if (array.length != nCols) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    1, array.length, 1, nCols);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outIndex      = 0;
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            System.arraycopy(array, outIndex, block, iRow * jWidth, jWidth);
+            outIndex += jWidth;
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[] getColumn(final int column)
+        throws MatrixIndexException {
+
+        checkColumnIndex(column);
+        final T[] out = buildArray(getField(), rows);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outIndex      = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                out[outIndex++] = block[i * jWidth + jColumn];
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setColumn(final int column, final T[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        checkColumnIndex(column);
+        final int nRows = getRowDimension();
+        if (array.length != nRows) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    array.length, 1, nRows, 1);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outIndex      = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final T[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                block[i * jWidth + jColumn] = array[outIndex++];
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T getEntry(final int row, final int column)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            return blocks[iBlock * blockColumns + jBlock][k];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(final int row, final int column, final T value)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            blocks[iBlock * blockColumns + jBlock][k] = value;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(final int row, final int column, final T increment)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            final T[] blockIJ = blocks[iBlock * blockColumns + jBlock];
+            blockIJ[k] = blockIJ[k].add(increment);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(final int row, final int column, final T factor)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            final T[] blockIJ = blocks[iBlock * blockColumns + jBlock];
+            blockIJ[k] = blockIJ[k].multiply(factor);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> transpose() {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), nCols, nRows);
+
+        // perform transpose block-wise, to ensure good cache behavior
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockColumns; ++iBlock) {
+            for (int jBlock = 0; jBlock < blockRows; ++jBlock) {
+
+                // transpose current block
+                final T[] outBlock = out.blocks[blockIndex];
+                final T[] tBlock   = blocks[jBlock * blockColumns + iBlock];
+                final int      pStart   = iBlock * BLOCK_SIZE;
+                final int      pEnd     = FastMath.min(pStart + BLOCK_SIZE, columns);
+                final int      qStart   = jBlock * BLOCK_SIZE;
+                final int      qEnd     = FastMath.min(qStart + BLOCK_SIZE, rows);
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    final int lInc = pEnd - pStart;
+                    int l = p - pStart;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        outBlock[k] = tBlock[l];
+                        ++k;
+                        l+= lInc;
+                    }
+                }
+
+                // go to next block
+                ++blockIndex;
+
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return rows;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return columns;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[] operate(final T[] v)
+        throws IllegalArgumentException {
+
+        if (v.length != columns) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, columns);
+        }
+        final T[] out = buildArray(getField(), rows);
+        final T zero = getField().getZero();
+
+        // perform multiplication block-wise, to ensure good cache behavior
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final T[] block  = blocks[iBlock * blockColumns + jBlock];
+                final int      qStart = jBlock * BLOCK_SIZE;
+                final int      qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    T sum = zero;
+                    int q = qStart;
+                    while (q < qEnd - 3) {
+                        sum = sum.
+                              add(block[k].multiply(v[q])).
+                              add(block[k + 1].multiply(v[q + 1])).
+                              add(block[k + 2].multiply(v[q + 2])).
+                              add(block[k + 3].multiply(v[q + 3]));
+                        k += 4;
+                        q += 4;
+                    }
+                    while (q < qEnd) {
+                        sum = sum.add(block[k++].multiply(v[q++]));
+                    }
+                    out[p] = out[p].add(sum);
+                }
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T[] preMultiply(final T[] v)
+        throws IllegalArgumentException {
+
+        if (v.length != rows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, rows);
+        }
+        final T[] out = buildArray(getField(), columns);
+        final T zero = getField().getZero();
+
+        // perform multiplication block-wise, to ensure good cache behavior
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth  = blockWidth(jBlock);
+            final int jWidth2 = jWidth  + jWidth;
+            final int jWidth3 = jWidth2 + jWidth;
+            final int jWidth4 = jWidth3 + jWidth;
+            final int qStart = jBlock * BLOCK_SIZE;
+            final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+            for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+                final T[] block  = blocks[iBlock * blockColumns + jBlock];
+                final int      pStart = iBlock * BLOCK_SIZE;
+                final int      pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+                for (int q = qStart; q < qEnd; ++q) {
+                    int k = q - qStart;
+                    T sum = zero;
+                    int p = pStart;
+                    while (p < pEnd - 3) {
+                        sum = sum.
+                              add(block[k].multiply(v[p])).
+                              add(block[k + jWidth].multiply(v[p + 1])).
+                              add(block[k + jWidth2].multiply(v[p + 2])).
+                              add(block[k + jWidth3].multiply(v[p + 3]));
+                        k += jWidth4;
+                        p += 4;
+                    }
+                    while (p < pEnd) {
+                        sum = sum.add(block[k].multiply(v[p++]));
+                        k += jWidth;
+                    }
+                    out[q] = out[q].add(sum);
+                }
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int qStart = jBlock * BLOCK_SIZE;
+                    final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    final T[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - pStart) * jWidth;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int qStart = jBlock * BLOCK_SIZE;
+                    final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    final T[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - pStart) * jWidth;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int q0     = jBlock * BLOCK_SIZE;
+                    final int qStart = FastMath.max(startColumn, q0);
+                    final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                    final T[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int q0     = jBlock * BLOCK_SIZE;
+                    final int qStart = FastMath.max(startColumn, q0);
+                    final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                    final T[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final T[] block = blocks[blockIndex];
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+                ++blockIndex;
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final T[] block = blocks[blockIndex];
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+                ++blockIndex;
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                final int jWidth = blockWidth(jBlock);
+                final int q0     = jBlock * BLOCK_SIZE;
+                final int qStart = FastMath.max(startColumn, q0);
+                final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                final T[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int p = pStart; p < pEnd; ++p) {
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                final int jWidth = blockWidth(jBlock);
+                final int q0     = jBlock * BLOCK_SIZE;
+                final int qStart = FastMath.max(startColumn, q0);
+                final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                final T[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int p = pStart; p < pEnd; ++p) {
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+            }
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Get the height of a block.
+     * @param blockRow row index (in block sense) of the block
+     * @return height (number of rows) of the block
+     */
+    private int blockHeight(final int blockRow) {
+        return (blockRow == blockRows - 1) ? rows - blockRow * BLOCK_SIZE : BLOCK_SIZE;
+    }
+
+    /**
+     * Get the width of a block.
+     * @param blockColumn column index (in block sense) of the block
+     * @return width (number of columns) of the block
+     */
+    private int blockWidth(final int blockColumn) {
+        return (blockColumn == blockColumns - 1) ? columns - blockColumn * BLOCK_SIZE : BLOCK_SIZE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/BlockRealMatrix.java b/src/main/java/org/apache/commons/math/linear/BlockRealMatrix.java
new file mode 100644
index 0000000..5e7060e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/BlockRealMatrix.java
@@ -0,0 +1,1690 @@
+/*
+ * 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.MathRuntimeException;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Cache-friendly implementation of RealMatrix using a flat arrays to store
+ * square blocks of the matrix.
+ * <p>
+ * This implementation is specially designed to be cache-friendly. Square blocks are
+ * stored as small arrays and allow efficient traversal of data both in row major direction
+ * and columns major direction, one block at a time. This greatly increases performances
+ * for algorithms that use crossed directions loops like multiplication or transposition.
+ * </p>
+ * <p>
+ * The size of square blocks is a static parameter. It may be tuned according to the cache
+ * size of the target computer processor. As a rule of thumbs, it should be the largest
+ * value that allows three blocks to be simultaneously cached (this is necessary for example
+ * for matrix multiplication). The default value is to use 52x52 blocks which is well suited
+ * for processors with 64k L1 cache (one block holds 2704 values or 21632 bytes). This value
+ * could be lowered to 36x36 for processors with 32k L1 cache.
+ * </p>
+ * <p>
+ * The regular blocks represent {@link #BLOCK_SIZE} x {@link #BLOCK_SIZE} squares. Blocks
+ * at right hand side and bottom side which may be smaller to fit matrix dimensions. The square
+ * blocks are flattened in row major order in single dimension arrays which are therefore
+ * {@link #BLOCK_SIZE}<sup>2</sup> elements long for regular blocks. The blocks are themselves
+ * organized in row major order.
+ * </p>
+ * <p>
+ * As an example, for a block size of 52x52, a 100x60 matrix would be stored in 4 blocks.
+ * Block 0 would be a double[2704] array holding the upper left 52x52 square, block 1 would be
+ * a double[416] array holding the upper right 52x8 rectangle, block 2 would be a double[2496]
+ * array holding the lower left 48x52 rectangle and block 3 would be a double[384] array
+ * holding the lower right 48x8 rectangle.
+ * </p>
+ * <p>
+ * The layout complexity overhead versus simple mapping of matrices to java
+ * arrays is negligible for small matrices (about 1%). The gain from cache efficiency leads
+ * to up to 3-fold improvements for matrices of moderate to large size.
+ * </p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class BlockRealMatrix extends AbstractRealMatrix implements Serializable {
+
+    /** Block size. */
+    public static final int BLOCK_SIZE = 52;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4991895511313664478L;
+
+    /** Blocks of matrix entries. */
+    private final double blocks[][];
+
+    /** Number of rows of the matrix. */
+    private final int rows;
+
+    /** Number of columns of the matrix. */
+    private final int columns;
+
+    /** Number of block rows of the matrix. */
+    private final int blockRows;
+
+    /** Number of block columns of the matrix. */
+    private final int blockColumns;
+
+    /**
+     * Create a new matrix with the supplied row and column dimensions.
+     *
+     * @param rows  the number of rows in the new matrix
+     * @param columns  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not
+     *  positive
+     */
+    public BlockRealMatrix(final int rows, final int columns)
+        throws IllegalArgumentException {
+
+        super(rows, columns);
+        this.rows    = rows;
+        this.columns = columns;
+
+        // number of blocks
+        blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        // allocate storage blocks, taking care of smaller ones at right and bottom
+        blocks = createBlocksLayout(rows, columns);
+
+    }
+
+    /**
+     * Create a new dense matrix copying entries from raw layout data.
+     * <p>The input array <em>must</em> already be in raw layout.</p>
+     * <p>Calling this constructor is equivalent to call:
+     * <pre>matrix = new BlockRealMatrix(rawData.length, rawData[0].length,
+     *                                   toBlocksLayout(rawData), false);</pre>
+     * </p>
+     * @param rawData data for new matrix, in raw layout
+     *
+     * @exception IllegalArgumentException if <code>blockData</code> shape is
+     * inconsistent with block layout
+     * @see #BlockRealMatrix(int, int, double[][], boolean)
+     */
+    public BlockRealMatrix(final double[][] rawData)
+        throws IllegalArgumentException {
+        this(rawData.length, rawData[0].length, toBlocksLayout(rawData), false);
+    }
+
+    /**
+     * Create a new dense matrix copying entries from block layout data.
+     * <p>The input array <em>must</em> already be in blocks layout.</p>
+     * @param rows  the number of rows in the new matrix
+     * @param columns  the number of columns in the new matrix
+     * @param blockData data for new matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     *
+     * @exception IllegalArgumentException if <code>blockData</code> shape is
+     * inconsistent with block layout
+     * @see #createBlocksLayout(int, int)
+     * @see #toBlocksLayout(double[][])
+     * @see #BlockRealMatrix(double[][])
+     */
+    public BlockRealMatrix(final int rows, final int columns,
+                           final double[][] blockData, final boolean copyArray)
+        throws IllegalArgumentException {
+
+        super(rows, columns);
+        this.rows    = rows;
+        this.columns = columns;
+
+        // number of blocks
+        blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        if (copyArray) {
+            // allocate storage blocks, taking care of smaller ones at right and bottom
+            blocks = new double[blockRows * blockColumns][];
+        } else {
+            // reference existing array
+            blocks = blockData;
+        }
+
+        int index = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock, ++index) {
+                if (blockData[index].length != iHeight * blockWidth(jBlock)) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.WRONG_BLOCK_LENGTH,
+                            blockData[index].length, iHeight * blockWidth(jBlock));
+                }
+                if (copyArray) {
+                    blocks[index] = blockData[index].clone();
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Convert a data array from raw layout to blocks layout.
+     * <p>
+     * Raw layout is the straightforward layout where element at row i and
+     * column j is in array element <code>rawData[i][j]</code>. Blocks layout
+     * is the layout used in {@link BlockRealMatrix} instances, where the matrix
+     * is split in square blocks (except at right and bottom side where blocks may
+     * be rectangular to fit matrix size) and each block is stored in a flattened
+     * one-dimensional array.
+     * </p>
+     * <p>
+     * This method creates an array in blocks layout from an input array in raw layout.
+     * It can be used to provide the array argument of the {@link
+     * #BlockRealMatrix(int, int, double[][], boolean)} constructor.
+     * </p>
+     * @param rawData data array in raw layout
+     * @return a new data array containing the same entries but in blocks layout
+     * @exception IllegalArgumentException if <code>rawData</code> is not rectangular
+     *  (not all rows have the same length)
+     * @see #createBlocksLayout(int, int)
+     * @see #BlockRealMatrix(int, int, double[][], boolean)
+     */
+    public static double[][] toBlocksLayout(final double[][] rawData)
+        throws IllegalArgumentException {
+
+        final int rows         = rawData.length;
+        final int columns      = rawData[0].length;
+        final int blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        // safety checks
+        for (int i = 0; i < rawData.length; ++i) {
+            final int length = rawData[i].length;
+            if (length != columns) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                        columns, length);
+            }
+        }
+
+        // convert array
+        final double[][] blocks = new double[blockRows * blockColumns][];
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart  = iBlock * BLOCK_SIZE;
+            final int pEnd    = FastMath.min(pStart + BLOCK_SIZE, rows);
+            final int iHeight = pEnd - pStart;
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final int jWidth = qEnd - qStart;
+
+                // allocate new block
+                final double[] block = new double[iHeight * jWidth];
+                blocks[blockIndex] = block;
+
+                // copy data
+                int index = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    System.arraycopy(rawData[p], qStart, block, index, jWidth);
+                    index += jWidth;
+                }
+
+                ++blockIndex;
+
+            }
+        }
+
+        return blocks;
+
+    }
+
+    /**
+     * Create a data array in blocks layout.
+     * <p>
+     * This method can be used to create the array argument of the {@link
+     * #BlockRealMatrix(int, int, double[][], boolean)} constructor.
+     * </p>
+     * @param rows  the number of rows in the new matrix
+     * @param columns  the number of columns in the new matrix
+     * @return a new data array in blocks layout
+     * @see #toBlocksLayout(double[][])
+     * @see #BlockRealMatrix(int, int, double[][], boolean)
+     */
+    public static double[][] createBlocksLayout(final int rows, final int columns) {
+
+        final int blockRows    = (rows    + BLOCK_SIZE - 1) / BLOCK_SIZE;
+        final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE;
+
+        final double[][] blocks = new double[blockRows * blockColumns][];
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart  = iBlock * BLOCK_SIZE;
+            final int pEnd    = FastMath.min(pStart + BLOCK_SIZE, rows);
+            final int iHeight = pEnd - pStart;
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final int jWidth = qEnd - qStart;
+                blocks[blockIndex] = new double[iHeight * jWidth];
+                ++blockIndex;
+            }
+        }
+
+        return blocks;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        return new BlockRealMatrix(rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix copy() {
+
+        // create an empty matrix
+        BlockRealMatrix copied = new BlockRealMatrix(rows, columns);
+
+        // copy the blocks
+        for (int i = 0; i < blocks.length; ++i) {
+            System.arraycopy(blocks[i], 0, copied.blocks[i], 0, blocks[i].length);
+        }
+
+        return copied;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix add(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return add((BlockRealMatrix) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkAdditionCompatible(this, m);
+
+            final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
+
+            // perform addition block-wise, to ensure good cache behavior
+            int blockIndex = 0;
+            for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+                for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+
+                    // perform addition on the current block
+                    final double[] outBlock = out.blocks[blockIndex];
+                    final double[] tBlock   = blocks[blockIndex];
+                    final int      pStart   = iBlock * BLOCK_SIZE;
+                    final int      pEnd     = FastMath.min(pStart + BLOCK_SIZE, rows);
+                    final int      qStart   = jBlock * BLOCK_SIZE;
+                    final int      qEnd     = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    int k = 0;
+                    for (int p = pStart; p < pEnd; ++p) {
+                        for (int q = qStart; q < qEnd; ++q) {
+                            outBlock[k] = tBlock[k] + m.getEntry(p, q);
+                            ++k;
+                        }
+                    }
+
+                    // go to next block
+                    ++blockIndex;
+
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BlockRealMatrix add(final BlockRealMatrix m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
+
+        // perform addition block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final double[] outBlock = out.blocks[blockIndex];
+            final double[] tBlock   = blocks[blockIndex];
+            final double[] mBlock   = m.blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k] + mBlock[k];
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix subtract(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return subtract((BlockRealMatrix) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkSubtractionCompatible(this, m);
+
+            final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
+
+            // perform subtraction block-wise, to ensure good cache behavior
+            int blockIndex = 0;
+            for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+                for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+
+                    // perform subtraction on the current block
+                    final double[] outBlock = out.blocks[blockIndex];
+                    final double[] tBlock   = blocks[blockIndex];
+                    final int      pStart   = iBlock * BLOCK_SIZE;
+                    final int      pEnd     = FastMath.min(pStart + BLOCK_SIZE, rows);
+                    final int      qStart   = jBlock * BLOCK_SIZE;
+                    final int      qEnd     = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    int k = 0;
+                    for (int p = pStart; p < pEnd; ++p) {
+                        for (int q = qStart; q < qEnd; ++q) {
+                            outBlock[k] = tBlock[k] - m.getEntry(p, q);
+                            ++k;
+                        }
+                    }
+
+                    // go to next block
+                    ++blockIndex;
+
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Compute this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this - m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public BlockRealMatrix subtract(final BlockRealMatrix m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkSubtractionCompatible(this, m);
+
+        final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
+
+        // perform subtraction block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final double[] outBlock = out.blocks[blockIndex];
+            final double[] tBlock   = blocks[blockIndex];
+            final double[] mBlock   = m.blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k] - mBlock[k];
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix scalarAdd(final double d)
+        throws IllegalArgumentException {
+
+        final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
+
+        // perform subtraction block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final double[] outBlock = out.blocks[blockIndex];
+            final double[] tBlock   = blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k] + d;
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix scalarMultiply(final double d)
+        throws IllegalArgumentException {
+
+        final BlockRealMatrix out = new BlockRealMatrix(rows, columns);
+
+        // perform subtraction block-wise, to ensure good cache behavior
+        for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) {
+            final double[] outBlock = out.blocks[blockIndex];
+            final double[] tBlock   = blocks[blockIndex];
+            for (int k = 0; k < outBlock.length; ++k) {
+                outBlock[k] = tBlock[k] * d;
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix multiply(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return multiply((BlockRealMatrix) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkMultiplicationCompatible(this, m);
+
+            final BlockRealMatrix out = new BlockRealMatrix(rows, m.getColumnDimension());
+
+            // perform multiplication block-wise, to ensure good cache behavior
+            int blockIndex = 0;
+            for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+
+                final int pStart = iBlock * BLOCK_SIZE;
+                final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+
+                for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+
+                    final int qStart = jBlock * BLOCK_SIZE;
+                    final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, m.getColumnDimension());
+
+                    // select current block
+                    final double[] outBlock = out.blocks[blockIndex];
+
+                    // perform multiplication on current block
+                    for (int kBlock = 0; kBlock < blockColumns; ++kBlock) {
+                        final int kWidth      = blockWidth(kBlock);
+                        final double[] tBlock = blocks[iBlock * blockColumns + kBlock];
+                        final int rStart      = kBlock * BLOCK_SIZE;
+                        int k = 0;
+                        for (int p = pStart; p < pEnd; ++p) {
+                            final int lStart = (p - pStart) * kWidth;
+                            final int lEnd   = lStart + kWidth;
+                            for (int q = qStart; q < qEnd; ++q) {
+                                double sum = 0;
+                                int r = rStart;
+                                for (int l = lStart; l < lEnd; ++l) {
+                                    sum += tBlock[l] * m.getEntry(r, q);
+                                    ++r;
+                                }
+                                outBlock[k] += sum;
+                                ++k;
+                            }
+                        }
+                    }
+
+                    // go to next block
+                    ++blockIndex;
+
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by m.
+     *
+     * @param m    matrix to postmultiply by
+     * @return     this * m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public BlockRealMatrix multiply(BlockRealMatrix m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkMultiplicationCompatible(this, m);
+
+        final BlockRealMatrix out = new BlockRealMatrix(rows, m.columns);
+
+        // perform multiplication block-wise, to ensure good cache behavior
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+
+            for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+                final int jWidth = out.blockWidth(jBlock);
+                final int jWidth2 = jWidth  + jWidth;
+                final int jWidth3 = jWidth2 + jWidth;
+                final int jWidth4 = jWidth3 + jWidth;
+
+                // select current block
+                final double[] outBlock = out.blocks[blockIndex];
+
+                // perform multiplication on current block
+                for (int kBlock = 0; kBlock < blockColumns; ++kBlock) {
+                    final int kWidth = blockWidth(kBlock);
+                    final double[] tBlock = blocks[iBlock * blockColumns + kBlock];
+                    final double[] mBlock = m.blocks[kBlock * m.blockColumns + jBlock];
+                    int k = 0;
+                    for (int p = pStart; p < pEnd; ++p) {
+                        final int lStart = (p - pStart) * kWidth;
+                        final int lEnd   = lStart + kWidth;
+                        for (int nStart = 0; nStart < jWidth; ++nStart) {
+                            double sum = 0;
+                            int l = lStart;
+                            int n = nStart;
+                            while (l < lEnd - 3) {
+                                sum += tBlock[l] * mBlock[n] +
+                                       tBlock[l + 1] * mBlock[n + jWidth] +
+                                       tBlock[l + 2] * mBlock[n + jWidth2] +
+                                       tBlock[l + 3] * mBlock[n + jWidth3];
+                                l += 4;
+                                n += jWidth4;
+                            }
+                            while (l < lEnd) {
+                                sum += tBlock[l++] * mBlock[n];
+                                n += jWidth;
+                            }
+                            outBlock[k] += sum;
+                            ++k;
+                        }
+                    }
+                }
+
+                // go to next block
+                ++blockIndex;
+
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[][] getData() {
+
+        final double[][] data = new double[getRowDimension()][getColumnDimension()];
+        final int lastColumns = columns - (blockColumns - 1) * BLOCK_SIZE;
+
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            int regularPos   = 0;
+            int lastPos      = 0;
+            for (int p = pStart; p < pEnd; ++p) {
+                final double[] dataP = data[p];
+                int blockIndex = iBlock * blockColumns;
+                int dataPos    = 0;
+                for (int jBlock = 0; jBlock < blockColumns - 1; ++jBlock) {
+                    System.arraycopy(blocks[blockIndex++], regularPos, dataP, dataPos, BLOCK_SIZE);
+                    dataPos += BLOCK_SIZE;
+                }
+                System.arraycopy(blocks[blockIndex], lastPos, dataP, dataPos, lastColumns);
+                regularPos += BLOCK_SIZE;
+                lastPos    += lastColumns;
+            }
+        }
+
+        return data;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getNorm() {
+        final double[] colSums = new double[BLOCK_SIZE];
+        double maxColSum = 0;
+        for (int jBlock = 0; jBlock < blockColumns; jBlock++) {
+            final int jWidth = blockWidth(jBlock);
+            Arrays.fill(colSums, 0, jWidth, 0.0);
+            for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+                final int iHeight = blockHeight(iBlock);
+                final double[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int j = 0; j < jWidth; ++j) {
+                    double sum = 0;
+                    for (int i = 0; i < iHeight; ++i) {
+                        sum += FastMath.abs(block[i * jWidth + j]);
+                    }
+                    colSums[j] += sum;
+                }
+            }
+            for (int j = 0; j < jWidth; ++j) {
+                maxColSum = FastMath.max(maxColSum, colSums[j]);
+            }
+        }
+        return maxColSum;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getFrobeniusNorm() {
+        double sum2 = 0;
+        for (int blockIndex = 0; blockIndex < blocks.length; ++blockIndex) {
+            for (final double entry : blocks[blockIndex]) {
+                sum2 += entry * entry;
+            }
+        }
+        return FastMath.sqrt(sum2);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix getSubMatrix(final int startRow, final int endRow,
+                                   final int startColumn, final int endColumn)
+        throws MatrixIndexException {
+
+        // safety checks
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+
+        // create the output matrix
+        final BlockRealMatrix out =
+            new BlockRealMatrix(endRow - startRow + 1, endColumn - startColumn + 1);
+
+        // compute blocks shifts
+        final int blockStartRow    = startRow    / BLOCK_SIZE;
+        final int rowsShift        = startRow    % BLOCK_SIZE;
+        final int blockStartColumn = startColumn / BLOCK_SIZE;
+        final int columnsShift     = startColumn % BLOCK_SIZE;
+
+        // perform extraction block-wise, to ensure good cache behavior
+        int pBlock = blockStartRow;
+        for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) {
+            final int iHeight = out.blockHeight(iBlock);
+            int qBlock = blockStartColumn;
+            for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) {
+                final int jWidth = out.blockWidth(jBlock);
+
+                // handle one block of the output matrix
+                final int      outIndex = iBlock * out.blockColumns + jBlock;
+                final double[] outBlock = out.blocks[outIndex];
+                final int      index    = pBlock * blockColumns + qBlock;
+                final int      width    = blockWidth(qBlock);
+
+                final int heightExcess = iHeight + rowsShift - BLOCK_SIZE;
+                final int widthExcess  = jWidth + columnsShift - BLOCK_SIZE;
+                if (heightExcess > 0) {
+                    // the submatrix block spans on two blocks rows from the original matrix
+                    if (widthExcess > 0) {
+                        // the submatrix block spans on two blocks columns from the original matrix
+                        final int width2 = blockWidth(qBlock + 1);
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, BLOCK_SIZE,
+                                      columnsShift, BLOCK_SIZE,
+                                      outBlock, jWidth, 0, 0);
+                        copyBlockPart(blocks[index + 1], width2,
+                                      rowsShift, BLOCK_SIZE,
+                                      0, widthExcess,
+                                      outBlock, jWidth, 0, jWidth - widthExcess);
+                        copyBlockPart(blocks[index + blockColumns], width,
+                                      0, heightExcess,
+                                      columnsShift, BLOCK_SIZE,
+                                      outBlock, jWidth, iHeight - heightExcess, 0);
+                        copyBlockPart(blocks[index + blockColumns + 1], width2,
+                                      0, heightExcess,
+                                      0, widthExcess,
+                                      outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess);
+                    } else {
+                        // the submatrix block spans on one block column from the original matrix
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, BLOCK_SIZE,
+                                      columnsShift, jWidth + columnsShift,
+                                      outBlock, jWidth, 0, 0);
+                        copyBlockPart(blocks[index + blockColumns], width,
+                                      0, heightExcess,
+                                      columnsShift, jWidth + columnsShift,
+                                      outBlock, jWidth, iHeight - heightExcess, 0);
+                    }
+                } else {
+                    // the submatrix block spans on one block row from the original matrix
+                    if (widthExcess > 0) {
+                        // the submatrix block spans on two blocks columns from the original matrix
+                        final int width2 = blockWidth(qBlock + 1);
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, iHeight + rowsShift,
+                                      columnsShift, BLOCK_SIZE,
+                                      outBlock, jWidth, 0, 0);
+                        copyBlockPart(blocks[index + 1], width2,
+                                      rowsShift, iHeight + rowsShift,
+                                      0, widthExcess,
+                                      outBlock, jWidth, 0, jWidth - widthExcess);
+                    } else {
+                        // the submatrix block spans on one block column from the original matrix
+                        copyBlockPart(blocks[index], width,
+                                      rowsShift, iHeight + rowsShift,
+                                      columnsShift, jWidth + columnsShift,
+                                      outBlock, jWidth, 0, 0);
+                    }
+               }
+
+                ++qBlock;
+
+            }
+
+            ++pBlock;
+
+        }
+
+        return out;
+
+    }
+
+    /**
+     * Copy a part of a block into another one
+     * <p>This method can be called only when the specified part fits in both
+     * blocks, no verification is done here.</p>
+     * @param srcBlock source block
+     * @param srcWidth source block width ({@link #BLOCK_SIZE} or smaller)
+     * @param srcStartRow start row in the source block
+     * @param srcEndRow end row (exclusive) in the source block
+     * @param srcStartColumn start column in the source block
+     * @param srcEndColumn end column (exclusive) in the source block
+     * @param dstBlock destination block
+     * @param dstWidth destination block width ({@link #BLOCK_SIZE} or smaller)
+     * @param dstStartRow start row in the destination block
+     * @param dstStartColumn start column in the destination block
+     */
+    private void copyBlockPart(final double[] srcBlock, final int srcWidth,
+                               final int srcStartRow, final int srcEndRow,
+                               final int srcStartColumn, final int srcEndColumn,
+                               final double[] dstBlock, final int dstWidth,
+                               final int dstStartRow, final int dstStartColumn) {
+        final int length = srcEndColumn - srcStartColumn;
+        int srcPos = srcStartRow * srcWidth + srcStartColumn;
+        int dstPos = dstStartRow * dstWidth + dstStartColumn;
+        for (int srcRow = srcStartRow; srcRow < srcEndRow; ++srcRow) {
+            System.arraycopy(srcBlock, srcPos, dstBlock, dstPos, length);
+            srcPos += srcWidth;
+            dstPos += dstWidth;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
+        throws MatrixIndexException {
+
+        // safety checks
+        final int refLength = subMatrix[0].length;
+        if (refLength < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+        final int endRow    = row + subMatrix.length - 1;
+        final int endColumn = column + refLength - 1;
+        MatrixUtils.checkSubMatrixIndex(this, row, endRow, column, endColumn);
+        for (final double[] subRow : subMatrix) {
+            if (subRow.length != refLength) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                        refLength, subRow.length);
+            }
+        }
+
+        // compute blocks bounds
+        final int blockStartRow    = row / BLOCK_SIZE;
+        final int blockEndRow      = (endRow + BLOCK_SIZE) / BLOCK_SIZE;
+        final int blockStartColumn = column / BLOCK_SIZE;
+        final int blockEndColumn   = (endColumn + BLOCK_SIZE) / BLOCK_SIZE;
+
+        // perform copy block-wise, to ensure good cache behavior
+        for (int iBlock = blockStartRow; iBlock < blockEndRow; ++iBlock) {
+            final int iHeight  = blockHeight(iBlock);
+            final int firstRow = iBlock * BLOCK_SIZE;
+            final int iStart   = FastMath.max(row,    firstRow);
+            final int iEnd     = FastMath.min(endRow + 1, firstRow + iHeight);
+
+            for (int jBlock = blockStartColumn; jBlock < blockEndColumn; ++jBlock) {
+                final int jWidth      = blockWidth(jBlock);
+                final int firstColumn = jBlock * BLOCK_SIZE;
+                final int jStart      = FastMath.max(column,    firstColumn);
+                final int jEnd        = FastMath.min(endColumn + 1, firstColumn + jWidth);
+                final int jLength     = jEnd - jStart;
+
+                // handle one block, row by row
+                final double[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int i = iStart; i < iEnd; ++i) {
+                    System.arraycopy(subMatrix[i - row], jStart - column,
+                                     block, (i - firstRow) * jWidth + (jStart - firstColumn),
+                                     jLength);
+                }
+
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix getRowMatrix(final int row)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final BlockRealMatrix out = new BlockRealMatrix(1, columns);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outBlockIndex = 0;
+        int outIndex      = 0;
+        double[] outBlock = out.blocks[outBlockIndex];
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            final int available  = outBlock.length - outIndex;
+            if (jWidth > available) {
+                System.arraycopy(block, iRow * jWidth, outBlock, outIndex, available);
+                outBlock = out.blocks[++outBlockIndex];
+                System.arraycopy(block, iRow * jWidth, outBlock, 0, jWidth - available);
+                outIndex = jWidth - available;
+            } else {
+                System.arraycopy(block, iRow * jWidth, outBlock, outIndex, jWidth);
+                outIndex += jWidth;
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRowMatrix(final int row, final RealMatrix matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setRowMatrix(row, (BlockRealMatrix) matrix);
+        } catch (ClassCastException cce) {
+            super.setRowMatrix(row, matrix);
+        }
+    }
+
+    /**
+     * Sets the entries in row number <code>row</code>
+     * as a row matrix.  Row indices start at 0.
+     *
+     * @param row the row to be set
+     * @param matrix row matrix (must have one row and the same number of columns
+     * as the instance)
+     * @throws MatrixIndexException if the specified row index is invalid
+     * @throws InvalidMatrixException if the matrix dimensions do not match one
+     * instance row
+     */
+    public void setRowMatrix(final int row, final BlockRealMatrix matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        if ((matrix.getRowDimension() != 1) ||
+            (matrix.getColumnDimension() != nCols)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(),
+                    1, nCols);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock = row / BLOCK_SIZE;
+        final int iRow   = row - iBlock * BLOCK_SIZE;
+        int mBlockIndex  = 0;
+        int mIndex       = 0;
+        double[] mBlock  = matrix.blocks[mBlockIndex];
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            final int available  = mBlock.length - mIndex;
+            if (jWidth > available) {
+                System.arraycopy(mBlock, mIndex, block, iRow * jWidth, available);
+                mBlock = matrix.blocks[++mBlockIndex];
+                System.arraycopy(mBlock, 0, block, iRow * jWidth, jWidth - available);
+                mIndex = jWidth - available;
+            } else {
+                System.arraycopy(mBlock, mIndex, block, iRow * jWidth, jWidth);
+                mIndex += jWidth;
+           }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix getColumnMatrix(final int column)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final BlockRealMatrix out = new BlockRealMatrix(rows, 1);
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outBlockIndex = 0;
+        int outIndex      = 0;
+        double[] outBlock = out.blocks[outBlockIndex];
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                if (outIndex >= outBlock.length) {
+                    outBlock = out.blocks[++outBlockIndex];
+                    outIndex = 0;
+                }
+                outBlock[outIndex++] = block[i * jWidth + jColumn];
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setColumnMatrix(final int column, final RealMatrix matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setColumnMatrix(column, (BlockRealMatrix) matrix);
+        } catch (ClassCastException cce) {
+            super.setColumnMatrix(column, matrix);
+        }
+    }
+
+    /**
+     * Sets the entries in column number <code>column</code>
+     * as a column matrix.  Column indices start at 0.
+     *
+     * @param column the column to be set
+     * @param matrix column matrix (must have one column and the same number of rows
+     * as the instance)
+     * @throws MatrixIndexException if the specified column index is invalid
+     * @throws InvalidMatrixException if the matrix dimensions do not match one
+     * instance column
+     */
+    void setColumnMatrix(final int column, final BlockRealMatrix matrix)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        if ((matrix.getRowDimension() != nRows) ||
+            (matrix.getColumnDimension() != 1)) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    matrix.getRowDimension(), matrix.getColumnDimension(),
+                    nRows, 1);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int mBlockIndex = 0;
+        int mIndex      = 0;
+        double[] mBlock = matrix.blocks[mBlockIndex];
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                if (mIndex >= mBlock.length) {
+                    mBlock = matrix.blocks[++mBlockIndex];
+                    mIndex = 0;
+                }
+                block[i * jWidth + jColumn] = mBlock[mIndex++];
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector getRowVector(final int row)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final double[] outData = new double[columns];
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outIndex      = 0;
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            System.arraycopy(block, iRow * jWidth, outData, outIndex, jWidth);
+            outIndex += jWidth;
+        }
+
+        return new ArrayRealVector(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRowVector(final int row, final RealVector vector)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setRow(row, ((ArrayRealVector) vector).getDataRef());
+        } catch (ClassCastException cce) {
+            super.setRowVector(row, vector);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector getColumnVector(final int column)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final double[] outData = new double[rows];
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outIndex      = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                outData[outIndex++] = block[i * jWidth + jColumn];
+            }
+        }
+
+        return new ArrayRealVector(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setColumnVector(final int column, final RealVector vector)
+        throws MatrixIndexException, InvalidMatrixException {
+        try {
+            setColumn(column, ((ArrayRealVector) vector).getDataRef());
+        } catch (ClassCastException cce) {
+            super.setColumnVector(column, vector);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] getRow(final int row)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final double[] out = new double[columns];
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outIndex      = 0;
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            System.arraycopy(block, iRow * jWidth, out, outIndex, jWidth);
+            outIndex += jWidth;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setRow(final int row, final double[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkRowIndex(this, row);
+        final int nCols = getColumnDimension();
+        if (array.length != nCols) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    1, array.length, 1, nCols);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int iBlock  = row / BLOCK_SIZE;
+        final int iRow    = row - iBlock * BLOCK_SIZE;
+        int outIndex      = 0;
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth     = blockWidth(jBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            System.arraycopy(array, outIndex, block, iRow * jWidth, jWidth);
+            outIndex += jWidth;
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] getColumn(final int column)
+        throws MatrixIndexException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final double[] out = new double[rows];
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outIndex      = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                out[outIndex++] = block[i * jWidth + jColumn];
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setColumn(final int column, final double[] array)
+        throws MatrixIndexException, InvalidMatrixException {
+
+        MatrixUtils.checkColumnIndex(this, column);
+        final int nRows = getRowDimension();
+        if (array.length != nRows) {
+            throw new InvalidMatrixException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                    array.length, 1, nRows, 1);
+        }
+
+        // perform copy block-wise, to ensure good cache behavior
+        final int jBlock  = column / BLOCK_SIZE;
+        final int jColumn = column - jBlock * BLOCK_SIZE;
+        final int jWidth  = blockWidth(jBlock);
+        int outIndex      = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int iHeight = blockHeight(iBlock);
+            final double[] block = blocks[iBlock * blockColumns + jBlock];
+            for (int i = 0; i < iHeight; ++i) {
+                block[i * jWidth + jColumn] = array[outIndex++];
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getEntry(final int row, final int column)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            return blocks[iBlock * blockColumns + jBlock][k];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(final int row, final int column, final double value)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            blocks[iBlock * blockColumns + jBlock][k] = value;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(final int row, final int column, final double increment)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            blocks[iBlock * blockColumns + jBlock][k] += increment;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(final int row, final int column, final double factor)
+        throws MatrixIndexException {
+        try {
+            final int iBlock = row    / BLOCK_SIZE;
+            final int jBlock = column / BLOCK_SIZE;
+            final int k      = (row    - iBlock * BLOCK_SIZE) * blockWidth(jBlock) +
+                               (column - jBlock * BLOCK_SIZE);
+            blocks[iBlock * blockColumns + jBlock][k] *= factor;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public BlockRealMatrix transpose() {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        final BlockRealMatrix out = new BlockRealMatrix(nCols, nRows);
+
+        // perform transpose block-wise, to ensure good cache behavior
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockColumns; ++iBlock) {
+            for (int jBlock = 0; jBlock < blockRows; ++jBlock) {
+
+                // transpose current block
+                final double[] outBlock = out.blocks[blockIndex];
+                final double[] tBlock   = blocks[jBlock * blockColumns + iBlock];
+                final int      pStart   = iBlock * BLOCK_SIZE;
+                final int      pEnd     = FastMath.min(pStart + BLOCK_SIZE, columns);
+                final int      qStart   = jBlock * BLOCK_SIZE;
+                final int      qEnd     = FastMath.min(qStart + BLOCK_SIZE, rows);
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    final int lInc = pEnd - pStart;
+                    int l = p - pStart;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        outBlock[k] = tBlock[l];
+                        ++k;
+                        l+= lInc;
+                    }
+                }
+
+                // go to next block
+                ++blockIndex;
+
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return rows;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return columns;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] operate(final double[] v)
+        throws IllegalArgumentException {
+
+        if (v.length != columns) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, columns);
+        }
+        final double[] out = new double[rows];
+
+        // perform multiplication block-wise, to ensure good cache behavior
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final double[] block  = blocks[iBlock * blockColumns + jBlock];
+                final int      qStart = jBlock * BLOCK_SIZE;
+                final int      qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    double sum = 0;
+                    int q = qStart;
+                    while (q < qEnd - 3) {
+                        sum += block[k]     * v[q]     +
+                               block[k + 1] * v[q + 1] +
+                               block[k + 2] * v[q + 2] +
+                               block[k + 3] * v[q + 3];
+                        k += 4;
+                        q += 4;
+                    }
+                    while (q < qEnd) {
+                        sum += block[k++] * v[q++];
+                    }
+                    out[p] += sum;
+                }
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] preMultiply(final double[] v)
+        throws IllegalArgumentException {
+
+        if (v.length != rows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, rows);
+        }
+        final double[] out = new double[columns];
+
+        // perform multiplication block-wise, to ensure good cache behavior
+        for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+            final int jWidth  = blockWidth(jBlock);
+            final int jWidth2 = jWidth  + jWidth;
+            final int jWidth3 = jWidth2 + jWidth;
+            final int jWidth4 = jWidth3 + jWidth;
+            final int qStart = jBlock * BLOCK_SIZE;
+            final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+            for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+                final double[] block  = blocks[iBlock * blockColumns + jBlock];
+                final int      pStart = iBlock * BLOCK_SIZE;
+                final int      pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+                for (int q = qStart; q < qEnd; ++q) {
+                    int k = q - qStart;
+                    double sum = 0;
+                    int p = pStart;
+                    while (p < pEnd - 3) {
+                        sum += block[k]           * v[p]     +
+                               block[k + jWidth]  * v[p + 1] +
+                               block[k + jWidth2] * v[p + 2] +
+                               block[k + jWidth3] * v[p + 3];
+                        k += jWidth4;
+                        p += 4;
+                    }
+                    while (p < pEnd) {
+                        sum += block[k] * v[p++];
+                        k += jWidth;
+                    }
+                    out[q] += sum;
+                }
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int qStart = jBlock * BLOCK_SIZE;
+                    final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    final double[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - pStart) * jWidth;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int qStart = jBlock * BLOCK_SIZE;
+                    final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                    final double[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - pStart) * jWidth;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int q0     = jBlock * BLOCK_SIZE;
+                    final int qStart = FastMath.max(startColumn, q0);
+                    final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                    final double[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int p = pStart; p < pEnd; ++p) {
+                for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                    final int jWidth = blockWidth(jBlock);
+                    final int q0     = jBlock * BLOCK_SIZE;
+                    final int qStart = FastMath.max(startColumn, q0);
+                    final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                    final double[] block = blocks[iBlock * blockColumns + jBlock];
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+             }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final double[] block = blocks[blockIndex];
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+                ++blockIndex;
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        int blockIndex = 0;
+        for (int iBlock = 0; iBlock < blockRows; ++iBlock) {
+            final int pStart = iBlock * BLOCK_SIZE;
+            final int pEnd   = FastMath.min(pStart + BLOCK_SIZE, rows);
+            for (int jBlock = 0; jBlock < blockColumns; ++jBlock) {
+                final int qStart = jBlock * BLOCK_SIZE;
+                final int qEnd   = FastMath.min(qStart + BLOCK_SIZE, columns);
+                final double[] block = blocks[blockIndex];
+                int k = 0;
+                for (int p = pStart; p < pEnd; ++p) {
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+                ++blockIndex;
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                final int jWidth = blockWidth(jBlock);
+                final int q0     = jBlock * BLOCK_SIZE;
+                final int qStart = FastMath.max(startColumn, q0);
+                final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                final double[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int p = pStart; p < pEnd; ++p) {
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        block[k] = visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor,
+                                       final int startRow, final int endRow,
+                                       final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(rows, columns, startRow, endRow, startColumn, endColumn);
+        for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) {
+            final int p0     = iBlock * BLOCK_SIZE;
+            final int pStart = FastMath.max(startRow, p0);
+            final int pEnd   = FastMath.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow);
+            for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) {
+                final int jWidth = blockWidth(jBlock);
+                final int q0     = jBlock * BLOCK_SIZE;
+                final int qStart = FastMath.max(startColumn, q0);
+                final int qEnd   = FastMath.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn);
+                final double[] block = blocks[iBlock * blockColumns + jBlock];
+                for (int p = pStart; p < pEnd; ++p) {
+                    int k = (p - p0) * jWidth + qStart - q0;
+                    for (int q = qStart; q < qEnd; ++q) {
+                        visitor.visit(p, q, block[k]);
+                        ++k;
+                    }
+                }
+            }
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Get the height of a block.
+     * @param blockRow row index (in block sense) of the block
+     * @return height (number of rows) of the block
+     */
+    private int blockHeight(final int blockRow) {
+        return (blockRow == blockRows - 1) ? rows - blockRow * BLOCK_SIZE : BLOCK_SIZE;
+    }
+
+    /**
+     * Get the width of a block.
+     * @param blockColumn column index (in block sense) of the block
+     * @return width (number of columns) of the block
+     */
+    private int blockWidth(final int blockColumn) {
+        return (blockColumn == blockColumns - 1) ? columns - blockColumn * BLOCK_SIZE : BLOCK_SIZE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/CholeskyDecomposition.java b/src/main/java/org/apache/commons/math/linear/CholeskyDecomposition.java
new file mode 100644
index 0000000..d28523e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/CholeskyDecomposition.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+
+/**
+ * An interface to classes that implement an algorithm to calculate the
+ * Cholesky decomposition of a real symmetric positive-definite matrix.
+ * <p>This interface is based on the class with similar name from the
+ * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the
+ * following changes:</p>
+ * <ul>
+ *   <li>a {@link #getLT() getLT} method has been added,</li>
+ *   <li>the <code>isspd</code> method has been removed, the constructors of
+ *   implementation classes being expected to throw {@link
+ *   NotPositiveDefiniteMatrixException} when a matrix cannot be decomposed,</li>
+ *   <li>a {@link #getDeterminant() getDeterminant} method has been added,</li>
+ *   <li>the <code>solve</code> method has been replaced by a {@link
+ *   #getSolver() getSolver} method and the equivalent method provided by
+ *   the returned {@link DecompositionSolver}.</li>
+ * </ul>
+ *
+ * @see <a href="http://mathworld.wolfram.com/CholeskyDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Cholesky_decomposition">Wikipedia</a>
+ * @version $Revision: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $
+ * @since 2.0
+ */
+public interface CholeskyDecomposition {
+
+    /**
+     * Returns the matrix L of the decomposition.
+     * <p>L is an lower-triangular matrix</p>
+     * @return the L matrix
+     */
+    RealMatrix getL();
+
+    /**
+     * Returns the transpose of the matrix L of the decomposition.
+     * <p>L<sup>T</sup> is an upper-triangular matrix</p>
+     * @return the transpose of the matrix L of the decomposition
+     */
+    RealMatrix getLT();
+
+    /**
+     * Return the determinant of the matrix
+     * @return determinant of the matrix
+     */
+    double getDeterminant();
+
+    /**
+     * Get a solver for finding the A &times; X = B solution in least square sense.
+     * @return a solver
+     */
+    DecompositionSolver getSolver();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java b/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java
new file mode 100644
index 0000000..bde380e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/CholeskyDecompositionImpl.java
@@ -0,0 +1,356 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Calculates the Cholesky decomposition of a matrix.
+ * <p>The Cholesky decomposition of a real symmetric positive-definite
+ * matrix A consists of a lower triangular matrix L with same size that
+ * satisfy: A = LL<sup>T</sup>Q = I). In a sense, this is the square root of A.</p>
+ *
+ * @see <a href="http://mathworld.wolfram.com/CholeskyDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Cholesky_decomposition">Wikipedia</a>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class CholeskyDecompositionImpl implements CholeskyDecomposition {
+
+    /** Default threshold above which off-diagonal elements are considered too different
+     * and matrix not symmetric. */
+    public static final double DEFAULT_RELATIVE_SYMMETRY_THRESHOLD = 1.0e-15;
+
+    /** Default threshold below which diagonal elements are considered null
+     * and matrix not positive definite. */
+    public static final double DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD = 1.0e-10;
+
+    /** Row-oriented storage for L<sup>T</sup> matrix data. */
+    private double[][] lTData;
+
+    /** Cached value of L. */
+    private RealMatrix cachedL;
+
+    /** Cached value of LT. */
+    private RealMatrix cachedLT;
+
+    /**
+     * Calculates the Cholesky decomposition of the given matrix.
+     * <p>
+     * Calling this constructor is equivalent to call {@link
+     * #CholeskyDecompositionImpl(RealMatrix, double, double)} with the
+     * thresholds set to the default values {@link
+     * #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD} and {@link
+     * #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD}
+     * </p>
+     * @param matrix the matrix to decompose
+     * @exception NonSquareMatrixException if matrix is not square
+     * @exception NotSymmetricMatrixException if matrix is not symmetric
+     * @exception NotPositiveDefiniteMatrixException if the matrix is not
+     * strictly positive definite
+     * @see #CholeskyDecompositionImpl(RealMatrix, double, double)
+     * @see #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD
+     * @see #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD
+     */
+    public CholeskyDecompositionImpl(final RealMatrix matrix)
+        throws NonSquareMatrixException,
+               NotSymmetricMatrixException, NotPositiveDefiniteMatrixException {
+        this(matrix, DEFAULT_RELATIVE_SYMMETRY_THRESHOLD,
+             DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD);
+    }
+
+    /**
+     * Calculates the Cholesky decomposition of the given matrix.
+     * @param matrix the matrix to decompose
+     * @param relativeSymmetryThreshold threshold above which off-diagonal
+     * elements are considered too different and matrix not symmetric
+     * @param absolutePositivityThreshold threshold below which diagonal
+     * elements are considered null and matrix not positive definite
+     * @exception NonSquareMatrixException if matrix is not square
+     * @exception NotSymmetricMatrixException if matrix is not symmetric
+     * @exception NotPositiveDefiniteMatrixException if the matrix is not
+     * strictly positive definite
+     * @see #CholeskyDecompositionImpl(RealMatrix)
+     * @see #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD
+     * @see #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD
+     */
+    public CholeskyDecompositionImpl(final RealMatrix matrix,
+                                     final double relativeSymmetryThreshold,
+                                     final double absolutePositivityThreshold)
+        throws NonSquareMatrixException,
+               NotSymmetricMatrixException, NotPositiveDefiniteMatrixException {
+
+        if (!matrix.isSquare()) {
+            throw new NonSquareMatrixException(matrix.getRowDimension(),
+                                               matrix.getColumnDimension());
+        }
+
+        final int order = matrix.getRowDimension();
+        lTData   = matrix.getData();
+        cachedL  = null;
+        cachedLT = null;
+
+        // check the matrix before transformation
+        for (int i = 0; i < order; ++i) {
+
+            final double[] lI = lTData[i];
+
+            // check off-diagonal elements (and reset them to 0)
+            for (int j = i + 1; j < order; ++j) {
+                final double[] lJ = lTData[j];
+                final double lIJ = lI[j];
+                final double lJI = lJ[i];
+                final double maxDelta =
+                    relativeSymmetryThreshold * FastMath.max(FastMath.abs(lIJ), FastMath.abs(lJI));
+                if (FastMath.abs(lIJ - lJI) > maxDelta) {
+                    throw new NotSymmetricMatrixException();
+                }
+                lJ[i] = 0;
+           }
+        }
+
+        // transform the matrix
+        for (int i = 0; i < order; ++i) {
+
+            final double[] ltI = lTData[i];
+
+            // check diagonal element
+            if (ltI[i] < absolutePositivityThreshold) {
+                throw new NotPositiveDefiniteMatrixException();
+            }
+
+            ltI[i] = FastMath.sqrt(ltI[i]);
+            final double inverse = 1.0 / ltI[i];
+
+            for (int q = order - 1; q > i; --q) {
+                ltI[q] *= inverse;
+                final double[] ltQ = lTData[q];
+                for (int p = q; p < order; ++p) {
+                    ltQ[p] -= ltI[q] * ltI[p];
+                }
+            }
+
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getL() {
+        if (cachedL == null) {
+            cachedL = getLT().transpose();
+        }
+        return cachedL;
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getLT() {
+
+        if (cachedLT == null) {
+            cachedLT = MatrixUtils.createRealMatrix(lTData);
+        }
+
+        // return the cached matrix
+        return cachedLT;
+
+    }
+
+    /** {@inheritDoc} */
+    public double getDeterminant() {
+        double determinant = 1.0;
+        for (int i = 0; i < lTData.length; ++i) {
+            double lTii = lTData[i][i];
+            determinant *= lTii * lTii;
+        }
+        return determinant;
+    }
+
+    /** {@inheritDoc} */
+    public DecompositionSolver getSolver() {
+        return new Solver(lTData);
+    }
+
+    /** Specialized solver. */
+    private static class Solver implements DecompositionSolver {
+
+        /** Row-oriented storage for L<sup>T</sup> matrix data. */
+        private final double[][] lTData;
+
+        /**
+         * Build a solver from decomposed matrix.
+         * @param lTData row-oriented storage for L<sup>T</sup> matrix data
+         */
+        private Solver(final double[][] lTData) {
+            this.lTData = lTData;
+        }
+
+        /** {@inheritDoc} */
+        public boolean isNonSingular() {
+            // if we get this far, the matrix was positive definite, hence non-singular
+            return true;
+        }
+
+        /** {@inheritDoc} */
+        public double[] solve(double[] b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = lTData.length;
+            if (b.length != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        b.length, m);
+            }
+
+            final double[] x = b.clone();
+
+            // Solve LY = b
+            for (int j = 0; j < m; j++) {
+                final double[] lJ = lTData[j];
+                x[j] /= lJ[j];
+                final double xJ = x[j];
+                for (int i = j + 1; i < m; i++) {
+                    x[i] -= xJ * lJ[i];
+                }
+            }
+
+            // Solve LTX = Y
+            for (int j = m - 1; j >= 0; j--) {
+                x[j] /= lTData[j][j];
+                final double xJ = x[j];
+                for (int i = 0; i < j; i++) {
+                    x[i] -= xJ * lTData[i][j];
+                }
+            }
+
+            return x;
+
+        }
+
+        /** {@inheritDoc} */
+        public RealVector solve(RealVector b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            try {
+                return solve((ArrayRealVector) b);
+            } catch (ClassCastException cce) {
+
+                final int m = lTData.length;
+                if (b.getDimension() != m) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                            b.getDimension(), m);
+                }
+
+                final double[] x = b.getData();
+
+                // Solve LY = b
+                for (int j = 0; j < m; j++) {
+                    final double[] lJ = lTData[j];
+                    x[j] /= lJ[j];
+                    final double xJ = x[j];
+                    for (int i = j + 1; i < m; i++) {
+                        x[i] -= xJ * lJ[i];
+                    }
+                }
+
+                // Solve LTX = Y
+                for (int j = m - 1; j >= 0; j--) {
+                    x[j] /= lTData[j][j];
+                    final double xJ = x[j];
+                    for (int i = 0; i < j; i++) {
+                        x[i] -= xJ * lTData[i][j];
+                    }
+                }
+
+                return new ArrayRealVector(x, 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 ArrayRealVector solve(ArrayRealVector b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            return new ArrayRealVector(solve(b.getDataRef()), false);
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix solve(RealMatrix b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = lTData.length;
+            if (b.getRowDimension() != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                        b.getRowDimension(), b.getColumnDimension(), m, "n");
+            }
+
+            final int nColB = b.getColumnDimension();
+            double[][] x = b.getData();
+
+            // Solve LY = b
+            for (int j = 0; j < m; j++) {
+                final double[] lJ = lTData[j];
+                final double lJJ = lJ[j];
+                final double[] xJ = x[j];
+                for (int k = 0; k < nColB; ++k) {
+                    xJ[k] /= lJJ;
+                }
+                for (int i = j + 1; i < m; i++) {
+                    final double[] xI = x[i];
+                    final double lJI = lJ[i];
+                    for (int k = 0; k < nColB; ++k) {
+                        xI[k] -= xJ[k] * lJI;
+                    }
+                }
+            }
+
+            // Solve LTX = Y
+            for (int j = m - 1; j >= 0; j--) {
+                final double lJJ = lTData[j][j];
+                final double[] xJ = x[j];
+                for (int k = 0; k < nColB; ++k) {
+                    xJ[k] /= lJJ;
+                }
+                for (int i = 0; i < j; i++) {
+                    final double[] xI = x[i];
+                    final double lIJ = lTData[i][j];
+                    for (int k = 0; k < nColB; ++k) {
+                        xI[k] -= xJ[k] * lIJ;
+                    }
+                }
+            }
+
+            return new Array2DRowRealMatrix(x, false);
+
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix getInverse() throws InvalidMatrixException {
+            return solve(MatrixUtils.createRealIdentityMatrix(lTData.length));
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java b/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java
new file mode 100644
index 0000000..4f7cb53
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/DecompositionSolver.java
@@ -0,0 +1,84 @@
+/*
+ * 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 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>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface DecompositionSolver {
+
+    /** 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
+     */
+    double[] solve(final double[] 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
+     */
+    RealVector solve(final RealVector 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
+     */
+    RealMatrix solve(final RealMatrix 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
+     */
+    RealMatrix getInverse()
+        throws InvalidMatrixException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java b/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java
new file mode 100644
index 0000000..808b00d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Default implementation of the {@link FieldMatrixChangingVisitor} interface.
+ * <p>
+ * This class is a convenience to create custom visitors without defining all
+ * methods. This class provides default implementations that do nothing.
+ * </p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class DefaultFieldMatrixChangingVisitor<T extends FieldElement<T>>
+    implements FieldMatrixChangingVisitor<T> {
+
+    /** Zero element of the field. */
+    private final T zero;
+
+    /** Build a new instance.
+     * @param zero additive identity of the field
+     */
+    public DefaultFieldMatrixChangingVisitor(final T zero) {
+        this.zero = zero;
+    }
+
+    /** {@inheritDoc} */
+    public void start(int rows, int columns,
+                      int startRow, int endRow, int startColumn, int endColumn) {
+    }
+
+    /** {@inheritDoc} */
+    public T visit(int row, int column, T value) throws MatrixVisitorException {
+        return value;
+    }
+
+    /** {@inheritDoc} */
+    public T end() {
+        return zero;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java b/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java
new file mode 100644
index 0000000..e1fd606
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Default implementation of the {@link FieldMatrixPreservingVisitor} interface.
+ * <p>
+ * This class is a convenience to create custom visitors without defining all
+ * methods. This class provides default implementations that do nothing.
+ * </p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class DefaultFieldMatrixPreservingVisitor<T extends FieldElement<T>>
+    implements FieldMatrixPreservingVisitor<T> {
+
+    /** Zero element of the field. */
+    private final T zero;
+
+    /** Build a new instance.
+     * @param zero additive identity of the field
+     */
+    public DefaultFieldMatrixPreservingVisitor(final T zero) {
+        this.zero = zero;
+    }
+
+    /** {@inheritDoc} */
+    public void start(int rows, int columns,
+                      int startRow, int endRow, int startColumn, int endColumn) {
+    }
+
+    /** {@inheritDoc} */
+    public void visit(int row, int column, T value)
+        throws MatrixVisitorException {
+    }
+
+    /** {@inheritDoc} */
+    public T end() {
+        return zero;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.java b/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.java
new file mode 100644
index 0000000..c609d81
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Default implementation of the {@link RealMatrixChangingVisitor} interface.
+ * <p>
+ * This class is a convenience to create custom visitors without defining all
+ * methods. This class provides default implementations that do nothing.
+ * </p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class DefaultRealMatrixChangingVisitor implements RealMatrixChangingVisitor {
+
+    /** {@inheritDoc} */
+    public void start(int rows, int columns,
+                      int startRow, int endRow, int startColumn, int endColumn) {
+    }
+
+    /** {@inheritDoc} */
+    public double visit(int row, int column, double value) throws MatrixVisitorException {
+        return value;
+    }
+
+    /** {@inheritDoc} */
+    public double end() {
+        return 0;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor.java b/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor.java
new file mode 100644
index 0000000..1ab5b14
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Default implementation of the {@link RealMatrixPreservingVisitor} interface.
+ * <p>
+ * This class is a convenience to create custom visitors without defining all
+ * methods. This class provides default implementations that do nothing.
+ * </p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class DefaultRealMatrixPreservingVisitor implements RealMatrixPreservingVisitor {
+
+    /** {@inheritDoc} */
+    public void start(int rows, int columns,
+                      int startRow, int endRow, int startColumn, int endColumn) {
+    }
+
+    /** {@inheritDoc} */
+    public void visit(int row, int column, double value)
+        throws MatrixVisitorException {
+    }
+
+    /** {@inheritDoc} */
+    public double end() {
+        return 0;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/EigenDecomposition.java b/src/main/java/org/apache/commons/math/linear/EigenDecomposition.java
new file mode 100644
index 0000000..f991e8b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/EigenDecomposition.java
@@ -0,0 +1,137 @@
+/*
+ * 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;
+
+
+/**
+ * An interface to classes that implement an algorithm to calculate the
+ * eigen decomposition of a real matrix.
+ * <p>The eigen decomposition of matrix A is a set of two matrices:
+ * V and D such that A = V &times; D &times; V<sup>T</sup>.
+ * A, V and D are all m &times; m matrices.</p>
+ * <p>This interface is similar in spirit to the <code>EigenvalueDecomposition</code>
+ * class from the <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a>
+ * library, with the following changes:</p>
+ * <ul>
+ *   <li>a {@link #getVT() getVt} method has been added,</li>
+ *   <li>two {@link #getRealEigenvalue(int) getRealEigenvalue} and {@link #getImagEigenvalue(int)
+ *   getImagEigenvalue} methods to pick up a single eigenvalue have been added,</li>
+ *   <li>a {@link #getEigenvector(int) getEigenvector} method to pick up a single
+ *   eigenvector has been added,</li>
+ *   <li>a {@link #getDeterminant() getDeterminant} method has been added.</li>
+ *   <li>a {@link #getSolver() getSolver} method has been added.</li>
+ * </ul>
+ * @see <a href="http://mathworld.wolfram.com/EigenDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix">Wikipedia</a>
+ * @version $Revision: 997726 $ $Date: 2010-09-16 14:39:51 +0200 (jeu. 16 sept. 2010) $
+ * @since 2.0
+ */
+public interface EigenDecomposition {
+
+    /**
+     * Returns the matrix V of the decomposition.
+     * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * <p>The columns of V are the eigenvectors of the original matrix.</p>
+     * <p>No assumption is made about the orientation of the system axes formed
+     * by the columns of V (e.g. in a 3-dimension space, V can form a left-
+     * or right-handed system).</p>
+     * @return the V matrix
+     */
+    RealMatrix getV();
+
+    /**
+     * Returns the block diagonal matrix D of the decomposition.
+     * <p>D is a block diagonal matrix.</p>
+     * <p>Real eigenvalues are on the diagonal while complex values are on
+     * 2x2 blocks { {real +imaginary}, {-imaginary, real} }.</p>
+     * @return the D matrix
+     * @see #getRealEigenvalues()
+     * @see #getImagEigenvalues()
+     */
+    RealMatrix getD();
+
+    /**
+     * Returns the transpose of the matrix V of the decomposition.
+     * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * <p>The columns of V are the eigenvectors of the original matrix.</p>
+     * <p>No assumption is made about the orientation of the system axes formed
+     * by the columns of V (e.g. in a 3-dimension space, V can form a left-
+     * or right-handed system).</p>
+     * @return the transpose of the V matrix
+     */
+    RealMatrix getVT();
+
+    /**
+     * Returns a copy of the real parts of the eigenvalues of the original matrix.
+     * @return a copy of the real parts of the eigenvalues of the original matrix
+     * @see #getD()
+     * @see #getRealEigenvalue(int)
+     * @see #getImagEigenvalues()
+     */
+    double[] getRealEigenvalues();
+
+    /**
+     * Returns the real part of the i<sup>th</sup> eigenvalue of the original matrix.
+     * @param i index of the eigenvalue (counting from 0)
+     * @return real part of the i<sup>th</sup> eigenvalue of the original matrix
+     * @see #getD()
+     * @see #getRealEigenvalues()
+     * @see #getImagEigenvalue(int)
+     */
+    double getRealEigenvalue(int i);
+
+    /**
+     * Returns a copy of the imaginary parts of the eigenvalues of the original matrix.
+     * @return a copy of the imaginary parts of the eigenvalues of the original matrix
+     * @see #getD()
+     * @see #getImagEigenvalue(int)
+     * @see #getRealEigenvalues()
+     */
+    double[] getImagEigenvalues();
+
+    /**
+     * Returns the imaginary part of the i<sup>th</sup> eigenvalue of the original matrix.
+     * @param i index of the eigenvalue (counting from 0)
+     * @return imaginary part of the i<sup>th</sup> eigenvalue of the original matrix
+     * @see #getD()
+     * @see #getImagEigenvalues()
+     * @see #getRealEigenvalue(int)
+     */
+    double getImagEigenvalue(int i);
+
+    /**
+     * Returns a copy of the i<sup>th</sup> eigenvector of the original matrix.
+     * @param i index of the eigenvector (counting from 0)
+     * @return copy of the i<sup>th</sup> eigenvector of the original matrix
+     * @see #getD()
+     */
+    RealVector getEigenvector(int i);
+
+    /**
+     * Return the determinant of the matrix
+     * @return determinant of the matrix
+     */
+    double getDeterminant();
+
+    /**
+     * Get a solver for finding the A &times; X = B solution in exact linear sense.
+     * @return a solver
+     */
+    DecompositionSolver getSolver();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java b/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java
new file mode 100644
index 0000000..1b3085c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/EigenDecompositionImpl.java
@@ -0,0 +1,619 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Calculates the eigen decomposition of a real <strong>symmetric</strong>
+ * matrix.
+ * <p>
+ * The eigen decomposition of matrix A is a set of two matrices: V and D such
+ * that A = V D V<sup>T</sup>. A, V and D are all m &times; m matrices.
+ * </p>
+ * <p>
+ * As of 2.0, this class supports only <strong>symmetric</strong> matrices, and
+ * hence computes only real realEigenvalues. This implies the D matrix returned
+ * by {@link #getD()} is always diagonal and the imaginary values returned
+ * {@link #getImagEigenvalue(int)} and {@link #getImagEigenvalues()} are always
+ * null.
+ * </p>
+ * <p>
+ * When called with a {@link RealMatrix} argument, this implementation only uses
+ * the upper part of the matrix, the part below the diagonal is not accessed at
+ * all.
+ * </p>
+ * <p>
+ * This implementation is based on the paper by A. Drubrulle, R.S. Martin and
+ * J.H. Wilkinson 'The Implicit QL Algorithm' in Wilksinson and Reinsch (1971)
+ * Handbook for automatic computation, vol. 2, Linear algebra, Springer-Verlag,
+ * New-York
+ * </p>
+ * @version $Revision: 1002040 $ $Date: 2010-09-28 09:18:31 +0200 (mar. 28 sept. 2010) $
+ * @since 2.0
+ */
+public class EigenDecompositionImpl implements EigenDecomposition {
+
+    /** Maximum number of iterations accepted in the implicit QL transformation */
+    private byte maxIter = 30;
+
+    /** Main diagonal of the tridiagonal matrix. */
+    private double[] main;
+
+    /** Secondary diagonal of the tridiagonal matrix. */
+    private double[] secondary;
+
+    /**
+     * Transformer to tridiagonal (may be null if matrix is already
+     * tridiagonal).
+     */
+    private TriDiagonalTransformer transformer;
+
+    /** Real part of the realEigenvalues. */
+    private double[] realEigenvalues;
+
+    /** Imaginary part of the realEigenvalues. */
+    private double[] imagEigenvalues;
+
+    /** Eigenvectors. */
+    private ArrayRealVector[] eigenvectors;
+
+    /** Cached value of V. */
+    private RealMatrix cachedV;
+
+    /** Cached value of D. */
+    private RealMatrix cachedD;
+
+    /** Cached value of Vt. */
+    private RealMatrix cachedVt;
+
+    /**
+     * Calculates the eigen decomposition of the given symmetric matrix.
+     * @param matrix The <strong>symmetric</strong> matrix to decompose.
+     * @param splitTolerance dummy parameter, present for backward compatibility only.
+     * @exception InvalidMatrixException (wrapping a
+     * {@link org.apache.commons.math.ConvergenceException} if algorithm
+     * fails to converge
+     */
+    public EigenDecompositionImpl(final RealMatrix matrix,final double splitTolerance)
+            throws InvalidMatrixException {
+        if (isSymmetric(matrix)) {
+            transformToTridiagonal(matrix);
+            findEigenVectors(transformer.getQ().getData());
+        } else {
+            // as of 2.0, non-symmetric matrices (i.e. complex eigenvalues) are
+            // NOT supported
+            // see issue https://issues.apache.org/jira/browse/MATH-235
+            throw new InvalidMatrixException(
+                    LocalizedFormats.ASSYMETRIC_EIGEN_NOT_SUPPORTED);
+        }
+    }
+
+    /**
+     * Calculates the eigen decomposition of the symmetric tridiagonal
+     * matrix.  The Householder matrix is assumed to be the identity matrix.
+     * @param main Main diagonal of the symmetric triadiagonal form
+     * @param secondary Secondary of the tridiagonal form
+     * @param splitTolerance dummy parameter, present for backward compatibility only.
+     * @exception InvalidMatrixException (wrapping a
+     * {@link org.apache.commons.math.ConvergenceException} if algorithm
+     * fails to converge
+     */
+    public EigenDecompositionImpl(final double[] main,final double[] secondary,
+            final double splitTolerance)
+            throws InvalidMatrixException {
+        this.main      = main.clone();
+        this.secondary = secondary.clone();
+        transformer    = null;
+        final int size=main.length;
+        double[][] z = new double[size][size];
+        for (int i=0;i<size;i++) {
+            z[i][i]=1.0;
+        }
+        findEigenVectors(z);
+    }
+
+    /**
+     * Check if a matrix is symmetric.
+     * @param matrix
+     *            matrix to check
+     * @return true if matrix is symmetric
+     */
+    private boolean isSymmetric(final RealMatrix matrix) {
+        final int rows = matrix.getRowDimension();
+        final int columns = matrix.getColumnDimension();
+        final double eps = 10 * rows * columns * MathUtils.EPSILON;
+        for (int i = 0; i < rows; ++i) {
+            for (int j = i + 1; j < columns; ++j) {
+                final double mij = matrix.getEntry(i, j);
+                final double mji = matrix.getEntry(j, i);
+                if (FastMath.abs(mij - mji) >
+                    (FastMath.max(FastMath.abs(mij), FastMath.abs(mji)) * eps)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getV() throws InvalidMatrixException {
+
+        if (cachedV == null) {
+            final int m = eigenvectors.length;
+            cachedV = MatrixUtils.createRealMatrix(m, m);
+            for (int k = 0; k < m; ++k) {
+                cachedV.setColumnVector(k, eigenvectors[k]);
+            }
+        }
+        // return the cached matrix
+        return cachedV;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getD() throws InvalidMatrixException {
+        if (cachedD == null) {
+            // cache the matrix for subsequent calls
+            cachedD = MatrixUtils.createRealDiagonalMatrix(realEigenvalues);
+        }
+        return cachedD;
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getVT() throws InvalidMatrixException {
+
+        if (cachedVt == null) {
+            final int m = eigenvectors.length;
+            cachedVt = MatrixUtils.createRealMatrix(m, m);
+            for (int k = 0; k < m; ++k) {
+                cachedVt.setRowVector(k, eigenvectors[k]);
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedVt;
+    }
+
+    /** {@inheritDoc} */
+    public double[] getRealEigenvalues() throws InvalidMatrixException {
+        return realEigenvalues.clone();
+    }
+
+    /** {@inheritDoc} */
+    public double getRealEigenvalue(final int i) throws InvalidMatrixException,
+            ArrayIndexOutOfBoundsException {
+        return realEigenvalues[i];
+    }
+
+    /** {@inheritDoc} */
+    public double[] getImagEigenvalues() throws InvalidMatrixException {
+        return imagEigenvalues.clone();
+    }
+
+    /** {@inheritDoc} */
+    public double getImagEigenvalue(final int i) throws InvalidMatrixException,
+            ArrayIndexOutOfBoundsException {
+        return imagEigenvalues[i];
+    }
+
+    /** {@inheritDoc} */
+    public RealVector getEigenvector(final int i)
+            throws InvalidMatrixException, ArrayIndexOutOfBoundsException {
+        return eigenvectors[i].copy();
+    }
+
+    /**
+     * Return the determinant of the matrix
+     * @return determinant of the matrix
+     */
+    public double getDeterminant() {
+        double determinant = 1;
+        for (double lambda : realEigenvalues) {
+            determinant *= lambda;
+        }
+        return determinant;
+    }
+
+    /** {@inheritDoc} */
+    public DecompositionSolver getSolver() {
+        return new Solver(realEigenvalues, imagEigenvalues, eigenvectors);
+    }
+
+    /** Specialized solver. */
+    private static class Solver implements DecompositionSolver {
+
+        /** Real part of the realEigenvalues. */
+        private double[] realEigenvalues;
+
+        /** Imaginary part of the realEigenvalues. */
+        private double[] imagEigenvalues;
+
+        /** Eigenvectors. */
+        private final ArrayRealVector[] eigenvectors;
+
+        /**
+         * Build a solver from decomposed matrix.
+         * @param realEigenvalues
+         *            real parts of the eigenvalues
+         * @param imagEigenvalues
+         *            imaginary parts of the eigenvalues
+         * @param eigenvectors
+         *            eigenvectors
+         */
+        private Solver(final double[] realEigenvalues,
+                final double[] imagEigenvalues,
+                final ArrayRealVector[] eigenvectors) {
+            this.realEigenvalues = realEigenvalues;
+            this.imagEigenvalues = imagEigenvalues;
+            this.eigenvectors = eigenvectors;
+        }
+
+        /**
+         * Solve the linear equation A &times; X = B for symmetric matrices A.
+         * <p>
+         * This method only find exact linear solutions, i.e. solutions for
+         * which ||A &times; X - B|| is exactly 0.
+         * </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
+         */
+        public double[] solve(final double[] b)
+                throws IllegalArgumentException, InvalidMatrixException {
+
+            if (!isNonSingular()) {
+                throw new SingularMatrixException();
+            }
+
+            final int m = realEigenvalues.length;
+            if (b.length != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        b.length, m);
+            }
+
+            final double[] bp = new double[m];
+            for (int i = 0; i < m; ++i) {
+                final ArrayRealVector v = eigenvectors[i];
+                final double[] vData = v.getDataRef();
+                final double s = v.dotProduct(b) / realEigenvalues[i];
+                for (int j = 0; j < m; ++j) {
+                    bp[j] += s * vData[j];
+                }
+            }
+
+            return bp;
+
+        }
+
+        /**
+         * Solve the linear equation A &times; X = B for symmetric matrices A.
+         * <p>
+         * This method only find exact linear solutions, i.e. solutions for
+         * which ||A &times; X - B|| is exactly 0.
+         * </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
+         */
+        public RealVector solve(final RealVector b)
+                throws IllegalArgumentException, InvalidMatrixException {
+
+            if (!isNonSingular()) {
+                throw new SingularMatrixException();
+            }
+
+            final int m = realEigenvalues.length;
+            if (b.getDimension() != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH, b
+                                .getDimension(), m);
+            }
+
+            final double[] bp = new double[m];
+            for (int i = 0; i < m; ++i) {
+                final ArrayRealVector v = eigenvectors[i];
+                final double[] vData = v.getDataRef();
+                final double s = v.dotProduct(b) / realEigenvalues[i];
+                for (int j = 0; j < m; ++j) {
+                    bp[j] += s * vData[j];
+                }
+            }
+
+            return new ArrayRealVector(bp, false);
+
+        }
+
+        /**
+         * Solve the linear equation A &times; X = B for symmetric matrices A.
+         * <p>
+         * This method only find exact linear solutions, i.e. solutions for
+         * which ||A &times; X - B|| is exactly 0.
+         * </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
+         */
+        public RealMatrix solve(final RealMatrix b)
+                throws IllegalArgumentException, InvalidMatrixException {
+
+            if (!isNonSingular()) {
+                throw new SingularMatrixException();
+            }
+
+            final int m = realEigenvalues.length;
+            if (b.getRowDimension() != m) {
+                throw MathRuntimeException
+                        .createIllegalArgumentException(
+                                LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                                b.getRowDimension(), b.getColumnDimension(), m,
+                                "n");
+            }
+
+            final int nColB = b.getColumnDimension();
+            final double[][] bp = new double[m][nColB];
+            for (int k = 0; k < nColB; ++k) {
+                for (int i = 0; i < m; ++i) {
+                    final ArrayRealVector v = eigenvectors[i];
+                    final double[] vData = v.getDataRef();
+                    double s = 0;
+                    for (int j = 0; j < m; ++j) {
+                        s += v.getEntry(j) * b.getEntry(j, k);
+                    }
+                    s /= realEigenvalues[i];
+                    for (int j = 0; j < m; ++j) {
+                        bp[j][k] += s * vData[j];
+                    }
+                }
+            }
+
+            return MatrixUtils.createRealMatrix(bp);
+
+        }
+
+        /**
+         * Check if the decomposed matrix is non-singular.
+         * @return true if the decomposed matrix is non-singular
+         */
+        public boolean isNonSingular() {
+            for (int i = 0; i < realEigenvalues.length; ++i) {
+                if ((realEigenvalues[i] == 0) && (imagEigenvalues[i] == 0)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Get the inverse of the decomposed matrix.
+         * @return inverse matrix
+         * @throws InvalidMatrixException
+         *             if decomposed matrix is singular
+         */
+        public RealMatrix getInverse() throws InvalidMatrixException {
+
+            if (!isNonSingular()) {
+                throw new SingularMatrixException();
+            }
+
+            final int m = realEigenvalues.length;
+            final double[][] invData = new double[m][m];
+
+            for (int i = 0; i < m; ++i) {
+                final double[] invI = invData[i];
+                for (int j = 0; j < m; ++j) {
+                    double invIJ = 0;
+                    for (int k = 0; k < m; ++k) {
+                        final double[] vK = eigenvectors[k].getDataRef();
+                        invIJ += vK[i] * vK[j] / realEigenvalues[k];
+                    }
+                    invI[j] = invIJ;
+                }
+            }
+            return MatrixUtils.createRealMatrix(invData);
+
+        }
+
+    }
+
+    /**
+     * Transform matrix to tridiagonal.
+     * @param matrix
+     *            matrix to transform
+     */
+    private void transformToTridiagonal(final RealMatrix matrix) {
+
+        // transform the matrix to tridiagonal
+        transformer = new TriDiagonalTransformer(matrix);
+        main = transformer.getMainDiagonalRef();
+        secondary = transformer.getSecondaryDiagonalRef();
+
+    }
+
+    /**
+     * Find eigenvalues and eigenvectors (Dubrulle et al., 1971)
+     * @param householderMatrix Householder matrix of the transformation
+     *  to tri-diagonal form.
+     */
+    private void findEigenVectors(double[][] householderMatrix) {
+
+        double[][]z = householderMatrix.clone();
+        final int n = main.length;
+        realEigenvalues = new double[n];
+        imagEigenvalues = new double[n];
+        double[] e = new double[n];
+        for (int i = 0; i < n - 1; i++) {
+            realEigenvalues[i] = main[i];
+            e[i] = secondary[i];
+        }
+        realEigenvalues[n - 1] = main[n - 1];
+        e[n - 1] = 0.0;
+
+        // Determine the largest main and secondary value in absolute term.
+        double maxAbsoluteValue=0.0;
+        for (int i = 0; i < n; i++) {
+            if (FastMath.abs(realEigenvalues[i])>maxAbsoluteValue) {
+                maxAbsoluteValue=FastMath.abs(realEigenvalues[i]);
+            }
+            if (FastMath.abs(e[i])>maxAbsoluteValue) {
+                maxAbsoluteValue=FastMath.abs(e[i]);
+            }
+        }
+        // Make null any main and secondary value too small to be significant
+        if (maxAbsoluteValue!=0.0) {
+            for (int i=0; i < n; i++) {
+                if (FastMath.abs(realEigenvalues[i])<=MathUtils.EPSILON*maxAbsoluteValue) {
+                    realEigenvalues[i]=0.0;
+                }
+                if (FastMath.abs(e[i])<=MathUtils.EPSILON*maxAbsoluteValue) {
+                    e[i]=0.0;
+                }
+            }
+        }
+
+        for (int j = 0; j < n; j++) {
+            int its = 0;
+            int m;
+            do {
+                for (m = j; m < n - 1; m++) {
+                    double delta = FastMath.abs(realEigenvalues[m]) + FastMath.abs(realEigenvalues[m + 1]);
+                    if (FastMath.abs(e[m]) + delta == delta) {
+                        break;
+                    }
+                }
+                if (m != j) {
+                    if (its == maxIter)
+                        throw new InvalidMatrixException(
+                                new MaxIterationsExceededException(maxIter));
+                    its++;
+                    double q = (realEigenvalues[j + 1] - realEigenvalues[j]) / (2 * e[j]);
+                    double t = FastMath.sqrt(1 + q * q);
+                    if (q < 0.0) {
+                        q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q - t);
+                    } else {
+                        q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q + t);
+                    }
+                    double u = 0.0;
+                    double s = 1.0;
+                    double c = 1.0;
+                    int i;
+                    for (i = m - 1; i >= j; i--) {
+                        double p = s * e[i];
+                        double h = c * e[i];
+                        if (FastMath.abs(p) >= FastMath.abs(q)) {
+                            c = q / p;
+                            t = FastMath.sqrt(c * c + 1.0);
+                            e[i + 1] = p * t;
+                            s = 1.0 / t;
+                            c = c * s;
+                        } else {
+                            s = p / q;
+                            t = FastMath.sqrt(s * s + 1.0);
+                            e[i + 1] = q * t;
+                            c = 1.0 / t;
+                            s = s * c;
+                        }
+                        if (e[i + 1] == 0.0) {
+                            realEigenvalues[i + 1] -= u;
+                            e[m] = 0.0;
+                            break;
+                        }
+                        q = realEigenvalues[i + 1] - u;
+                        t = (realEigenvalues[i] - q) * s + 2.0 * c * h;
+                        u = s * t;
+                        realEigenvalues[i + 1] = q + u;
+                        q = c * t - h;
+                        for (int ia = 0; ia < n; ia++) {
+                            p = z[ia][i + 1];
+                            z[ia][i + 1] = s * z[ia][i] + c * p;
+                            z[ia][i] = c * z[ia][i] - s * p;
+                        }
+                    }
+                    if (t == 0.0 && i >= j)
+                        continue;
+                    realEigenvalues[j] -= u;
+                    e[j] = q;
+                    e[m] = 0.0;
+                }
+            } while (m != j);
+        }
+
+        //Sort the eigen values (and vectors) in increase order
+        for (int i = 0; i < n; i++) {
+            int k = i;
+            double p = realEigenvalues[i];
+            for (int j = i + 1; j < n; j++) {
+                if (realEigenvalues[j] > p) {
+                    k = j;
+                    p = realEigenvalues[j];
+                }
+            }
+            if (k != i) {
+                realEigenvalues[k] = realEigenvalues[i];
+                realEigenvalues[i] = p;
+                for (int j = 0; j < n; j++) {
+                    p = z[j][i];
+                    z[j][i] = z[j][k];
+                    z[j][k] = p;
+                }
+            }
+        }
+
+        // Determine the largest eigen value in absolute term.
+        maxAbsoluteValue=0.0;
+        for (int i = 0; i < n; i++) {
+            if (FastMath.abs(realEigenvalues[i])>maxAbsoluteValue) {
+                maxAbsoluteValue=FastMath.abs(realEigenvalues[i]);
+            }
+        }
+        // Make null any eigen value too small to be significant
+        if (maxAbsoluteValue!=0.0) {
+            for (int i=0; i < n; i++) {
+                if (FastMath.abs(realEigenvalues[i])<MathUtils.EPSILON*maxAbsoluteValue) {
+                    realEigenvalues[i]=0.0;
+                }
+            }
+        }
+        eigenvectors = new ArrayRealVector[n];
+        double[] tmp = new double[n];
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < n; j++) {
+                tmp[j] = z[j][i];
+            }
+            eigenvectors[i] = new ArrayRealVector(tmp);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldDecompositionSolver.java b/src/main/java/org/apache/commons/math/linear/FieldDecompositionSolver.java
new file mode 100644
index 0000000..8238cc3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldDecompositionSolver.java
@@ -0,0 +1,86 @@
+/*
+ * 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 org.apache.commons.math.FieldElement;
+
+
+/**
+ * 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: 781122 $ $Date: 2009-06-02 20:53:23 +0200 (mar. 02 juin 2009) $
+ * @since 2.0
+ */
+public interface FieldDecompositionSolver<T extends FieldElement<T>> {
+
+    /** 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;
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldLUDecomposition.java b/src/main/java/org/apache/commons/math/linear/FieldLUDecomposition.java
new file mode 100644
index 0000000..cbdbadd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldLUDecomposition.java
@@ -0,0 +1,94 @@
+/*
+ * 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 org.apache.commons.math.FieldElement;
+
+/**
+ * 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
+ * <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: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $
+ * @since 2.0
+ */
+public interface FieldLUDecomposition<T extends FieldElement<T>> {
+
+    /**
+     * 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();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldLUDecompositionImpl.java b/src/main/java/org/apache/commons/math/linear/FieldLUDecompositionImpl.java
new file mode 100644
index 0000000..44fba31
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldLUDecompositionImpl.java
@@ -0,0 +1,434 @@
+/*
+ * 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 org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * 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: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class FieldLUDecompositionImpl<T extends FieldElement<T>> implements FieldLUDecomposition<T> {
+
+    /** 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 Array2DRowFieldMatrix<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 Array2DRowFieldMatrix<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 Array2DRowFieldMatrix<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} */
+        public T[] solve(T[] b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = pivot.length;
+            if (b.length != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        b.length, m);
+            }
+            if (singular) {
+                throw new SingularMatrixException();
+            }
+
+            @SuppressWarnings("unchecked") // field is of type T
+            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} */
+        public FieldVector<T> solve(FieldVector<T> b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            try {
+                return solve((ArrayFieldVector<T>) b);
+            } catch (ClassCastException cce) {
+
+                final int m = pivot.length;
+                if (b.getDimension() != m) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                            b.getDimension(), m);
+                }
+                if (singular) {
+                    throw new SingularMatrixException();
+                }
+
+                @SuppressWarnings("unchecked") // field is of type T
+                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 ArrayFieldVector<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 ArrayFieldVector<T> solve(ArrayFieldVector<T> b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            return new ArrayFieldVector<T>(solve(b.getDataRef()), false);
+        }
+
+        /** {@inheritDoc} */
+        public FieldMatrix<T> solve(FieldMatrix<T> b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = pivot.length;
+            if (b.getRowDimension() != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                        b.getRowDimension(), b.getColumnDimension(), m, "n");
+            }
+            if (singular) {
+                throw new SingularMatrixException();
+            }
+
+            final int nColB = b.getColumnDimension();
+
+            // Apply permutations to b
+            @SuppressWarnings("unchecked") // field is of type T
+            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 Array2DRowFieldMatrix<T>(bp, false);
+
+        }
+
+        /** {@inheritDoc} */
+        public FieldMatrix<T> getInverse() throws InvalidMatrixException {
+            final int m = pivot.length;
+            final T one = field.getOne();
+            FieldMatrix<T> identity = new Array2DRowFieldMatrix<T>(field, m, m);
+            for (int i = 0; i < m; ++i) {
+                identity.setEntry(i, i, one);
+            }
+            return solve(identity);
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldMatrix.java b/src/main/java/org/apache/commons/math/linear/FieldMatrix.java
new file mode 100644
index 0000000..98d82ae
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldMatrix.java
@@ -0,0 +1,798 @@
+/*
+ * 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 org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Interface defining field-valued matrix with basic algebraic operations.
+ * <p>
+ * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</p>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ */
+public interface FieldMatrix<T extends FieldElement<T>> extends AnyMatrix {
+
+    /**
+     * Get the type of field elements of the matrix.
+     * @return type of field elements of the matrix
+     */
+    Field<T> getField();
+
+    /**
+     * Create a new FieldMatrix<T> of the same type as the instance with the supplied
+     * row and column dimensions.
+     *
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @return a new matrix of the same type as the instance
+     * @throws IllegalArgumentException if row or column dimension is not positive
+     * @since 2.0
+     */
+    FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension);
+
+    /**
+     * Returns a (deep) copy of this.
+     *
+     * @return matrix copy
+     */
+    FieldMatrix<T> copy();
+
+    /**
+     * Compute the sum of this and m.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException;
+
+    /**
+     * Compute this minus m.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    FieldMatrix<T> subtract(FieldMatrix<T> m) throws IllegalArgumentException;
+
+     /**
+     * Returns the result of adding d to each entry of this.
+     *
+     * @param d    value to be added to each entry
+     * @return     d + this
+     */
+    FieldMatrix<T> scalarAdd(T d);
+
+    /**
+     * Returns the result multiplying each entry of this by d.
+     *
+     * @param d    value to multiply all entries by
+     * @return     d * this
+     */
+    FieldMatrix<T> scalarMultiply(T d);
+
+    /**
+     * Returns the result of postmultiplying this by m.
+     *
+     * @param m    matrix to postmultiply by
+     * @return     this * m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    FieldMatrix<T> multiply(FieldMatrix<T> m) throws IllegalArgumentException;
+
+    /**
+     * Returns the result premultiplying this by <code>m</code>.
+     * @param m    matrix to premultiply by
+     * @return     m * this
+     * @throws     IllegalArgumentException
+     *             if rowDimension(this) != columnDimension(m)
+     */
+    FieldMatrix<T> preMultiply(FieldMatrix<T> m) throws IllegalArgumentException;
+
+    /**
+     * Returns matrix entries as a two-dimensional array.
+     *
+     * @return    2-dimensional array of entries
+     */
+    T[][] getData();
+
+    /**
+     * Gets a submatrix. Rows and columns are indicated
+     * counting from 0 to n-1.
+     *
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     * @return The subMatrix containing the data of the
+     *         specified rows and columns
+     * @exception MatrixIndexException  if the indices are not valid
+     */
+   FieldMatrix<T> getSubMatrix(int startRow, int endRow, int startColumn, int endColumn)
+       throws MatrixIndexException;
+
+   /**
+    * Gets a submatrix. Rows and columns are indicated
+    * counting from 0 to n-1.
+    *
+    * @param selectedRows Array of row indices.
+    * @param selectedColumns Array of column indices.
+    * @return The subMatrix containing the data in the
+    *         specified rows and columns
+    * @exception MatrixIndexException if row or column selections are not valid
+    */
+   FieldMatrix<T> getSubMatrix(int[] selectedRows, int[] selectedColumns)
+       throws MatrixIndexException;
+
+   /**
+    * Copy a submatrix. Rows and columns are indicated
+    * counting from 0 to n-1.
+    *
+    * @param startRow Initial row index
+    * @param endRow Final row index (inclusive)
+    * @param startColumn Initial column index
+    * @param endColumn Final column index (inclusive)
+    * @param destination The arrays where the submatrix data should be copied
+    * (if larger than rows/columns counts, only the upper-left part will be used)
+    * @exception MatrixIndexException if the indices are not valid
+    * @exception IllegalArgumentException if the destination array is too small
+    */
+  void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn,
+                     T[][] destination)
+      throws MatrixIndexException, IllegalArgumentException;
+
+  /**
+   * Copy a submatrix. Rows and columns are indicated
+   * counting from 0 to n-1.
+   *
+    * @param selectedRows Array of row indices.
+    * @param selectedColumns Array of column indices.
+   * @param destination The arrays where the submatrix data should be copied
+   * (if larger than rows/columns counts, only the upper-left part will be used)
+   * @exception MatrixIndexException if the indices are not valid
+   * @exception IllegalArgumentException if the destination array is too small
+   */
+  void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
+      throws MatrixIndexException, IllegalArgumentException;
+
+   /**
+    * Replace the submatrix starting at <code>row, column</code> using data in
+    * the input <code>subMatrix</code> array. Indexes are 0-based.
+    * <p>
+    * Example:<br>
+    * Starting with <pre>
+    * 1  2  3  4
+    * 5  6  7  8
+    * 9  0  1  2
+    * </pre>
+    * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
+    * <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
+    * 1  2  3  4
+    * 5  3  4  8
+    * 9  5  6  2
+    * </pre></p>
+    *
+    * @param subMatrix  array containing the submatrix replacement data
+    * @param row  row coordinate of the top, left element to be replaced
+    * @param column  column coordinate of the top, left element to be replaced
+    * @throws MatrixIndexException  if subMatrix does not fit into this
+    *    matrix from element in (row, column)
+    * @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
+    *  (not all rows have the same length) or empty
+    * @throws NullPointerException if <code>subMatrix</code> is null
+    * @since 2.0
+    */
+   void setSubMatrix(T[][] subMatrix, int row, int column)
+       throws MatrixIndexException;
+
+   /**
+    * Returns the entries in row number <code>row</code>
+    * as a row matrix.  Row indices start at 0.
+    *
+    * @param row the row to be fetched
+    * @return row matrix
+    * @throws MatrixIndexException if the specified row index is invalid
+    */
+   FieldMatrix<T> getRowMatrix(int row) throws MatrixIndexException;
+
+   /**
+    * Sets the entries in row number <code>row</code>
+    * as a row matrix.  Row indices start at 0.
+    *
+    * @param row the row to be set
+    * @param matrix row matrix (must have one row and the same number of columns
+    * as the instance)
+    * @throws MatrixIndexException if the specified row index is invalid
+    * @throws InvalidMatrixException if the matrix dimensions do not match one
+    * instance row
+    */
+   void setRowMatrix(int row, FieldMatrix<T> matrix)
+       throws MatrixIndexException, InvalidMatrixException;
+
+   /**
+    * Returns the entries in column number <code>column</code>
+    * as a column matrix.  Column indices start at 0.
+    *
+    * @param column the column to be fetched
+    * @return column matrix
+    * @throws MatrixIndexException if the specified column index is invalid
+    */
+   FieldMatrix<T> getColumnMatrix(int column) throws MatrixIndexException;
+
+   /**
+    * Sets the entries in column number <code>column</code>
+    * as a column matrix.  Column indices start at 0.
+    *
+    * @param column the column to be set
+    * @param matrix column matrix (must have one column and the same number of rows
+    * as the instance)
+    * @throws MatrixIndexException if the specified column index is invalid
+    * @throws InvalidMatrixException if the matrix dimensions do not match one
+    * instance column
+    */
+   void setColumnMatrix(int column, FieldMatrix<T> matrix)
+       throws MatrixIndexException, InvalidMatrixException;
+
+   /**
+    * Returns the entries in row number <code>row</code>
+    * 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
+    */
+   FieldVector<T> getRowVector(int row) throws MatrixIndexException;
+
+   /**
+    * Sets the entries in row number <code>row</code>
+    * as a vector.  Row indices start at 0.
+    *
+    * @param row the row to be set
+    * @param vector row vector (must have the same number of columns
+    * as the instance)
+    * @throws MatrixIndexException if the specified row index is invalid
+    * @throws InvalidMatrixException if the vector dimension does not match one
+    * instance row
+    */
+   void setRowVector(int row, FieldVector<T> vector)
+       throws MatrixIndexException, InvalidMatrixException;
+
+   /**
+    * Returns the entries in column number <code>column</code>
+    * as a 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
+    */
+   FieldVector<T> getColumnVector(int column) throws MatrixIndexException;
+
+   /**
+    * Sets the entries in column number <code>column</code>
+    * as a vector.  Column indices start at 0.
+    *
+    * @param column the column to be set
+    * @param vector column vector (must have the same number of rows as the instance)
+    * @throws MatrixIndexException if the specified column index is invalid
+    * @throws InvalidMatrixException if the vector dimension does not match one
+    * instance column
+    */
+   void setColumnVector(int column, FieldVector<T> vector)
+       throws MatrixIndexException, InvalidMatrixException;
+
+    /**
+     * Returns the entries in row number <code>row</code> as an array.
+     * <p>
+     * Row indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= row < rowDimension.</code></p>
+     *
+     * @param row the row to be fetched
+     * @return array of entries in the row
+     * @throws MatrixIndexException if the specified row index is not valid
+     */
+    T[] getRow(int row) throws MatrixIndexException;
+
+    /**
+     * Sets the entries in row number <code>row</code>
+     * as a row matrix.  Row indices start at 0.
+     *
+     * @param row the row to be set
+     * @param array row matrix (must have the same number of columns as the instance)
+     * @throws MatrixIndexException if the specified row index is invalid
+     * @throws InvalidMatrixException if the array size does not match one
+     * instance row
+     */
+    void setRow(int row, T[] array)
+        throws MatrixIndexException, InvalidMatrixException;
+
+    /**
+     * Returns the entries in column number <code>col</code> as an array.
+     * <p>
+     * Column indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= column < columnDimension.</code></p>
+     *
+     * @param column the column to be fetched
+     * @return array of entries in the column
+     * @throws MatrixIndexException if the specified column index is not valid
+     */
+    T[] getColumn(int column) throws MatrixIndexException;
+
+    /**
+     * Sets the entries in column number <code>column</code>
+     * as a column matrix.  Column indices start at 0.
+     *
+     * @param column the column to be set
+     * @param array column array (must have the same number of rows as the instance)
+     * @throws MatrixIndexException if the specified column index is invalid
+     * @throws InvalidMatrixException if the array size does not match one
+     * instance column
+     */
+    void setColumn(int column, T[] array)
+        throws MatrixIndexException, InvalidMatrixException;
+
+    /**
+     * Returns the entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be fetched
+     * @param column  column location of entry to be fetched
+     * @return matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     */
+    T getEntry(int row, int column) throws MatrixIndexException;
+
+    /**
+     * Set the entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be set
+     * @param column  column location of entry to be set
+     * @param value matrix entry to be set in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     * @since 2.0
+     */
+    void setEntry(int row, int column, T value) throws MatrixIndexException;
+
+    /**
+     * Change an entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be set
+     * @param column  column location of entry to be set
+     * @param increment value to add to the current matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     * @since 2.0
+     */
+    void addToEntry(int row, int column, T increment) throws MatrixIndexException;
+
+    /**
+     * Change an entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be set
+     * @param column  column location of entry to be set
+     * @param factor multiplication factor for the current matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     * @since 2.0
+     */
+    void multiplyEntry(int row, int column, T factor) throws MatrixIndexException;
+
+    /**
+     * Returns the transpose of this matrix.
+     *
+     * @return transpose matrix
+     */
+    FieldMatrix<T> transpose();
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
+     * trace</a> of the matrix (the sum of the elements on the main diagonal).
+     *
+     * @return trace
+     * @throws NonSquareMatrixException if the matrix is not square
+     */
+    T getTrace() throws NonSquareMatrixException;
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @param v the vector to operate on
+     * @return this*v
+     * @throws IllegalArgumentException if columnDimension != v.size()
+     */
+    T[] operate(T[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @param v the vector to operate on
+     * @return this*v
+     * @throws IllegalArgumentException if columnDimension != v.size()
+     */
+    FieldVector<T> operate(FieldVector<T> v) throws IllegalArgumentException;
+
+    /**
+     * Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
+     *
+     * @param v the row vector to premultiply by
+     * @return v*this
+     * @throws IllegalArgumentException if rowDimension != v.size()
+     */
+    T[] preMultiply(T[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
+     *
+     * @param v the row vector to premultiply by
+     * @return v*this
+     * @throws IllegalArgumentException if rowDimension != v.size()
+     */
+    FieldVector<T> preMultiply(FieldVector<T> v) throws IllegalArgumentException;
+
+    /**
+     * Visit (and possibly change) all matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) all matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) some matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor,
+                          int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) some matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor,
+                          int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) all matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) all matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) some matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor,
+                             int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) some matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor,
+                             int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) all matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) all matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) some matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor,
+                                int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) some matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
+     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor,
+                                int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldMatrixChangingVisitor.java b/src/main/java/org/apache/commons/math/linear/FieldMatrixChangingVisitor.java
new file mode 100644
index 0000000..c621975
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldMatrixChangingVisitor.java
@@ -0,0 +1,63 @@
+/*
+ * 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 org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Interface defining a visitor for matrix entries.
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface FieldMatrixChangingVisitor<T extends FieldElement<?>> {
+
+    /**
+     * Start visiting a matrix.
+     * <p>This method is called once before any entry of the matrix is visited.</p>
+     * @param rows number of rows of the matrix
+     * @param columns number of columns of the matrix
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     */
+    void start(int rows, int columns,
+               int startRow, int endRow, int startColumn, int endColumn);
+
+    /**
+     * Visit one matrix entry.
+     * @param row row index of the entry
+     * @param column column index of the entry
+     * @param value current value of the entry
+     * @return the new value to be set for the entry
+     * @throws MatrixVisitorException if something wrong occurs
+     */
+    T visit(int row, int column, T value)
+        throws MatrixVisitorException;
+
+    /**
+     * End visiting a matrix.
+     * <p>This method is called once after all entries of the matrix have been visited.</p>
+     * @return the value that the <code>walkInXxxOrder</code> must return
+     */
+    T end();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.java b/src/main/java/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.java
new file mode 100644
index 0000000..76e062e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.apache.commons.math.FieldElement;
+import org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Interface defining a visitor for matrix entries.
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface FieldMatrixPreservingVisitor<T extends FieldElement<?>> {
+
+    /**
+     * Start visiting a matrix.
+     * <p>This method is called once before any entry of the matrix is visited.</p>
+     * @param rows number of rows of the matrix
+     * @param columns number of columns of the matrix
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     */
+    void start(int rows, int columns,
+               int startRow, int endRow, int startColumn, int endColumn);
+
+    /**
+     * Visit one matrix entry.
+     * @param row row index of the entry
+     * @param column column index of the entry
+     * @param value current value of the entry
+     * @throws MatrixVisitorException if something wrong occurs
+     */
+    void visit(int row, int column, T value)
+        throws MatrixVisitorException;
+
+    /**
+     * End visiting a matrix.
+     * <p>This method is called once after all entries of the matrix have been visited.</p>
+     * @return the value that the <code>walkInXxxOrder</code> must return
+     */
+    T end();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/FieldVector.java b/src/main/java/org/apache/commons/math/linear/FieldVector.java
new file mode 100644
index 0000000..c68281b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/FieldVector.java
@@ -0,0 +1,358 @@
+/*
+ * 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 org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+
+/**
+ * Interface defining a field-valued vector with basic algebraic operations.
+ * <p>
+ * vector element indexing is 0-based -- e.g., <code>getEntry(0)</code>
+ * returns the first element of the vector.
+ * </p>
+ * <p>
+ * The various <code>mapXxx</code> and <code>mapXxxToSelf</code> 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 <code>mapXxx</code>
+ * versions create a new vector to hold the result and do not change the instance.
+ * The <code>mapXxxToSelf</code> 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 <i>fluent API</i>
+ * style, like this:
+ * </p>
+ * <pre>
+ *   RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
+ * </pre>
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public interface FieldVector<T extends FieldElement<T>>  {
+
+    /**
+     * Get the type of field elements of the vector.
+     * @return type of field elements of the vector
+     */
+    Field<T> getField();
+
+    /**
+     * Returns a (deep) copy of this.
+     * @return vector copy
+     */
+    FieldVector<T> 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
+     */
+    FieldVector<T> add(FieldVector<T> v)
+        throws IllegalArgumentException;
+
+    /**
+     * 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
+     */
+    FieldVector<T> add(T[] 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
+     */
+    FieldVector<T> subtract(FieldVector<T> 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
+     */
+    FieldVector<T> subtract(T[] v)
+        throws IllegalArgumentException;
+
+    /**
+     * Map an addition operation to each entry.
+     * @param d value to be added to each entry
+     * @return this + d
+     */
+    FieldVector<T> mapAdd(T d);
+
+    /**
+     * Map an addition operation to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @param d value to be added to each entry
+     * @return for convenience, return this
+     */
+    FieldVector<T> mapAddToSelf(T d);
+
+    /**
+     * Map a subtraction operation to each entry.
+     * @param d value to be subtracted to each entry
+     * @return this - d
+     */
+    FieldVector<T> mapSubtract(T d);
+
+    /**
+     * Map a subtraction operation to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @param d value to be subtracted to each entry
+     * @return for convenience, return this
+     */
+    FieldVector<T> mapSubtractToSelf(T d);
+
+    /**
+     * Map a multiplication operation to each entry.
+     * @param d value to multiply all entries by
+     * @return this * d
+     */
+    FieldVector<T> mapMultiply(T d);
+
+    /**
+     * Map a multiplication operation to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @param d value to multiply all entries by
+     * @return for convenience, return this
+     */
+    FieldVector<T> mapMultiplyToSelf(T d);
+
+    /**
+     * Map a division operation to each entry.
+     * @param d value to divide all entries by
+     * @return this / d
+     */
+    FieldVector<T> mapDivide(T d);
+
+    /**
+     * Map a division operation to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @param d value to divide all entries by
+     * @return for convenience, return this
+     */
+    FieldVector<T> mapDivideToSelf(T d);
+
+    /**
+     * Map the 1/x function to each entry.
+     * @return a vector containing the result of applying the function to each entry
+     */
+    FieldVector<T> mapInv();
+
+    /**
+     * Map the 1/x function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     */
+    FieldVector<T> mapInvToSelf();
+
+    /**
+     * 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
+     */
+    FieldVector<T> ebeMultiply(FieldVector<T> v) throws IllegalArgumentException;
+
+    /**
+     * 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
+     */
+    FieldVector<T> ebeMultiply(T[] 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
+     */
+    FieldVector<T> ebeDivide(FieldVector<T> 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
+     */
+    FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns vector entries as a T array.
+     * @return T array of entries
+     */
+     T[] 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
+     */
+    T dotProduct(FieldVector<T> v)
+        throws IllegalArgumentException;
+
+    /**
+     * 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
+     */
+    T dotProduct(T[] v)
+        throws IllegalArgumentException;
+
+    /** 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
+     */
+    FieldVector<T> projection(FieldVector<T> v)
+        throws IllegalArgumentException;
+
+    /** 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
+     */
+    FieldVector<T> projection(T[] 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
+     */
+    FieldMatrix<T> outerProduct(FieldVector<T> 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
+     */
+    FieldMatrix<T> outerProduct(T[] v)
+        throws IllegalArgumentException;
+
+    /**
+     * Returns the entry in the specified index.
+     * <p>
+     * The index start at 0 and must be lesser than the size,
+     * otherwise a {@link MatrixIndexException} is thrown.
+     * </p>
+     * @param index  index location of entry to be fetched
+     * @return vector entry at index
+     * @throws MatrixIndexException if the index is not valid
+     * @see #setEntry(int, FieldElement)
+     */
+    T getEntry(int index)
+        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
+     * @see #getEntry(int)
+     */
+    void setEntry(int index, T value)
+        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
+     */
+    FieldVector<T> append(FieldVector<T> v);
+
+    /**
+     * Construct a vector by appending a T to this vector.
+     * @param d T to append.
+     * @return a new vector
+     */
+    FieldVector<T> append(T d);
+
+    /**
+     * Construct a vector by appending a T array to this vector.
+     * @param a T array to append.
+     * @return a new vector
+     */
+    FieldVector<T> append(T[] 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
+     */
+    FieldVector<T> getSubVector(int index, int n)
+        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
+     * @see #setSubVector(int, FieldElement[])
+     */
+    void setSubVector(int index, FieldVector<T> v)
+        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
+     * @see #setSubVector(int, FieldVector)
+     */
+    void setSubVector(int index, T[] v)
+        throws MatrixIndexException;
+
+    /**
+     * Set all elements to a single value.
+     * @param value single value to set for all elements
+     */
+    void set(T value);
+
+    /**
+     * Convert the vector to a T array.
+     * <p>The array is independent from vector data, it's elements
+     * are copied.</p>
+     * @return array containing a copy of vector elements
+     */
+    T[] toArray();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/InvalidMatrixException.java b/src/main/java/org/apache/commons/math/linear/InvalidMatrixException.java
new file mode 100644
index 0000000..403188d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/InvalidMatrixException.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Thrown when a system attempts an operation on a matrix, and
+ * that matrix does not satisfy the preconditions for the
+ * aforementioned operation.
+ * @version $Revision: 1073253 $ $Date: 2011-02-22 09:40:05 +0100 (mar. 22 févr. 2011) $
+ */
+public class InvalidMatrixException extends MathRuntimeException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -2068020346562029801L;
+
+    /**
+     * Construct an exception with the given message.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.0
+     * @deprecated since 2.2 replaced by {@link #InvalidMatrixException(Localizable, Object...)}
+     */
+    @Deprecated
+    public InvalidMatrixException(final String pattern, final Object ... arguments) {
+        this(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Construct an exception with the given message.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public InvalidMatrixException(final Localizable pattern, final Object ... arguments) {
+        super(pattern, arguments);
+    }
+
+    /**
+     * Construct an exception with the given message.
+     * @param cause the exception or error that caused this exception
+     * to be thrown.
+     * @since 2.0
+     */
+    public InvalidMatrixException(final Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/LUDecomposition.java b/src/main/java/org/apache/commons/math/linear/LUDecomposition.java
new file mode 100644
index 0000000..41a61aa
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/LUDecomposition.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+
+/**
+ * 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
+ * <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>
+ *
+ * @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: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $
+ * @since 2.0
+ */
+public interface LUDecomposition {
+
+    /**
+     * 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)
+     */
+    RealMatrix 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)
+     */
+    RealMatrix 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()
+     */
+    RealMatrix 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
+     */
+    double getDeterminant();
+
+    /**
+     * Get a solver for finding the A &times; X = B solution in exact linear sense.
+     * @return a solver
+     */
+    DecompositionSolver getSolver();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java b/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java
new file mode 100644
index 0000000..e5c9bbf
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/LUDecompositionImpl.java
@@ -0,0 +1,423 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * 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>As shown by the presence of the P matrix, this decomposition is
+ * implemented using partial pivoting.</p>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class LUDecompositionImpl implements LUDecomposition {
+
+    /** Default bound to determine effective singularity in LU decomposition */
+    private static final double DEFAULT_TOO_SMALL = 10E-12;
+
+    /** Entries of LU decomposition. */
+    private double 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 RealMatrix cachedL;
+
+    /** Cached value of U. */
+    private RealMatrix cachedU;
+
+    /** Cached value of P. */
+    private RealMatrix cachedP;
+
+    /**
+     * Calculates the LU-decomposition of the given matrix.
+     * @param matrix The matrix to decompose.
+     * @exception InvalidMatrixException if matrix is not square
+     */
+    public LUDecompositionImpl(RealMatrix matrix)
+        throws InvalidMatrixException {
+        this(matrix, DEFAULT_TOO_SMALL);
+    }
+
+    /**
+     * Calculates the LU-decomposition of the given matrix.
+     * @param matrix The matrix to decompose.
+     * @param singularityThreshold threshold (based on partial row norm)
+     * under which a matrix is considered singular
+     * @exception NonSquareMatrixException if matrix is not square
+     */
+    public LUDecompositionImpl(RealMatrix matrix, double singularityThreshold)
+        throws NonSquareMatrixException {
+
+        if (!matrix.isSquare()) {
+            throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension());
+        }
+
+        final int m = matrix.getColumnDimension();
+        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++) {
+
+            double sum = 0;
+
+            // upper
+            for (int row = 0; row < col; row++) {
+                final double[] luRow = lu[row];
+                sum = luRow[col];
+                for (int i = 0; i < row; i++) {
+                    sum -= luRow[i] * lu[i][col];
+                }
+                luRow[col] = sum;
+            }
+
+            // lower
+            int max = col; // permutation row
+            double largest = Double.NEGATIVE_INFINITY;
+            for (int row = col; row < m; row++) {
+                final double[] luRow = lu[row];
+                sum = luRow[col];
+                for (int i = 0; i < col; i++) {
+                    sum -= luRow[i] * lu[i][col];
+                }
+                luRow[col] = sum;
+
+                // maintain best permutation choice
+                if (FastMath.abs(sum) > largest) {
+                    largest = FastMath.abs(sum);
+                    max = row;
+                }
+            }
+
+            // Singularity check
+            if (FastMath.abs(lu[max][col]) < singularityThreshold) {
+                singular = true;
+                return;
+            }
+
+            // 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 = luMax[i];
+                    luMax[i] = luCol[i];
+                    luCol[i] = tmp;
+                }
+                int temp = pivot[max];
+                pivot[max] = pivot[col];
+                pivot[col] = temp;
+                even = !even;
+            }
+
+            // Divide the lower elements by the "winning" diagonal elt.
+            final double luDiag = lu[col][col];
+            for (int row = col + 1; row < m; row++) {
+                lu[row][col] /= luDiag;
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getL() {
+        if ((cachedL == null) && !singular) {
+            final int m = pivot.length;
+            cachedL = MatrixUtils.createRealMatrix(m, m);
+            for (int i = 0; i < m; ++i) {
+                final double[] luI = lu[i];
+                for (int j = 0; j < i; ++j) {
+                    cachedL.setEntry(i, j, luI[j]);
+                }
+                cachedL.setEntry(i, i, 1.0);
+            }
+        }
+        return cachedL;
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getU() {
+        if ((cachedU == null) && !singular) {
+            final int m = pivot.length;
+            cachedU = MatrixUtils.createRealMatrix(m, m);
+            for (int i = 0; i < m; ++i) {
+                final double[] luI = lu[i];
+                for (int j = i; j < m; ++j) {
+                    cachedU.setEntry(i, j, luI[j]);
+                }
+            }
+        }
+        return cachedU;
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getP() {
+        if ((cachedP == null) && !singular) {
+            final int m = pivot.length;
+            cachedP = MatrixUtils.createRealMatrix(m, m);
+            for (int i = 0; i < m; ++i) {
+                cachedP.setEntry(i, pivot[i], 1.0);
+            }
+        }
+        return cachedP;
+    }
+
+    /** {@inheritDoc} */
+    public int[] getPivot() {
+        return pivot.clone();
+    }
+
+    /** {@inheritDoc} */
+    public double getDeterminant() {
+        if (singular) {
+            return 0;
+        } else {
+            final int m = pivot.length;
+            double determinant = even ? 1 : -1;
+            for (int i = 0; i < m; i++) {
+                determinant *= lu[i][i];
+            }
+            return determinant;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public DecompositionSolver getSolver() {
+        return new Solver(lu, pivot, singular);
+    }
+
+    /** Specialized solver. */
+    private static class Solver implements DecompositionSolver {
+
+        /** Entries of LU decomposition. */
+        private final double lu[][];
+
+        /** Pivot permutation associated with LU decomposition. */
+        private final int[] pivot;
+
+        /** Singularity indicator. */
+        private final boolean singular;
+
+        /**
+         * Build a solver from decomposed matrix.
+         * @param lu entries of LU decomposition
+         * @param pivot pivot permutation associated with LU decomposition
+         * @param singular singularity indicator
+         */
+        private Solver(final double[][] lu, final int[] pivot, final boolean singular) {
+            this.lu       = lu;
+            this.pivot    = pivot;
+            this.singular = singular;
+        }
+
+        /** {@inheritDoc} */
+        public boolean isNonSingular() {
+            return !singular;
+        }
+
+        /** {@inheritDoc} */
+        public double[] solve(double[] b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = pivot.length;
+            if (b.length != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.length, m);
+            }
+            if (singular) {
+                throw new SingularMatrixException();
+            }
+
+            final double[] bp = new double[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 double bpCol = bp[col];
+                for (int i = col + 1; i < m; i++) {
+                    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] -= bpCol * lu[i][col];
+                }
+            }
+
+            return bp;
+
+        }
+
+        /** {@inheritDoc} */
+        public RealVector solve(RealVector b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            try {
+                return solve((ArrayRealVector) b);
+            } catch (ClassCastException cce) {
+
+                final int m = pivot.length;
+                if (b.getDimension() != m) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.VECTOR_LENGTH_MISMATCH, b.getDimension(), m);
+                }
+                if (singular) {
+                    throw new SingularMatrixException();
+                }
+
+                final double[] bp = new double[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 double bpCol = bp[col];
+                    for (int i = col + 1; i < m; i++) {
+                        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] -= bpCol * lu[i][col];
+                    }
+                }
+
+                return new ArrayRealVector(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 ArrayRealVector solve(ArrayRealVector b)
+            throws IllegalArgumentException, InvalidMatrixException {
+            return new ArrayRealVector(solve(b.getDataRef()), false);
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix solve(RealMatrix b)
+            throws IllegalArgumentException, InvalidMatrixException {
+
+            final int m = pivot.length;
+            if (b.getRowDimension() != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                        b.getRowDimension(), b.getColumnDimension(), m, "n");
+            }
+            if (singular) {
+                throw new SingularMatrixException();
+            }
+
+            final int nColB = b.getColumnDimension();
+
+            // Apply permutations to b
+            final double[][] bp = new double[m][nColB];
+            for (int row = 0; row < m; row++) {
+                final double[] 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 double[] bpCol = bp[col];
+                for (int i = col + 1; i < m; i++) {
+                    final double[] bpI = bp[i];
+                    final double luICol = lu[i][col];
+                    for (int j = 0; j < nColB; j++) {
+                        bpI[j] -= bpCol[j] * luICol;
+                    }
+                }
+            }
+
+            // Solve UX = Y
+            for (int col = m - 1; col >= 0; col--) {
+                final double[] bpCol = bp[col];
+                final double luDiag = lu[col][col];
+                for (int j = 0; j < nColB; j++) {
+                    bpCol[j] /= luDiag;
+                }
+                for (int i = 0; i < col; i++) {
+                    final double[] bpI = bp[i];
+                    final double luICol = lu[i][col];
+                    for (int j = 0; j < nColB; j++) {
+                        bpI[j] -= bpCol[j] * luICol;
+                    }
+                }
+            }
+
+            return new Array2DRowRealMatrix(bp, false);
+
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix getInverse() throws InvalidMatrixException {
+            return solve(MatrixUtils.createRealIdentityMatrix(pivot.length));
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/MatrixIndexException.java b/src/main/java/org/apache/commons/math/linear/MatrixIndexException.java
new file mode 100644
index 0000000..6d1e0a3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/MatrixIndexException.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Thrown when an operation addresses a matrix coordinate (row, col)
+ * which is outside of the dimensions of a matrix.
+ * @version $Revision: 1073255 $ $Date: 2011-02-22 09:42:06 +0100 (mar. 22 févr. 2011) $
+ */
+public class MatrixIndexException extends MathRuntimeException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 8120540015829487660L;
+
+    /**
+     * Constructs a new instance with specified formatted detail message.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @deprecated as of 2.2 replaced by {@link #MatrixIndexException(Localizable, Object...)}
+     */
+    @Deprecated
+    public MatrixIndexException(final String pattern, final Object ... arguments) {
+      this(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new instance with specified formatted detail message.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MatrixIndexException(final Localizable pattern, final Object ... arguments) {
+      super(pattern, arguments);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/MatrixUtils.java b/src/main/java/org/apache/commons/math/linear/MatrixUtils.java
new file mode 100644
index 0000000..4917b89
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/MatrixUtils.java
@@ -0,0 +1,957 @@
+/*
+ * 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.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+import org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.fraction.BigFraction;
+import org.apache.commons.math.fraction.Fraction;
+
+/**
+ * A collection of static methods that operate on or return matrices.
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class MatrixUtils {
+
+    /**
+     * Private constructor.
+     */
+    private MatrixUtils() {
+        super();
+    }
+
+    /**
+     * Returns a {@link RealMatrix} with specified dimensions.
+     * <p>The type of matrix returned depends on the dimension. Below
+     * 2<sup>12</sup> elements (i.e. 4096 elements or 64&times;64 for a
+     * square matrix) which can be stored in a 32kB array, a {@link
+     * Array2DRowRealMatrix} instance is built. Above this threshold a {@link
+     * BlockRealMatrix} instance is built.</p>
+     * <p>The matrix elements are all set to 0.0.</p>
+     * @param rows number of rows of the matrix
+     * @param columns number of columns of the matrix
+     * @return  RealMatrix with specified dimensions
+     * @see #createRealMatrix(double[][])
+     */
+    public static RealMatrix createRealMatrix(final int rows, final int columns) {
+        return (rows * columns <= 4096) ?
+                new Array2DRowRealMatrix(rows, columns) : new BlockRealMatrix(rows, columns);
+    }
+
+    /**
+     * Returns a {@link FieldMatrix} with specified dimensions.
+     * <p>The type of matrix returned depends on the dimension. Below
+     * 2<sup>12</sup> elements (i.e. 4096 elements or 64&times;64 for a
+     * square matrix), a {@link FieldMatrix} instance is built. Above
+     * this threshold a {@link BlockFieldMatrix} instance is built.</p>
+     * <p>The matrix elements are all set to field.getZero().</p>
+     * @param <T> the type of the field elements
+     * @param field field to which the matrix elements belong
+     * @param rows number of rows of the matrix
+     * @param columns number of columns of the matrix
+     * @return  FieldMatrix with specified dimensions
+     * @see #createFieldMatrix(FieldElement[][])
+     * @since 2.0
+     */
+    public static <T extends FieldElement<T>> FieldMatrix<T> createFieldMatrix(final Field<T> field,
+                                                                               final int rows,
+                                                                               final int columns) {
+        return (rows * columns <= 4096) ?
+                new Array2DRowFieldMatrix<T>(field, rows, columns) : new BlockFieldMatrix<T>(field, rows, columns);
+    }
+
+    /**
+     * Returns a {@link RealMatrix} whose entries are the the values in the
+     * the input array.
+     * <p>The type of matrix returned depends on the dimension. Below
+     * 2<sup>12</sup> elements (i.e. 4096 elements or 64&times;64 for a
+     * square matrix) which can be stored in a 32kB array, a {@link
+     * Array2DRowRealMatrix} instance is built. Above this threshold a {@link
+     * BlockRealMatrix} instance is built.</p>
+     * <p>The input array is copied, not referenced.</p>
+     *
+     * @param data input array
+     * @return  RealMatrix containing the values of the array
+     * @throws IllegalArgumentException if <code>data</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if either <code>data</code> or
+     * <code>data[0]</code> is null
+     * @see #createRealMatrix(int, int)
+     */
+    public static RealMatrix createRealMatrix(double[][] data) {
+        return (data.length * data[0].length <= 4096) ?
+                new Array2DRowRealMatrix(data) : new BlockRealMatrix(data);
+    }
+
+    /**
+     * Returns a {@link FieldMatrix} whose entries are the the values in the
+     * the input array.
+     * <p>The type of matrix returned depends on the dimension. Below
+     * 2<sup>12</sup> elements (i.e. 4096 elements or 64&times;64 for a
+     * square matrix), a {@link FieldMatrix} instance is built. Above
+     * this threshold a {@link BlockFieldMatrix} instance is built.</p>
+     * <p>The input array is copied, not referenced.</p>
+     * @param <T> the type of the field elements
+     * @param data input array
+     * @return  RealMatrix containing the values of the array
+     * @throws IllegalArgumentException if <code>data</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if either <code>data</code> or
+     * <code>data[0]</code> is null
+     * @see #createFieldMatrix(Field, int, int)
+     * @since 2.0
+     */
+    public static <T extends FieldElement<T>> FieldMatrix<T> createFieldMatrix(T[][] data) {
+        return (data.length * data[0].length <= 4096) ?
+                new Array2DRowFieldMatrix<T>(data) : new BlockFieldMatrix<T>(data);
+    }
+
+    /**
+     * Returns <code>dimension x dimension</code> identity matrix.
+     *
+     * @param dimension dimension of identity matrix to generate
+     * @return identity matrix
+     * @throws IllegalArgumentException if dimension is not positive
+     * @since 1.1
+     */
+    public static RealMatrix createRealIdentityMatrix(int dimension) {
+        final RealMatrix m = createRealMatrix(dimension, dimension);
+        for (int i = 0; i < dimension; ++i) {
+            m.setEntry(i, i, 1.0);
+        }
+        return m;
+    }
+
+    /**
+     * Returns <code>dimension x dimension</code> identity matrix.
+     *
+     * @param <T> the type of the field elements
+     * @param field field to which the elements belong
+     * @param dimension dimension of identity matrix to generate
+     * @return identity matrix
+     * @throws IllegalArgumentException if dimension is not positive
+     * @since 2.0
+     */
+    public static <T extends FieldElement<T>> FieldMatrix<T>
+        createFieldIdentityMatrix(final Field<T> field, final int dimension) {
+        final T zero = field.getZero();
+        final T one  = field.getOne();
+        @SuppressWarnings("unchecked") // zero is type T
+        final T[][] d = (T[][]) Array.newInstance(zero.getClass(), new int[] { dimension, dimension });
+        for (int row = 0; row < dimension; row++) {
+            final T[] dRow = d[row];
+            Arrays.fill(dRow, zero);
+            dRow[row] = one;
+        }
+        return new Array2DRowFieldMatrix<T>(d, false);
+    }
+
+    /**
+     * Returns <code>dimension x dimension</code> identity matrix.
+     *
+     * @param dimension dimension of identity matrix to generate
+     * @return identity matrix
+     * @throws IllegalArgumentException if dimension is not positive
+     * @since 1.1
+     * @deprecated since 2.0, replaced by {@link #createFieldIdentityMatrix(Field, int)}
+     */
+    @Deprecated
+    public static BigMatrix createBigIdentityMatrix(int dimension) {
+        final BigDecimal[][] d = new BigDecimal[dimension][dimension];
+        for (int row = 0; row < dimension; row++) {
+            final BigDecimal[] dRow = d[row];
+            Arrays.fill(dRow, BigMatrixImpl.ZERO);
+            dRow[row] = BigMatrixImpl.ONE;
+        }
+        return new BigMatrixImpl(d, false);
+    }
+
+    /**
+     * Returns a diagonal matrix with specified elements.
+     *
+     * @param diagonal diagonal elements of the matrix (the array elements
+     * will be copied)
+     * @return diagonal matrix
+     * @since 2.0
+     */
+    public static RealMatrix createRealDiagonalMatrix(final double[] diagonal) {
+        final RealMatrix m = createRealMatrix(diagonal.length, diagonal.length);
+        for (int i = 0; i < diagonal.length; ++i) {
+            m.setEntry(i, i, diagonal[i]);
+        }
+        return m;
+    }
+
+    /**
+     * Returns a diagonal matrix with specified elements.
+     *
+     * @param <T> the type of the field elements
+     * @param diagonal diagonal elements of the matrix (the array elements
+     * will be copied)
+     * @return diagonal matrix
+     * @since 2.0
+     */
+    public static <T extends FieldElement<T>> FieldMatrix<T>
+        createFieldDiagonalMatrix(final T[] diagonal) {
+        final FieldMatrix<T> m =
+            createFieldMatrix(diagonal[0].getField(), diagonal.length, diagonal.length);
+        for (int i = 0; i < diagonal.length; ++i) {
+            m.setEntry(i, i, diagonal[i]);
+        }
+        return m;
+    }
+
+    /**
+     * Returns a {@link BigMatrix} whose entries are the the values in the
+     * the input array.  The input array is copied, not referenced.
+     *
+     * @param data input array
+     * @return  RealMatrix containing the values of the array
+     * @throws IllegalArgumentException if <code>data</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if data is null
+     * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])}
+     */
+    @Deprecated
+    public static BigMatrix createBigMatrix(double[][] data) {
+        return new BigMatrixImpl(data);
+    }
+
+    /**
+     * Returns a {@link BigMatrix} whose entries are the the values in the
+     * the input array.  The input array is copied, not referenced.
+     *
+     * @param data input array
+     * @return  RealMatrix containing the values of the array
+     * @throws IllegalArgumentException if <code>data</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if data is null
+     * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])}
+     */
+    @Deprecated
+    public static BigMatrix createBigMatrix(BigDecimal[][] data) {
+        return new BigMatrixImpl(data);
+    }
+
+    /**
+     * Returns a {@link BigMatrix} whose entries are the the values in the
+     * the input array.
+     * <p>If an array is built specially in order to be embedded in a
+     * BigMatrix 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 data data for new matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @return  BigMatrix containing the values of the array
+     * @throws IllegalArgumentException if <code>data</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>data</code> is null
+     * @see #createRealMatrix(double[][])
+     * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])}
+     */
+    @Deprecated
+    public static BigMatrix createBigMatrix(BigDecimal[][] data, boolean copyArray) {
+        return new BigMatrixImpl(data, copyArray);
+    }
+
+    /**
+     * Returns a {@link BigMatrix} whose entries are the the values in the
+     * the input array.  The input array is copied, not referenced.
+     *
+     * @param data input array
+     * @return  RealMatrix containing the values of the array
+     * @throws IllegalArgumentException if <code>data</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if data is null
+     * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])}
+     */
+    @Deprecated
+    public static BigMatrix createBigMatrix(String[][] data) {
+        return new BigMatrixImpl(data);
+    }
+
+    /**
+     * Creates a {@link RealVector} using the data from the input array.
+     *
+     * @param data the input data
+     * @return a data.length RealVector
+     * @throws IllegalArgumentException if <code>data</code> is empty
+     * @throws NullPointerException if <code>data</code>is null
+     */
+    public static RealVector createRealVector(double[] data) {
+        return new ArrayRealVector(data, true);
+    }
+
+    /**
+     * Creates a {@link FieldVector} using the data from the input array.
+     *
+     * @param <T> the type of the field elements
+     * @param data the input data
+     * @return a data.length FieldVector
+     * @throws IllegalArgumentException if <code>data</code> is empty
+     * @throws NullPointerException if <code>data</code>is null
+     */
+    public static <T extends FieldElement<T>> FieldVector<T> createFieldVector(final T[] data) {
+        return new ArrayFieldVector<T>(data, true);
+    }
+
+    /**
+     * Creates a row {@link RealMatrix} using the data from the input
+     * array.
+     *
+     * @param rowData the input row data
+     * @return a 1 x rowData.length RealMatrix
+     * @throws IllegalArgumentException if <code>rowData</code> is empty
+     * @throws NullPointerException if <code>rowData</code>is null
+     */
+    public static RealMatrix createRowRealMatrix(double[] rowData) {
+        final int nCols = rowData.length;
+        final RealMatrix m = createRealMatrix(1, nCols);
+        for (int i = 0; i < nCols; ++i) {
+            m.setEntry(0, i, rowData[i]);
+        }
+        return m;
+    }
+
+    /**
+     * Creates a row {@link FieldMatrix} using the data from the input
+     * array.
+     *
+     * @param <T> the type of the field elements
+     * @param rowData the input row data
+     * @return a 1 x rowData.length FieldMatrix
+     * @throws IllegalArgumentException if <code>rowData</code> is empty
+     * @throws NullPointerException if <code>rowData</code>is null
+     */
+    public static <T extends FieldElement<T>> FieldMatrix<T>
+        createRowFieldMatrix(final T[] rowData) {
+        final int nCols = rowData.length;
+        if (nCols == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+        }
+        final FieldMatrix<T> m = createFieldMatrix(rowData[0].getField(), 1, nCols);
+        for (int i = 0; i < nCols; ++i) {
+            m.setEntry(0, i, rowData[i]);
+        }
+        return m;
+    }
+
+    /**
+     * Creates a row {@link BigMatrix} using the data from the input
+     * array.
+     *
+     * @param rowData the input row data
+     * @return a 1 x rowData.length BigMatrix
+     * @throws IllegalArgumentException if <code>rowData</code> is empty
+     * @throws NullPointerException if <code>rowData</code>is null
+     * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])}
+     */
+    @Deprecated
+    public static BigMatrix createRowBigMatrix(double[] rowData) {
+        final int nCols = rowData.length;
+        final BigDecimal[][] data = new BigDecimal[1][nCols];
+        for (int i = 0; i < nCols; ++i) {
+            data[0][i] = new BigDecimal(rowData[i]);
+        }
+        return new BigMatrixImpl(data, false);
+    }
+
+    /**
+     * Creates a row {@link BigMatrix} using the data from the input
+     * array.
+     *
+     * @param rowData the input row data
+     * @return a 1 x rowData.length BigMatrix
+     * @throws IllegalArgumentException if <code>rowData</code> is empty
+     * @throws NullPointerException if <code>rowData</code>is null
+     * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])}
+     */
+    @Deprecated
+    public static BigMatrix createRowBigMatrix(BigDecimal[] rowData) {
+        final int nCols = rowData.length;
+        final BigDecimal[][] data = new BigDecimal[1][nCols];
+        System.arraycopy(rowData, 0, data[0], 0, nCols);
+        return new BigMatrixImpl(data, false);
+    }
+
+    /**
+     * Creates a row {@link BigMatrix} using the data from the input
+     * array.
+     *
+     * @param rowData the input row data
+     * @return a 1 x rowData.length BigMatrix
+     * @throws IllegalArgumentException if <code>rowData</code> is empty
+     * @throws NullPointerException if <code>rowData</code>is null
+     * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])}
+     */
+    @Deprecated
+    public static BigMatrix createRowBigMatrix(String[] rowData) {
+        final int nCols = rowData.length;
+        final BigDecimal[][] data = new BigDecimal[1][nCols];
+        for (int i = 0; i < nCols; ++i) {
+            data[0][i] = new BigDecimal(rowData[i]);
+        }
+        return new BigMatrixImpl(data, false);
+    }
+
+    /**
+     * Creates a column {@link RealMatrix} using the data from the input
+     * array.
+     *
+     * @param columnData  the input column data
+     * @return a columnData x 1 RealMatrix
+     * @throws IllegalArgumentException if <code>columnData</code> is empty
+     * @throws NullPointerException if <code>columnData</code>is null
+     */
+    public static RealMatrix createColumnRealMatrix(double[] columnData) {
+        final int nRows = columnData.length;
+        final RealMatrix m = createRealMatrix(nRows, 1);
+        for (int i = 0; i < nRows; ++i) {
+            m.setEntry(i, 0, columnData[i]);
+        }
+        return m;
+    }
+
+    /**
+     * Creates a column {@link FieldMatrix} using the data from the input
+     * array.
+     *
+     * @param <T> the type of the field elements
+     * @param columnData  the input column data
+     * @return a columnData x 1 FieldMatrix
+     * @throws IllegalArgumentException if <code>columnData</code> is empty
+     * @throws NullPointerException if <code>columnData</code>is null
+     */
+    public static <T extends FieldElement<T>> FieldMatrix<T>
+        createColumnFieldMatrix(final T[] columnData) {
+        final int nRows = columnData.length;
+        if (nRows == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+        }
+        final FieldMatrix<T> m = createFieldMatrix(columnData[0].getField(), nRows, 1);
+        for (int i = 0; i < nRows; ++i) {
+            m.setEntry(i, 0, columnData[i]);
+        }
+        return m;
+    }
+
+    /**
+     * Creates a column {@link BigMatrix} using the data from the input
+     * array.
+     *
+     * @param columnData  the input column data
+     * @return a columnData x 1 BigMatrix
+     * @throws IllegalArgumentException if <code>columnData</code> is empty
+     * @throws NullPointerException if <code>columnData</code>is null
+     * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])}
+     */
+    @Deprecated
+    public static BigMatrix createColumnBigMatrix(double[] columnData) {
+        final int nRows = columnData.length;
+        final BigDecimal[][] data = new BigDecimal[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = new BigDecimal(columnData[row]);
+        }
+        return new BigMatrixImpl(data, false);
+    }
+
+    /**
+     * Creates a column {@link BigMatrix} using the data from the input
+     * array.
+     *
+     * @param columnData  the input column data
+     * @return a columnData x 1 BigMatrix
+     * @throws IllegalArgumentException if <code>columnData</code> is empty
+     * @throws NullPointerException if <code>columnData</code>is null
+     * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])}
+     */
+    @Deprecated
+    public static BigMatrix createColumnBigMatrix(BigDecimal[] columnData) {
+        final int nRows = columnData.length;
+        final BigDecimal[][] data = new BigDecimal[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = columnData[row];
+        }
+        return new BigMatrixImpl(data, false);
+    }
+
+    /**
+     * Creates a column {@link BigMatrix} using the data from the input
+     * array.
+     *
+     * @param columnData  the input column data
+     * @return a columnData x 1 BigMatrix
+     * @throws IllegalArgumentException if <code>columnData</code> is empty
+     * @throws NullPointerException if <code>columnData</code>is null
+     * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])}
+     */
+    @Deprecated
+    public static BigMatrix createColumnBigMatrix(String[] columnData) {
+        int nRows = columnData.length;
+        final BigDecimal[][] data = new BigDecimal[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = new BigDecimal(columnData[row]);
+        }
+        return new BigMatrixImpl(data, false);
+    }
+
+    /**
+     * Check if a row index is valid.
+     * @param m matrix containing the submatrix
+     * @param row row index to check
+     * @exception MatrixIndexException if index is not valid
+     */
+    public static void checkRowIndex(final AnyMatrix m, final int row) {
+        if (row < 0 || row >= m.getRowDimension()) {
+            throw new MatrixIndexException(LocalizedFormats.ROW_INDEX_OUT_OF_RANGE,
+                                           row, 0, m.getRowDimension() - 1);
+        }
+    }
+
+    /**
+     * Check if a column index is valid.
+     * @param m matrix containing the submatrix
+     * @param column column index to check
+     * @exception MatrixIndexException if index is not valid
+     */
+    public static void checkColumnIndex(final AnyMatrix m, final int column)
+        throws MatrixIndexException {
+        if (column < 0 || column >= m.getColumnDimension()) {
+            throw new MatrixIndexException(LocalizedFormats.COLUMN_INDEX_OUT_OF_RANGE,
+                                           column, 0, m.getColumnDimension() - 1);
+        }
+    }
+
+    /**
+     * Check if submatrix ranges indices are valid.
+     * Rows and columns are indicated counting from 0 to n-1.
+     *
+     * @param m matrix containing the submatrix
+     * @param startRow Initial row index
+     * @param endRow Final row index
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception MatrixIndexException  if the indices are not valid
+     */
+    public static void checkSubMatrixIndex(final AnyMatrix m,
+                                           final int startRow, final int endRow,
+                                           final int startColumn, final int endColumn) {
+        checkRowIndex(m, startRow);
+        checkRowIndex(m, endRow);
+        if (startRow > endRow) {
+            throw new MatrixIndexException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW,
+                                           startRow, endRow);
+        }
+
+        checkColumnIndex(m, startColumn);
+        checkColumnIndex(m, endColumn);
+        if (startColumn > endColumn) {
+            throw new MatrixIndexException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN,
+                                           startColumn, endColumn);
+        }
+
+
+    }
+
+    /**
+     * Check if submatrix ranges indices are valid.
+     * Rows and columns are indicated counting from 0 to n-1.
+     *
+     * @param m matrix containing the submatrix
+     * @param selectedRows Array of row indices.
+     * @param selectedColumns Array of column indices.
+     * @exception MatrixIndexException if row or column selections are not valid
+     */
+    public static void checkSubMatrixIndex(final AnyMatrix m,
+                                           final int[] selectedRows, final int[] selectedColumns)
+        throws MatrixIndexException {
+        if (selectedRows.length * selectedColumns.length == 0) {
+            if (selectedRows.length == 0) {
+                throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY);
+            }
+            throw new MatrixIndexException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY);
+        }
+
+        for (final int row : selectedRows) {
+            checkRowIndex(m, row);
+        }
+        for (final int column : selectedColumns) {
+            checkColumnIndex(m, column);
+        }
+    }
+
+    /**
+     * Check if matrices are addition compatible
+     * @param left left hand side matrix
+     * @param right right hand side matrix
+     * @exception IllegalArgumentException if matrices are not addition compatible
+     */
+    public static void checkAdditionCompatible(final AnyMatrix left, final AnyMatrix right)
+        throws IllegalArgumentException {
+        if ((left.getRowDimension()    != right.getRowDimension()) ||
+            (left.getColumnDimension() != right.getColumnDimension())) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_ADDITION_COMPATIBLE_MATRICES,
+                    left.getRowDimension(), left.getColumnDimension(),
+                    right.getRowDimension(), right.getColumnDimension());
+        }
+    }
+
+    /**
+     * Check if matrices are subtraction compatible
+     * @param left left hand side matrix
+     * @param right right hand side matrix
+     * @exception IllegalArgumentException if matrices are not subtraction compatible
+     */
+    public static void checkSubtractionCompatible(final AnyMatrix left, final AnyMatrix right)
+        throws IllegalArgumentException {
+        if ((left.getRowDimension()    != right.getRowDimension()) ||
+            (left.getColumnDimension() != right.getColumnDimension())) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_SUBTRACTION_COMPATIBLE_MATRICES,
+                    left.getRowDimension(), left.getColumnDimension(),
+                    right.getRowDimension(), right.getColumnDimension());
+        }
+    }
+
+    /**
+     * Check if matrices are multiplication compatible
+     * @param left left hand side matrix
+     * @param right right hand side matrix
+     * @exception IllegalArgumentException if matrices are not multiplication compatible
+     */
+    public static void checkMultiplicationCompatible(final AnyMatrix left, final AnyMatrix right)
+        throws IllegalArgumentException {
+        if (left.getColumnDimension() != right.getRowDimension()) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_MULTIPLICATION_COMPATIBLE_MATRICES,
+                    left.getRowDimension(), left.getColumnDimension(),
+                    right.getRowDimension(), right.getColumnDimension());
+        }
+    }
+
+    /**
+     * Convert a {@link FieldMatrix}/{@link Fraction} matrix to a {@link RealMatrix}.
+     * @param m matrix to convert
+     * @return converted matrix
+     */
+    public static Array2DRowRealMatrix fractionMatrixToRealMatrix(final FieldMatrix<Fraction> m) {
+        final FractionMatrixConverter converter = new FractionMatrixConverter();
+        m.walkInOptimizedOrder(converter);
+        return converter.getConvertedMatrix();
+    }
+
+    /** Converter for {@link FieldMatrix}/{@link Fraction}. */
+    private static class FractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor<Fraction> {
+
+        /** Converted array. */
+        private double[][] data;
+
+        /** Simple constructor. */
+        public FractionMatrixConverter() {
+            super(Fraction.ZERO);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void start(int rows, int columns,
+                          int startRow, int endRow, int startColumn, int endColumn) {
+            data = new double[rows][columns];
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void visit(int row, int column, Fraction value) {
+            data[row][column] = value.doubleValue();
+        }
+
+        /** Get the converted matrix.
+         * @return converted matrix
+         */
+        Array2DRowRealMatrix getConvertedMatrix() {
+            return new Array2DRowRealMatrix(data, false);
+        }
+
+    }
+
+    /**
+     * Convert a {@link FieldMatrix}/{@link BigFraction} matrix to a {@link RealMatrix}.
+     * @param m matrix to convert
+     * @return converted matrix
+     */
+    public static Array2DRowRealMatrix bigFractionMatrixToRealMatrix(final FieldMatrix<BigFraction> m) {
+        final BigFractionMatrixConverter converter = new BigFractionMatrixConverter();
+        m.walkInOptimizedOrder(converter);
+        return converter.getConvertedMatrix();
+    }
+
+    /** Converter for {@link FieldMatrix}/{@link BigFraction}. */
+    private static class BigFractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor<BigFraction> {
+
+        /** Converted array. */
+        private double[][] data;
+
+        /** Simple constructor. */
+        public BigFractionMatrixConverter() {
+            super(BigFraction.ZERO);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void start(int rows, int columns,
+                          int startRow, int endRow, int startColumn, int endColumn) {
+            data = new double[rows][columns];
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void visit(int row, int column, BigFraction value) {
+            data[row][column] = value.doubleValue();
+        }
+
+        /** Get the converted matrix.
+         * @return converted matrix
+         */
+        Array2DRowRealMatrix getConvertedMatrix() {
+            return new Array2DRowRealMatrix(data, false);
+        }
+
+    }
+
+    /** Serialize a {@link RealVector}.
+     * <p>
+     * This method is intended to be called from within a private
+     * <code>writeObject</code> method (after a call to
+     * <code>oos.defaultWriteObject()</code>) in a class that has a
+     * {@link RealVector} field, which should be declared <code>transient</code>.
+     * This way, the default handling does not serialize the vector (the {@link
+     * RealVector} interface is not serializable by default) but this method does
+     * serialize it specifically.
+     * </p>
+     * <p>
+     * The following example shows how a simple class with a name and a real vector
+     * should be written:
+     * <pre><code>
+     * public class NamedVector implements Serializable {
+     *
+     *     private final String name;
+     *     private final transient RealVector coefficients;
+     *
+     *     // omitted constructors, getters ...
+     *
+     *     private void writeObject(ObjectOutputStream oos) throws IOException {
+     *         oos.defaultWriteObject();  // takes care of name field
+     *         MatrixUtils.serializeRealVector(coefficients, oos);
+     *     }
+     *
+     *     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
+     *         ois.defaultReadObject();  // takes care of name field
+     *         MatrixUtils.deserializeRealVector(this, "coefficients", ois);
+     *     }
+     *
+     * }
+     * </code></pre>
+     * </p>
+     *
+     * @param vector real vector to serialize
+     * @param oos stream where the real vector should be written
+     * @exception IOException if object cannot be written to stream
+     * @see #deserializeRealVector(Object, String, ObjectInputStream)
+     */
+    public static void serializeRealVector(final RealVector vector,
+                                           final ObjectOutputStream oos)
+        throws IOException {
+        final int n = vector.getDimension();
+        oos.writeInt(n);
+        for (int i = 0; i < n; ++i) {
+            oos.writeDouble(vector.getEntry(i));
+        }
+    }
+
+    /** Deserialize  a {@link RealVector} field in a class.
+     * <p>
+     * This method is intended to be called from within a private
+     * <code>readObject</code> method (after a call to
+     * <code>ois.defaultReadObject()</code>) in a class that has a
+     * {@link RealVector} field, which should be declared <code>transient</code>.
+     * This way, the default handling does not deserialize the vector (the {@link
+     * RealVector} interface is not serializable by default) but this method does
+     * deserialize it specifically.
+     * </p>
+     * @param instance instance in which the field must be set up
+     * @param fieldName name of the field within the class (may be private and final)
+     * @param ois stream from which the real vector should be read
+     * @exception ClassNotFoundException if a class in the stream cannot be found
+     * @exception IOException if object cannot be read from the stream
+     * @see #serializeRealVector(RealVector, ObjectOutputStream)
+     */
+    public static void deserializeRealVector(final Object instance,
+                                             final String fieldName,
+                                             final ObjectInputStream ois)
+      throws ClassNotFoundException, IOException {
+        try {
+
+            // read the vector data
+            final int n = ois.readInt();
+            final double[] data = new double[n];
+            for (int i = 0; i < n; ++i) {
+                data[i] = ois.readDouble();
+            }
+
+            // create the instance
+            final RealVector vector = new ArrayRealVector(data, false);
+
+            // set up the field
+            final java.lang.reflect.Field f =
+                instance.getClass().getDeclaredField(fieldName);
+            f.setAccessible(true);
+            f.set(instance, vector);
+
+        } catch (NoSuchFieldException nsfe) {
+            IOException ioe = new IOException();
+            ioe.initCause(nsfe);
+            throw ioe;
+        } catch (IllegalAccessException iae) {
+            IOException ioe = new IOException();
+            ioe.initCause(iae);
+            throw ioe;
+        }
+
+    }
+
+    /** Serialize a {@link RealMatrix}.
+     * <p>
+     * This method is intended to be called from within a private
+     * <code>writeObject</code> method (after a call to
+     * <code>oos.defaultWriteObject()</code>) in a class that has a
+     * {@link RealMatrix} field, which should be declared <code>transient</code>.
+     * This way, the default handling does not serialize the matrix (the {@link
+     * RealMatrix} interface is not serializable by default) but this method does
+     * serialize it specifically.
+     * </p>
+     * <p>
+     * The following example shows how a simple class with a name and a real matrix
+     * should be written:
+     * <pre><code>
+     * public class NamedMatrix implements Serializable {
+     *
+     *     private final String name;
+     *     private final transient RealMatrix coefficients;
+     *
+     *     // omitted constructors, getters ...
+     *
+     *     private void writeObject(ObjectOutputStream oos) throws IOException {
+     *         oos.defaultWriteObject();  // takes care of name field
+     *         MatrixUtils.serializeRealMatrix(coefficients, oos);
+     *     }
+     *
+     *     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
+     *         ois.defaultReadObject();  // takes care of name field
+     *         MatrixUtils.deserializeRealMatrix(this, "coefficients", ois);
+     *     }
+     *
+     * }
+     * </code></pre>
+     * </p>
+     *
+     * @param matrix real matrix to serialize
+     * @param oos stream where the real matrix should be written
+     * @exception IOException if object cannot be written to stream
+     * @see #deserializeRealMatrix(Object, String, ObjectInputStream)
+     */
+    public static void serializeRealMatrix(final RealMatrix matrix,
+                                           final ObjectOutputStream oos)
+        throws IOException {
+        final int n = matrix.getRowDimension();
+        final int m = matrix.getColumnDimension();
+        oos.writeInt(n);
+        oos.writeInt(m);
+        for (int i = 0; i < n; ++i) {
+            for (int j = 0; j < m; ++j) {
+                oos.writeDouble(matrix.getEntry(i, j));
+            }
+        }
+    }
+
+    /** Deserialize  a {@link RealMatrix} field in a class.
+     * <p>
+     * This method is intended to be called from within a private
+     * <code>readObject</code> method (after a call to
+     * <code>ois.defaultReadObject()</code>) in a class that has a
+     * {@link RealMatrix} field, which should be declared <code>transient</code>.
+     * This way, the default handling does not deserialize the matrix (the {@link
+     * RealMatrix} interface is not serializable by default) but this method does
+     * deserialize it specifically.
+     * </p>
+     * @param instance instance in which the field must be set up
+     * @param fieldName name of the field within the class (may be private and final)
+     * @param ois stream from which the real matrix should be read
+     * @exception ClassNotFoundException if a class in the stream cannot be found
+     * @exception IOException if object cannot be read from the stream
+     * @see #serializeRealMatrix(RealMatrix, ObjectOutputStream)
+     */
+    public static void deserializeRealMatrix(final Object instance,
+                                             final String fieldName,
+                                             final ObjectInputStream ois)
+      throws ClassNotFoundException, IOException {
+        try {
+
+            // read the matrix data
+            final int n = ois.readInt();
+            final int m = ois.readInt();
+            final double[][] data = new double[n][m];
+            for (int i = 0; i < n; ++i) {
+                final double[] dataI = data[i];
+                for (int j = 0; j < m; ++j) {
+                    dataI[j] = ois.readDouble();
+                }
+            }
+
+            // create the instance
+            final RealMatrix matrix = new Array2DRowRealMatrix(data, false);
+
+            // set up the field
+            final java.lang.reflect.Field f =
+                instance.getClass().getDeclaredField(fieldName);
+            f.setAccessible(true);
+            f.set(instance, matrix);
+
+        } catch (NoSuchFieldException nsfe) {
+            IOException ioe = new IOException();
+            ioe.initCause(nsfe);
+            throw ioe;
+        } catch (IllegalAccessException iae) {
+            IOException ioe = new IOException();
+            ioe.initCause(iae);
+            throw ioe;
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/MatrixVisitorException.java b/src/main/java/org/apache/commons/math/linear/MatrixVisitorException.java
new file mode 100644
index 0000000..de25f16
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/MatrixVisitorException.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * Thrown when a visitor encounters an error while processing a matrix entry.
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ */
+public class MatrixVisitorException extends MathRuntimeException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 3814333035048617048L;
+
+    /**
+     * Constructs a new instance with specified formatted detail message.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     */
+    public MatrixVisitorException(final String pattern, final Object[] arguments) {
+      super(new DummyLocalizable(pattern), arguments);
+    }
+
+    /**
+     * Constructs a new instance with specified formatted detail message.
+     * @param pattern format specifier
+     * @param arguments format arguments
+     * @since 2.2
+     */
+    public MatrixVisitorException(final Localizable pattern, final Object[] arguments) {
+      super(pattern, arguments);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/NonSquareMatrixException.java b/src/main/java/org/apache/commons/math/linear/NonSquareMatrixException.java
new file mode 100644
index 0000000..291c0e5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/NonSquareMatrixException.java
@@ -0,0 +1,42 @@
+/*
+ * 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 org.apache.commons.math.exception.util.LocalizedFormats;
+
+
+/**
+ * Thrown when an operation defined only for square matrices is applied to non-square ones.
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class NonSquareMatrixException extends InvalidMatrixException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 8996207526636673730L;
+
+    /**
+     * Construct an exception with the given message.
+     * @param rows number of rows of the faulty matrix
+     * @param columns number of columns of the faulty matrix
+     */
+    public NonSquareMatrixException(final int rows, final int columns) {
+        super(LocalizedFormats.NON_SQUARE_MATRIX, rows, columns);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException.java b/src/main/java/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException.java
new file mode 100644
index 0000000..f7ede55
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException.java
@@ -0,0 +1,43 @@
+/*
+ * 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 org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * This class represents exceptions thrown when a matrix expected to
+ * be positive definite is not.
+ *
+ * @since 1.2
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+
+public class NotPositiveDefiniteMatrixException extends MathException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4122929125438624648L;
+
+    /** Simple constructor.
+     * build an exception with a default message.
+     */
+    public NotPositiveDefiniteMatrixException() {
+        super(LocalizedFormats.NOT_POSITIVE_DEFINITE_MATRIX);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/NotSymmetricMatrixException.java b/src/main/java/org/apache/commons/math/linear/NotSymmetricMatrixException.java
new file mode 100644
index 0000000..e422079
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/NotSymmetricMatrixException.java
@@ -0,0 +1,43 @@
+/*
+ * 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 org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * This class represents exceptions thrown when a matrix expected to
+ * be symmetric is not
+ *
+ * @since 2.0
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+
+public class NotSymmetricMatrixException extends MathException {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -7012803946709786097L;
+
+    /** Simple constructor.
+     * build an exception with a default message.
+     */
+    public NotSymmetricMatrixException() {
+        super(LocalizedFormats.NOT_SYMMETRIC_MATRIX);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/OpenMapRealMatrix.java b/src/main/java/org/apache/commons/math/linear/OpenMapRealMatrix.java
new file mode 100644
index 0000000..e651320
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/OpenMapRealMatrix.java
@@ -0,0 +1,292 @@
+/*
+ * 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 org.apache.commons.math.util.OpenIntToDoubleHashMap;
+
+/**
+ * Sparse matrix implementation based on an open addressed map.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public class OpenMapRealMatrix extends AbstractRealMatrix implements SparseRealMatrix, Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -5962461716457143437L;
+
+    /** Number of rows of the matrix. */
+    private final int rows;
+
+    /** Number of columns of the matrix. */
+    private final int columns;
+
+    /** Storage for (sparse) matrix elements. */
+    private final OpenIntToDoubleHashMap entries;
+
+    /**
+     * Build a sparse matrix with the supplied row and column dimensions.
+     * @param rowDimension number of rows of the matrix
+     * @param columnDimension number of columns of the matrix
+     */
+    public OpenMapRealMatrix(int rowDimension, int columnDimension) {
+        super(rowDimension, columnDimension);
+        this.rows    = rowDimension;
+        this.columns = columnDimension;
+        this.entries = new OpenIntToDoubleHashMap(0.0);
+    }
+
+    /**
+     * Build a matrix by copying another one.
+     * @param matrix matrix to copy
+     */
+    public OpenMapRealMatrix(OpenMapRealMatrix matrix) {
+        this.rows    = matrix.rows;
+        this.columns = matrix.columns;
+        this.entries = new OpenIntToDoubleHashMap(matrix.entries);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealMatrix copy() {
+        return new OpenMapRealMatrix(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealMatrix createMatrix(int rowDimension, int columnDimension)
+            throws IllegalArgumentException {
+        return new OpenMapRealMatrix(rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return columns;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealMatrix add(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return add((OpenMapRealMatrix) m);
+        } catch (ClassCastException cce) {
+            return (OpenMapRealMatrix) super.add(m);
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public OpenMapRealMatrix add(OpenMapRealMatrix m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final OpenMapRealMatrix out = new OpenMapRealMatrix(this);
+        for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) {
+            iterator.advance();
+            final int row = iterator.key() / columns;
+            final int col = iterator.key() - row * columns;
+            out.setEntry(row, col, getEntry(row, col) + iterator.value());
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealMatrix subtract(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return subtract((OpenMapRealMatrix) m);
+        } catch (ClassCastException cce) {
+            return (OpenMapRealMatrix) super.subtract(m);
+        }
+    }
+
+    /**
+     * Compute this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this - m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public OpenMapRealMatrix subtract(OpenMapRealMatrix m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final OpenMapRealMatrix out = new OpenMapRealMatrix(this);
+        for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) {
+            iterator.advance();
+            final int row = iterator.key() / columns;
+            final int col = iterator.key() - row * columns;
+            out.setEntry(row, col, getEntry(row, col) - iterator.value());
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix multiply(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return multiply((OpenMapRealMatrix) m);
+        } catch (ClassCastException cce) {
+
+            // safety check
+            MatrixUtils.checkMultiplicationCompatible(this, m);
+
+            final int outCols = m.getColumnDimension();
+            final BlockRealMatrix out = new BlockRealMatrix(rows, outCols);
+            for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) {
+                iterator.advance();
+                final double value = iterator.value();
+                final int key      = iterator.key();
+                final int i        = key / columns;
+                final int k        = key % columns;
+                for (int j = 0; j < outCols; ++j) {
+                    out.addToEntry(i, j, value * m.getEntry(k, j));
+                }
+            }
+
+            return out;
+
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by m.
+     *
+     * @param m    matrix to postmultiply by
+     * @return     this * m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public OpenMapRealMatrix multiply(OpenMapRealMatrix m) throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkMultiplicationCompatible(this, m);
+
+        final int outCols = m.getColumnDimension();
+        OpenMapRealMatrix out = new OpenMapRealMatrix(rows, outCols);
+        for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) {
+            iterator.advance();
+            final double value = iterator.value();
+            final int key      = iterator.key();
+            final int i        = key / columns;
+            final int k        = key % columns;
+            for (int j = 0; j < outCols; ++j) {
+                final int rightKey = m.computeKey(k, j);
+                if (m.entries.containsKey(rightKey)) {
+                    final int outKey = out.computeKey(i, j);
+                    final double outValue =
+                        out.entries.get(outKey) + value * m.entries.get(rightKey);
+                    if (outValue == 0.0) {
+                        out.entries.remove(outKey);
+                    } else {
+                        out.entries.put(outKey, outValue);
+                    }
+                }
+            }
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getEntry(int row, int column) throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        MatrixUtils.checkColumnIndex(this, column);
+        return entries.get(computeKey(row, column));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return rows;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(int row, int column, double value)
+            throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        MatrixUtils.checkColumnIndex(this, column);
+        if (value == 0.0) {
+            entries.remove(computeKey(row, column));
+        } else {
+            entries.put(computeKey(row, column), value);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(int row, int column, double increment)
+            throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        MatrixUtils.checkColumnIndex(this, column);
+        final int key = computeKey(row, column);
+        final double value = entries.get(key) + increment;
+        if (value == 0.0) {
+            entries.remove(key);
+        } else {
+            entries.put(key, value);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(int row, int column, double factor)
+            throws MatrixIndexException {
+        MatrixUtils.checkRowIndex(this, row);
+        MatrixUtils.checkColumnIndex(this, column);
+        final int key = computeKey(row, column);
+        final double value = entries.get(key) * factor;
+        if (value == 0.0) {
+            entries.remove(key);
+        } else {
+            entries.put(key, value);
+        }
+    }
+
+    /**
+     * Compute the key to access a matrix element
+     * @param row row index of the matrix element
+     * @param column column index of the matrix element
+     * @return key within the map to access the matrix element
+     */
+    private int computeKey(int row, int column) {
+        return row * columns + column;
+    }
+
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java b/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java
new file mode 100644
index 0000000..b1d1912
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/OpenMapRealVector.java
@@ -0,0 +1,915 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.OpenIntToDoubleHashMap;
+import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store.
+ * @version $Revision: 1073262 $ $Date: 2011-02-22 10:02:25 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+*/
+public class OpenMapRealVector extends AbstractRealVector implements SparseRealVector, Serializable {
+
+    /** Default Tolerance for having a value considered zero. */
+    public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12;
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 8772222695580707260L;
+
+    /** Entries of the vector. */
+    private final OpenIntToDoubleHashMap entries;
+
+    /** Dimension of the vector. */
+    private final int virtualSize;
+
+    /** Tolerance for having a value considered zero. */
+    private final double epsilon;
+
+    /**
+     * 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
+     * #OpenMapRealVector(OpenMapRealVector, int)} constructor
+     * or one of the <code>append</code> method ({@link #append(double)}, {@link
+     * #append(double[])}, {@link #append(RealVector)}) to gather data
+     * into this vector.</p>
+     */
+    public OpenMapRealVector() {
+        this(0, DEFAULT_ZERO_TOLERANCE);
+    }
+
+    /**
+     * Construct a (dimension)-length vector of zeros.
+     * @param dimension size of the vector
+     */
+    public OpenMapRealVector(int dimension) {
+        this(dimension, DEFAULT_ZERO_TOLERANCE);
+    }
+
+    /**
+     * Construct a (dimension)-length vector of zeros, specifying zero tolerance.
+     * @param dimension Size of the vector
+     * @param epsilon The tolerance for having a value considered zero
+     */
+    public OpenMapRealVector(int dimension, double epsilon) {
+        virtualSize = dimension;
+        entries = new OpenIntToDoubleHashMap(0.0);
+        this.epsilon = epsilon;
+    }
+
+    /**
+     * Build a resized vector, for use with append.
+     * @param v The original vector
+     * @param resize The amount to resize it
+     */
+    protected OpenMapRealVector(OpenMapRealVector v, int resize) {
+        virtualSize = v.getDimension() + resize;
+        entries = new OpenIntToDoubleHashMap(v.entries);
+        epsilon = v.epsilon;
+    }
+
+    /**
+     * Build a vector with known the sparseness (for advanced use only).
+     * @param dimension The size of the vector
+     * @param expectedSize The expected number of non-zero entries
+     */
+    public OpenMapRealVector(int dimension, int expectedSize) {
+        this(dimension, expectedSize, DEFAULT_ZERO_TOLERANCE);
+    }
+
+    /**
+     * Build a vector with known the sparseness and zero tolerance setting (for advanced use only).
+     * @param dimension The size of the vector
+     * @param expectedSize The expected number of non-zero entries
+     * @param epsilon The tolerance for having a value considered zero
+     */
+    public OpenMapRealVector(int dimension, int expectedSize, double epsilon) {
+        virtualSize = dimension;
+        entries = new OpenIntToDoubleHashMap(expectedSize, 0.0);
+        this.epsilon = epsilon;
+    }
+
+    /**
+     * Create from a double array.
+     * Only non-zero entries will be stored
+     * @param values The set of values to create from
+     */
+    public OpenMapRealVector(double[] values) {
+        this(values, DEFAULT_ZERO_TOLERANCE);
+    }
+
+    /**
+     * Create from a double array, specifying zero tolerance.
+     * Only non-zero entries will be stored
+     * @param values The set of values to create from
+     * @param epsilon The tolerance for having a value considered zero
+     */
+    public OpenMapRealVector(double[] values, double epsilon) {
+        virtualSize = values.length;
+        entries = new OpenIntToDoubleHashMap(0.0);
+        this.epsilon = epsilon;
+        for (int key = 0; key < values.length; key++) {
+            double value = values[key];
+            if (!isDefaultValue(value)) {
+                entries.put(key, value);
+            }
+        }
+    }
+
+    /**
+     * Create from a Double array.
+     * Only non-zero entries will be stored
+     * @param values The set of values to create from
+     */
+    public OpenMapRealVector(Double[] values) {
+        this(values, DEFAULT_ZERO_TOLERANCE);
+    }
+
+    /**
+     * Create from a Double array.
+     * Only non-zero entries will be stored
+     * @param values The set of values to create from
+     * @param epsilon The tolerance for having a value considered zero
+     */
+    public OpenMapRealVector(Double[] values, double epsilon) {
+        virtualSize = values.length;
+        entries = new OpenIntToDoubleHashMap(0.0);
+        this.epsilon = epsilon;
+        for (int key = 0; key < values.length; key++) {
+            double value = values[key].doubleValue();
+            if (!isDefaultValue(value)) {
+                entries.put(key, value);
+            }
+        }
+    }
+
+    /**
+     * Copy constructor.
+     * @param v The instance to copy from
+     */
+    public OpenMapRealVector(OpenMapRealVector v) {
+        virtualSize = v.getDimension();
+        entries = new OpenIntToDoubleHashMap(v.getEntries());
+        epsilon = v.epsilon;
+    }
+
+    /**
+     * Generic copy constructor.
+     * @param v The instance to copy from
+     */
+    public OpenMapRealVector(RealVector v) {
+        virtualSize = v.getDimension();
+        entries = new OpenIntToDoubleHashMap(0.0);
+        epsilon = DEFAULT_ZERO_TOLERANCE;
+        for (int key = 0; key < virtualSize; key++) {
+            double value = v.getEntry(key);
+            if (!isDefaultValue(value)) {
+                entries.put(key, value);
+            }
+        }
+    }
+
+    /**
+     * Get the entries of this instance.
+     * @return entries of this instance
+     */
+    private OpenIntToDoubleHashMap getEntries() {
+        return entries;
+    }
+
+    /**
+     * Determine if this value is within epsilon of zero.
+     * @param value The value to test
+     * @return <code>true</code> if this value is within epsilon to zero, <code>false</code> otherwise
+     * @since 2.1
+     */
+    protected boolean isDefaultValue(double value) {
+        return FastMath.abs(value) < epsilon;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealVector add(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        if (v instanceof OpenMapRealVector) {
+            return add((OpenMapRealVector) v);
+        } else {
+            return super.add(v);
+        }
+    }
+
+    /**
+     * Optimized method to add two OpenMapRealVectors.  Copies the larger vector, iterates over the smaller.
+     * @param v Vector to add with
+     * @return The sum of <code>this</code> with <code>v</code>
+     * @throws IllegalArgumentException If the dimensions don't match
+     */
+    public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{
+        checkVectorDimensions(v.getDimension());
+        boolean copyThis = entries.size() > v.entries.size();
+        OpenMapRealVector res = copyThis ? this.copy() : v.copy();
+        Iterator iter = copyThis ? v.entries.iterator() : entries.iterator();
+        OpenIntToDoubleHashMap randomAccess = copyThis ? entries : v.entries;
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (randomAccess.containsKey(key)) {
+                res.setEntry(key, randomAccess.get(key) + iter.value());
+            } else {
+                res.setEntry(key, iter.value());
+            }
+        }
+        return res;
+    }
+
+    /**
+     * Optimized method to append a OpenMapRealVector.
+     * @param v vector to append
+     * @return The result of appending <code>v</code> to self
+     */
+    public OpenMapRealVector append(OpenMapRealVector v) {
+        OpenMapRealVector res = new OpenMapRealVector(this, v.getDimension());
+        Iterator iter = v.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key() + virtualSize, iter.value());
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public OpenMapRealVector append(RealVector v) {
+        if (v instanceof OpenMapRealVector) {
+            return append((OpenMapRealVector) v);
+        }
+        return append(v.getData());
+    }
+
+    /** {@inheritDoc} */
+    public OpenMapRealVector append(double d) {
+        OpenMapRealVector res = new OpenMapRealVector(this, 1);
+        res.setEntry(virtualSize, d);
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public OpenMapRealVector append(double[] a) {
+        OpenMapRealVector res = new OpenMapRealVector(this, a.length);
+        for (int i = 0; i < a.length; i++) {
+            res.setEntry(i + virtualSize, a[i]);
+        }
+        return res;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 2.1
+     */
+    @Override
+    public OpenMapRealVector copy() {
+        return new OpenMapRealVector(this);
+    }
+
+    /**
+     * Optimized method to compute the dot product with an OpenMapRealVector.
+     * Iterates over the smaller of the two.
+     * @param v The vector to compute the dot product with
+     * @return The dot product of <code>this</code> and <code>v</code>
+     * @throws IllegalArgumentException If the dimensions don't match
+     */
+    public double dotProduct(OpenMapRealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        boolean thisIsSmaller  = entries.size() < v.entries.size();
+        Iterator iter = thisIsSmaller  ? entries.iterator() : v.entries.iterator();
+        OpenIntToDoubleHashMap larger = thisIsSmaller  ? v.entries : entries;
+        double d = 0;
+        while(iter.hasNext()) {
+            iter.advance();
+            d += iter.value() * larger.get(iter.key());
+        }
+        return d;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double dotProduct(RealVector v) throws IllegalArgumentException {
+        if(v instanceof OpenMapRealVector) {
+            return dotProduct((OpenMapRealVector)v);
+        } else {
+            return super.dotProduct(v);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public OpenMapRealVector ebeDivide(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        OpenMapRealVector res = new OpenMapRealVector(this);
+        Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key()));
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector ebeDivide(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        OpenMapRealVector res = new OpenMapRealVector(this);
+        Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value() / v[iter.key()]);
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public OpenMapRealVector ebeMultiply(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        OpenMapRealVector res = new OpenMapRealVector(this);
+        Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key()));
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector ebeMultiply(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        OpenMapRealVector res = new OpenMapRealVector(this);
+        Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value() * v[iter.key()]);
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public OpenMapRealVector getSubVector(int index, int n) throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + n - 1);
+        OpenMapRealVector res = new OpenMapRealVector(n);
+        int end = index + n;
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (key >= index && key < end) {
+                res.setEntry(key - index, iter.value());
+            }
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] getData() {
+        double[] res = new double[virtualSize];
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res[iter.key()] = iter.value();
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public int getDimension() {
+        return virtualSize;
+    }
+
+    /**
+     * Optimized method to compute distance.
+     * @param v The vector to compute distance to
+     * @return The distance from <code>this</code> and <code>v</code>
+     * @throws IllegalArgumentException If the dimensions don't match
+     */
+    public double getDistance(OpenMapRealVector v) throws IllegalArgumentException {
+        Iterator iter = entries.iterator();
+        double res = 0;
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            double delta;
+            delta = iter.value() - v.getEntry(key);
+            res += delta * delta;
+        }
+        iter = v.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (!entries.containsKey(key)) {
+                final double value = iter.value();
+                res += value * value;
+            }
+        }
+        return FastMath.sqrt(res);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getDistance(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        if (v instanceof OpenMapRealVector) {
+            return getDistance((OpenMapRealVector) v);
+        }
+        return getDistance(v.getData());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getDistance(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double res = 0;
+        for (int i = 0; i < v.length; i++) {
+            double delta = entries.get(i) - v[i];
+            res += delta * delta;
+        }
+        return FastMath.sqrt(res);
+    }
+
+    /** {@inheritDoc} */
+    public double getEntry(int index) throws MatrixIndexException {
+        checkIndex(index);
+        return entries.get(index);
+    }
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>1</sub> norm, i.e. the sum of the absolute values of
+     * elements differences.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     */
+    public double getL1Distance(OpenMapRealVector v) {
+        double max = 0;
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            double delta = FastMath.abs(iter.value() - v.getEntry(iter.key()));
+            max += delta;
+        }
+        iter = v.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (!entries.containsKey(key)) {
+                double delta = FastMath.abs(iter.value());
+                max +=  FastMath.abs(delta);
+            }
+        }
+        return max;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getL1Distance(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        if (v instanceof OpenMapRealVector) {
+            return getL1Distance((OpenMapRealVector) v);
+        }
+        return getL1Distance(v.getData());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getL1Distance(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double max = 0;
+        for (int i = 0; i < v.length; i++) {
+            double delta = FastMath.abs(getEntry(i) - v[i]);
+            max += delta;
+        }
+        return max;
+    }
+
+    /**
+     * Optimized method to compute LInfDistance.
+     * @param v The vector to compute from
+     * @return the LInfDistance
+     */
+    private double getLInfDistance(OpenMapRealVector v) {
+        double max = 0;
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            double delta = FastMath.abs(iter.value() - v.getEntry(iter.key()));
+            if (delta > max) {
+                max = delta;
+            }
+        }
+        iter = v.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (!entries.containsKey(key)) {
+                if (iter.value() > max) {
+                    max = iter.value();
+                }
+            }
+        }
+        return max;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getLInfDistance(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        if (v instanceof OpenMapRealVector) {
+            return getLInfDistance((OpenMapRealVector) v);
+        }
+        return getLInfDistance(v.getData());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getLInfDistance(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        double max = 0;
+        for (int i = 0; i < v.length; i++) {
+            double delta = FastMath.abs(getEntry(i) - v[i]);
+            if (delta > max) {
+                max = delta;
+            }
+        }
+        return max;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isInfinite() {
+        boolean infiniteFound = false;
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            final double value = iter.value();
+            if (Double.isNaN(value)) {
+                return false;
+            }
+            if (Double.isInfinite(value)) {
+                infiniteFound = true;
+            }
+        }
+        return infiniteFound;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isNaN() {
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            if (Double.isNaN(iter.value())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector mapAdd(double d) {
+        return copy().mapAddToSelf(d);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector mapAddToSelf(double d) {
+        for (int i = 0; i < virtualSize; i++) {
+            setEntry(i, getEntry(i) + d);
+        }
+        return this;
+    }
+
+     /** {@inheritDoc} */
+    @Override
+    public RealMatrix outerProduct(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize);
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int row = iter.key();
+            double value = iter.value();
+            for (int col = 0; col < virtualSize; col++) {
+                res.setEntry(row, col, value * v[col]);
+            }
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public RealVector projection(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        return v.mapMultiply(dotProduct(v) / v.dotProduct(v));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector projection(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        return (OpenMapRealVector) projection(new OpenMapRealVector(v));
+    }
+
+    /** {@inheritDoc} */
+    public void setEntry(int index, double value) throws MatrixIndexException {
+        checkIndex(index);
+        if (!isDefaultValue(value)) {
+            entries.put(index, value);
+        } else if (entries.containsKey(index)) {
+            entries.remove(index);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubVector(int index, RealVector v) throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + v.getDimension() - 1);
+        setSubVector(index, v.getData());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubVector(int index, double[] v) throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + v.length - 1);
+        for (int i = 0; i < v.length; i++) {
+            setEntry(i + index, v[i]);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void set(double value) {
+        for (int i = 0; i < virtualSize; i++) {
+            setEntry(i, value);
+        }
+    }
+
+    /**
+     * Optimized method to subtract OpenMapRealVectors.
+     * @param v The vector to subtract from <code>this</code>
+     * @return The difference of <code>this</code> and <code>v</code>
+     * @throws IllegalArgumentException If the dimensions don't match
+     */
+    public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{
+        checkVectorDimensions(v.getDimension());
+        OpenMapRealVector res = copy();
+        Iterator iter = v.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (entries.containsKey(key)) {
+                res.setEntry(key, entries.get(key) - iter.value());
+            } else {
+                res.setEntry(key, -iter.value());
+            }
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector subtract(RealVector v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        if (v instanceof OpenMapRealVector) {
+            return subtract((OpenMapRealVector) v);
+        }
+        return subtract(v.getData());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        OpenMapRealVector res = new OpenMapRealVector(this);
+        for (int i = 0; i < v.length; i++) {
+            if (entries.containsKey(i)) {
+                res.setEntry(i, entries.get(i) - v[i]);
+            } else {
+                res.setEntry(i, -v[i]);
+            }
+        }
+        return res;
+    }
+
+
+    /** {@inheritDoc} */
+    @Override
+    public OpenMapRealVector unitVector() {
+        OpenMapRealVector res = copy();
+        res.unitize();
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void unitize() {
+        double norm = getNorm();
+        if (isDefaultValue(norm)) {
+            throw  MathRuntimeException.createArithmeticException(LocalizedFormats.CANNOT_NORMALIZE_A_ZERO_NORM_VECTOR);
+        }
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            entries.put(iter.key(), iter.value() / norm);
+        }
+
+    }
+
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] toArray() {
+        return getData();
+    }
+
+    /** {@inheritDoc}
+     * <p> Implementation Note: This works on exact values, and as a result
+     * it is possible for {@code a.subtract(b)} to be the zero vector, while
+     * {@code a.hashCode() != b.hashCode()}.</p>
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        long temp;
+        temp = Double.doubleToLongBits(epsilon);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + virtualSize;
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            temp = Double.doubleToLongBits(iter.value());
+            result = prime * result + (int) (temp ^ (temp >>32));
+        }
+        return result;
+    }
+
+    /**
+     * <p> Implementation Note: This performs an exact comparison, and as a result
+     * it is possible for {@code a.subtract(b}} to be the zero vector, while
+     * {@code  a.equals(b) == false}.</p>
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof OpenMapRealVector)) {
+            return false;
+        }
+        OpenMapRealVector other = (OpenMapRealVector) obj;
+        if (virtualSize != other.virtualSize) {
+            return false;
+        }
+        if (Double.doubleToLongBits(epsilon) !=
+            Double.doubleToLongBits(other.epsilon)) {
+            return false;
+        }
+        Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            double test = other.getEntry(iter.key());
+            if (Double.doubleToLongBits(test) != Double.doubleToLongBits(iter.value())) {
+                return false;
+            }
+        }
+        iter = other.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            double test = iter.value();
+            if (Double.doubleToLongBits(test) != Double.doubleToLongBits(getEntry(iter.key()))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     *
+     * @return the percentage of none zero elements as a decimal percent.
+     * @deprecated as of 2.2 replaced by the correctly spelled {@link #getSparsity()}
+     */
+    @Deprecated
+    public double getSparcity() {
+        return getSparsity();
+    }
+
+    /**
+    *
+    * @return the percentage of none zero elements as a decimal percent.
+    * @since 2.2
+    */
+   public double getSparsity() {
+        return (double)entries.size()/(double)getDimension();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public java.util.Iterator<Entry> sparseIterator() {
+        return new OpenMapSparseIterator();
+    }
+
+    /**
+     *  Implementation of <code>Entry</code> optimized for OpenMap.
+     * <p>This implementation does not allow arbitrary calls to <code>setIndex</code>
+     * since the order that entries are returned is undefined.
+     */
+    protected class OpenMapEntry extends Entry {
+
+        /** Iterator pointing to the entry. */
+        private final Iterator iter;
+
+        /** Build an entry from an iterator point to an element.
+         * @param iter iterator pointing to the entry
+         */
+        protected OpenMapEntry(Iterator iter) {
+            this.iter = iter;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public double getValue() {
+            return iter.value();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void setValue(double value) {
+            entries.put(iter.key(), value);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public int getIndex() {
+            return iter.key();
+        }
+
+    }
+
+    /**
+     *  Iterator class to do iteration over just the non-zero elements.
+     *  <p>This implementation is fail-fast, so cannot be used to modify any zero element.
+     *
+     */
+    protected class OpenMapSparseIterator implements java.util.Iterator<Entry> {
+
+        /** Underlying iterator. */
+        private final Iterator iter;
+
+        /** Current entry. */
+        private final Entry current;
+
+        /** Simple constructor. */
+        protected OpenMapSparseIterator() {
+            iter = entries.iterator();
+            current = new OpenMapEntry(iter);
+        }
+
+        /** {@inheritDoc} */
+        public boolean hasNext() {
+            return iter.hasNext();
+        }
+
+        /** {@inheritDoc} */
+        public Entry next() {
+            iter.advance();
+            return current;
+        }
+
+        /** {@inheritDoc} */
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported");
+       }
+
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/linear/QRDecomposition.java b/src/main/java/org/apache/commons/math/linear/QRDecomposition.java
new file mode 100644
index 0000000..2f58e05
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/QRDecomposition.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+
+/**
+ * An interface to classes that implement an algorithm to calculate the
+ * QR-decomposition of a real matrix.
+ * <p>This interface is based on the class with similar name from the
+ * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the
+ * following changes:</p>
+ * <ul>
+ *   <li>a {@link #getQT() getQT} method has been added,</li>
+ *   <li>the <code>solve</code> and <code>isFullRank</code> methods have been replaced
+ *   by a {@link #getSolver() getSolver} method and the equivalent methods provided by
+ *   the returned {@link DecompositionSolver}.</li>
+ * </ul>
+ *
+ * @see <a href="http://mathworld.wolfram.com/QRDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/QR_decomposition">Wikipedia</a>
+ * @version $Revision: 826627 $ $Date: 2009-10-19 12:27:47 +0200 (lun. 19 oct. 2009) $
+ * @since 1.2
+ */
+public interface QRDecomposition {
+
+    /**
+     * Returns the matrix R of the decomposition.
+     * <p>R is an upper-triangular matrix</p>
+     * @return the R matrix
+     */
+    RealMatrix getR();
+
+    /**
+     * Returns the matrix Q of the decomposition.
+     * <p>Q is an orthogonal matrix</p>
+     * @return the Q matrix
+     */
+    RealMatrix getQ();
+
+    /**
+     * Returns the transpose of the matrix Q of the decomposition.
+     * <p>Q is an orthogonal matrix</p>
+     * @return the Q matrix
+     */
+    RealMatrix getQT();
+
+    /**
+     * Returns the Householder reflector vectors.
+     * <p>H is a lower trapezoidal matrix whose columns represent
+     * each successive Householder reflector vector. This matrix is used
+     * to compute Q.</p>
+     * @return a matrix containing the Householder reflector vectors
+     */
+    RealMatrix getH();
+
+    /**
+     * Get a solver for finding the A &times; X = B solution in least square sense.
+     * @return a solver
+     */
+    DecompositionSolver getSolver();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java b/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java
new file mode 100644
index 0000000..7356a8a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/QRDecompositionImpl.java
@@ -0,0 +1,453 @@
+/*
+ * 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.Arrays;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Calculates the QR-decomposition of a matrix.
+ * <p>The QR-decomposition of a matrix A consists of two matrices Q and R
+ * that satisfy: A = QR, Q is orthogonal (Q<sup>T</sup>Q = I), and R is
+ * upper triangular. If A is m&times;n, Q is m&times;m and R m&times;n.</p>
+ * <p>This class compute the decomposition using Householder reflectors.</p>
+ * <p>For efficiency purposes, the decomposition in packed form is transposed.
+ * This allows inner loop to iterate inside rows, which is much more cache-efficient
+ * in Java.</p>
+ *
+ * @see <a href="http://mathworld.wolfram.com/QRDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/QR_decomposition">Wikipedia</a>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ */
+public class QRDecompositionImpl implements QRDecomposition {
+
+    /**
+     * A packed TRANSPOSED representation of the QR decomposition.
+     * <p>The elements BELOW the diagonal are the elements of the UPPER triangular
+     * matrix R, and the rows ABOVE the diagonal are the Householder reflector vectors
+     * from which an explicit form of Q can be recomputed if desired.</p>
+     */
+    private double[][] qrt;
+
+    /** The diagonal elements of R. */
+    private double[] rDiag;
+
+    /** Cached value of Q. */
+    private RealMatrix cachedQ;
+
+    /** Cached value of QT. */
+    private RealMatrix cachedQT;
+
+    /** Cached value of R. */
+    private RealMatrix cachedR;
+
+    /** Cached value of H. */
+    private RealMatrix cachedH;
+
+    /**
+     * Calculates the QR-decomposition of the given matrix.
+     * @param matrix The matrix to decompose.
+     */
+    public QRDecompositionImpl(RealMatrix matrix) {
+
+        final int m = matrix.getRowDimension();
+        final int n = matrix.getColumnDimension();
+        qrt = matrix.transpose().getData();
+        rDiag = new double[FastMath.min(m, n)];
+        cachedQ  = null;
+        cachedQT = null;
+        cachedR  = null;
+        cachedH  = null;
+
+        /*
+         * The QR decomposition of a matrix A is calculated using Householder
+         * reflectors by repeating the following operations to each minor
+         * A(minor,minor) of A:
+         */
+        for (int minor = 0; minor < FastMath.min(m, n); minor++) {
+
+            final double[] qrtMinor = qrt[minor];
+
+            /*
+             * Let x be the first column of the minor, and a^2 = |x|^2.
+             * x will be in the positions qr[minor][minor] through qr[m][minor].
+             * The first column of the transformed minor will be (a,0,0,..)'
+             * The sign of a is chosen to be opposite to the sign of the first
+             * component of x. Let's find a:
+             */
+            double xNormSqr = 0;
+            for (int row = minor; row < m; row++) {
+                final double c = qrtMinor[row];
+                xNormSqr += c * c;
+            }
+            final double a = (qrtMinor[minor] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr);
+            rDiag[minor] = a;
+
+            if (a != 0.0) {
+
+                /*
+                 * Calculate the normalized reflection vector v and transform
+                 * the first column. We know the norm of v beforehand: v = x-ae
+                 * so |v|^2 = <x-ae,x-ae> = <x,x>-2a<x,e>+a^2<e,e> =
+                 * a^2+a^2-2a<x,e> = 2a*(a - <x,e>).
+                 * Here <x, e> is now qr[minor][minor].
+                 * v = x-ae is stored in the column at qr:
+                 */
+                qrtMinor[minor] -= a; // now |v|^2 = -2a*(qr[minor][minor])
+
+                /*
+                 * Transform the rest of the columns of the minor:
+                 * They will be transformed by the matrix H = I-2vv'/|v|^2.
+                 * If x is a column vector of the minor, then
+                 * Hx = (I-2vv'/|v|^2)x = x-2vv'x/|v|^2 = x - 2<x,v>/|v|^2 v.
+                 * Therefore the transformation is easily calculated by
+                 * subtracting the column vector (2<x,v>/|v|^2)v from x.
+                 *
+                 * Let 2<x,v>/|v|^2 = alpha. From above we have
+                 * |v|^2 = -2a*(qr[minor][minor]), so
+                 * alpha = -<x,v>/(a*qr[minor][minor])
+                 */
+                for (int col = minor+1; col < n; col++) {
+                    final double[] qrtCol = qrt[col];
+                    double alpha = 0;
+                    for (int row = minor; row < m; row++) {
+                        alpha -= qrtCol[row] * qrtMinor[row];
+                    }
+                    alpha /= a * qrtMinor[minor];
+
+                    // Subtract the column vector alpha*v from x.
+                    for (int row = minor; row < m; row++) {
+                        qrtCol[row] -= alpha * qrtMinor[row];
+                    }
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getR() {
+
+        if (cachedR == null) {
+
+            // R is supposed to be m x n
+            final int n = qrt.length;
+            final int m = qrt[0].length;
+            cachedR = MatrixUtils.createRealMatrix(m, n);
+
+            // copy the diagonal from rDiag and the upper triangle of qr
+            for (int row = FastMath.min(m, n) - 1; row >= 0; row--) {
+                cachedR.setEntry(row, row, rDiag[row]);
+                for (int col = row + 1; col < n; col++) {
+                    cachedR.setEntry(row, col, qrt[col][row]);
+                }
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedR;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getQ() {
+        if (cachedQ == null) {
+            cachedQ = getQT().transpose();
+        }
+        return cachedQ;
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getQT() {
+
+        if (cachedQT == null) {
+
+            // QT is supposed to be m x m
+            final int n = qrt.length;
+            final int m = qrt[0].length;
+            cachedQT = MatrixUtils.createRealMatrix(m, m);
+
+            /*
+             * Q = Q1 Q2 ... Q_m, so Q is formed by first constructing Q_m and then
+             * applying the Householder transformations Q_(m-1),Q_(m-2),...,Q1 in
+             * succession to the result
+             */
+            for (int minor = m - 1; minor >= FastMath.min(m, n); minor--) {
+                cachedQT.setEntry(minor, minor, 1.0);
+            }
+
+            for (int minor = FastMath.min(m, n)-1; minor >= 0; minor--){
+                final double[] qrtMinor = qrt[minor];
+                cachedQT.setEntry(minor, minor, 1.0);
+                if (qrtMinor[minor] != 0.0) {
+                    for (int col = minor; col < m; col++) {
+                        double alpha = 0;
+                        for (int row = minor; row < m; row++) {
+                            alpha -= cachedQT.getEntry(col, row) * qrtMinor[row];
+                        }
+                        alpha /= rDiag[minor] * qrtMinor[minor];
+
+                        for (int row = minor; row < m; row++) {
+                            cachedQT.addToEntry(col, row, -alpha * qrtMinor[row]);
+                        }
+                    }
+                }
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedQT;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getH() {
+
+        if (cachedH == null) {
+
+            final int n = qrt.length;
+            final int m = qrt[0].length;
+            cachedH = MatrixUtils.createRealMatrix(m, n);
+            for (int i = 0; i < m; ++i) {
+                for (int j = 0; j < FastMath.min(i + 1, n); ++j) {
+                    cachedH.setEntry(i, j, qrt[j][i] / -rDiag[j]);
+                }
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedH;
+
+    }
+
+    /** {@inheritDoc} */
+    public DecompositionSolver getSolver() {
+        return new Solver(qrt, rDiag);
+    }
+
+    /** Specialized solver. */
+    private static class Solver implements DecompositionSolver {
+
+        /**
+         * A packed TRANSPOSED representation of the QR decomposition.
+         * <p>The elements BELOW the diagonal are the elements of the UPPER triangular
+         * matrix R, and the rows ABOVE the diagonal are the Householder reflector vectors
+         * from which an explicit form of Q can be recomputed if desired.</p>
+         */
+        private final double[][] qrt;
+
+        /** The diagonal elements of R. */
+        private final double[] rDiag;
+
+        /**
+         * Build a solver from decomposed matrix.
+         * @param qrt packed TRANSPOSED representation of the QR decomposition
+         * @param rDiag diagonal elements of R
+         */
+        private Solver(final double[][] qrt, final double[] rDiag) {
+            this.qrt   = qrt;
+            this.rDiag = rDiag;
+        }
+
+        /** {@inheritDoc} */
+        public boolean isNonSingular() {
+
+            for (double diag : rDiag) {
+                if (diag == 0) {
+                    return false;
+                }
+            }
+            return true;
+
+        }
+
+        /** {@inheritDoc} */
+        public double[] solve(double[] b)
+        throws IllegalArgumentException, InvalidMatrixException {
+
+            final int n = qrt.length;
+            final int m = qrt[0].length;
+            if (b.length != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                        b.length, m);
+            }
+            if (!isNonSingular()) {
+                throw new SingularMatrixException();
+            }
+
+            final double[] x = new double[n];
+            final double[] y = b.clone();
+
+            // apply Householder transforms to solve Q.y = b
+            for (int minor = 0; minor < FastMath.min(m, n); minor++) {
+
+                final double[] qrtMinor = qrt[minor];
+                double dotProduct = 0;
+                for (int row = minor; row < m; row++) {
+                    dotProduct += y[row] * qrtMinor[row];
+                }
+                dotProduct /= rDiag[minor] * qrtMinor[minor];
+
+                for (int row = minor; row < m; row++) {
+                    y[row] += dotProduct * qrtMinor[row];
+                }
+
+            }
+
+            // solve triangular system R.x = y
+            for (int row = rDiag.length - 1; row >= 0; --row) {
+                y[row] /= rDiag[row];
+                final double yRow   = y[row];
+                final double[] qrtRow = qrt[row];
+                x[row] = yRow;
+                for (int i = 0; i < row; i++) {
+                    y[i] -= yRow * qrtRow[i];
+                }
+            }
+
+            return x;
+
+        }
+
+        /** {@inheritDoc} */
+        public RealVector solve(RealVector b)
+        throws IllegalArgumentException, InvalidMatrixException {
+            try {
+                return solve((ArrayRealVector) b);
+            } catch (ClassCastException cce) {
+                return new ArrayRealVector(solve(b.getData()), 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 that minimizes the two norm of A &times; X - B
+         * @throws IllegalArgumentException if matrices dimensions don't match
+         * @throws InvalidMatrixException if decomposed matrix is singular
+         */
+        public ArrayRealVector solve(ArrayRealVector b)
+        throws IllegalArgumentException, InvalidMatrixException {
+            return new ArrayRealVector(solve(b.getDataRef()), false);
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix solve(RealMatrix b)
+        throws IllegalArgumentException, InvalidMatrixException {
+
+            final int n = qrt.length;
+            final int m = qrt[0].length;
+            if (b.getRowDimension() != m) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIMENSIONS_MISMATCH_2x2,
+                        b.getRowDimension(), b.getColumnDimension(), m, "n");
+            }
+            if (!isNonSingular()) {
+                throw new SingularMatrixException();
+            }
+
+            final int columns        = b.getColumnDimension();
+            final int blockSize      = BlockRealMatrix.BLOCK_SIZE;
+            final int cBlocks        = (columns + blockSize - 1) / blockSize;
+            final double[][] xBlocks = BlockRealMatrix.createBlocksLayout(n, columns);
+            final double[][] y       = new double[b.getRowDimension()][blockSize];
+            final double[]   alpha   = new double[blockSize];
+
+            for (int kBlock = 0; kBlock < cBlocks; ++kBlock) {
+                final int kStart = kBlock * blockSize;
+                final int kEnd   = FastMath.min(kStart + blockSize, columns);
+                final int kWidth = kEnd - kStart;
+
+                // get the right hand side vector
+                b.copySubMatrix(0, m - 1, kStart, kEnd - 1, y);
+
+                // apply Householder transforms to solve Q.y = b
+                for (int minor = 0; minor < FastMath.min(m, n); minor++) {
+                    final double[] qrtMinor = qrt[minor];
+                    final double factor     = 1.0 / (rDiag[minor] * qrtMinor[minor]);
+
+                    Arrays.fill(alpha, 0, kWidth, 0.0);
+                    for (int row = minor; row < m; ++row) {
+                        final double   d    = qrtMinor[row];
+                        final double[] yRow = y[row];
+                        for (int k = 0; k < kWidth; ++k) {
+                            alpha[k] += d * yRow[k];
+                        }
+                    }
+                    for (int k = 0; k < kWidth; ++k) {
+                        alpha[k] *= factor;
+                    }
+
+                    for (int row = minor; row < m; ++row) {
+                        final double   d    = qrtMinor[row];
+                        final double[] yRow = y[row];
+                        for (int k = 0; k < kWidth; ++k) {
+                            yRow[k] += alpha[k] * d;
+                        }
+                    }
+
+                }
+
+                // solve triangular system R.x = y
+                for (int j = rDiag.length - 1; j >= 0; --j) {
+                    final int      jBlock = j / blockSize;
+                    final int      jStart = jBlock * blockSize;
+                    final double   factor = 1.0 / rDiag[j];
+                    final double[] yJ     = y[j];
+                    final double[] xBlock = xBlocks[jBlock * cBlocks + kBlock];
+                    int index = (j - jStart) * kWidth;
+                    for (int k = 0; k < kWidth; ++k) {
+                        yJ[k]          *= factor;
+                        xBlock[index++] = yJ[k];
+                    }
+
+                    final double[] qrtJ = qrt[j];
+                    for (int i = 0; i < j; ++i) {
+                        final double rIJ  = qrtJ[i];
+                        final double[] yI = y[i];
+                        for (int k = 0; k < kWidth; ++k) {
+                            yI[k] -= yJ[k] * rIJ;
+                        }
+                    }
+
+                }
+
+            }
+
+            return new BlockRealMatrix(n, columns, xBlocks, false);
+
+        }
+
+        /** {@inheritDoc} */
+        public RealMatrix getInverse()
+        throws InvalidMatrixException {
+            return solve(MatrixUtils.createRealIdentityMatrix(rDiag.length));
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/RealMatrix.java b/src/main/java/org/apache/commons/math/linear/RealMatrix.java
new file mode 100644
index 0000000..e025fd4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/RealMatrix.java
@@ -0,0 +1,871 @@
+/*
+ * 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 org.apache.commons.math.linear.MatrixVisitorException;
+
+
+/**
+ * Interface defining a real-valued matrix with basic algebraic operations.
+ * <p>
+ * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ */
+public interface RealMatrix extends AnyMatrix {
+
+    /**
+     * Create a new RealMatrix of the same type as the instance with the supplied
+     * row and column dimensions.
+     *
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @return a new matrix of the same type as the instance
+     * @throws IllegalArgumentException if row or column dimension is not positive
+     * @since 2.0
+     */
+    RealMatrix createMatrix(final int rowDimension, final int columnDimension);
+
+    /**
+     * Returns a (deep) copy of this.
+     *
+     * @return matrix copy
+     */
+    RealMatrix copy();
+
+    /**
+     * Compute the sum of this and m.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    RealMatrix add(RealMatrix m) throws IllegalArgumentException;
+
+    /**
+     * Compute this minus m.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this - m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    RealMatrix subtract(RealMatrix m) throws IllegalArgumentException;
+
+     /**
+     * Returns the result of adding d to each entry of this.
+     *
+     * @param d    value to be added to each entry
+     * @return     d + this
+     */
+    RealMatrix scalarAdd(double d);
+
+    /**
+     * Returns the result multiplying each entry of this by d.
+     *
+     * @param d    value to multiply all entries by
+     * @return     d * this
+     */
+    RealMatrix scalarMultiply(double d);
+
+    /**
+     * Returns the result of postmultiplying this by m.
+     *
+     * @param m    matrix to postmultiply by
+     * @return     this * m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    RealMatrix multiply(RealMatrix m) throws IllegalArgumentException;
+
+    /**
+     * Returns the result premultiplying this by <code>m</code>.
+     * @param m    matrix to premultiply by
+     * @return     m * this
+     * @throws     IllegalArgumentException
+     *             if rowDimension(this) != columnDimension(m)
+     */
+    RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException;
+
+    /**
+     * Returns matrix entries as a two-dimensional array.
+     *
+     * @return    2-dimensional array of entries
+     */
+    double[][] getData();
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
+     * maximum absolute row sum norm</a> of the matrix.
+     *
+     * @return norm
+     */
+    double getNorm();
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/FrobeniusNorm.html">
+     * Frobenius norm</a> of the matrix.
+     *
+     * @return norm
+     */
+    double getFrobeniusNorm();
+
+    /**
+     * Gets a submatrix. Rows and columns are indicated
+     * counting from 0 to n-1.
+     *
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     * @return The subMatrix containing the data of the
+     *         specified rows and columns
+     * @exception MatrixIndexException  if the indices are not valid
+     */
+   RealMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn)
+       throws MatrixIndexException;
+
+   /**
+    * Gets a submatrix. Rows and columns are indicated
+    * counting from 0 to n-1.
+    *
+    * @param selectedRows Array of row indices.
+    * @param selectedColumns Array of column indices.
+    * @return The subMatrix containing the data in the
+    *         specified rows and columns
+    * @exception MatrixIndexException if row or column selections are not valid
+    */
+   RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
+       throws MatrixIndexException;
+
+   /**
+    * Copy a submatrix. Rows and columns are indicated
+    * counting from 0 to n-1.
+    *
+    * @param startRow Initial row index
+    * @param endRow Final row index (inclusive)
+    * @param startColumn Initial column index
+    * @param endColumn Final column index (inclusive)
+    * @param destination The arrays where the submatrix data should be copied
+    * (if larger than rows/columns counts, only the upper-left part will be used)
+    * @exception MatrixIndexException if the indices are not valid
+    * @exception IllegalArgumentException if the destination array is too small
+    */
+  void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn,
+                     double[][] destination)
+      throws MatrixIndexException, IllegalArgumentException;
+
+  /**
+   * Copy a submatrix. Rows and columns are indicated
+   * counting from 0 to n-1.
+   *
+    * @param selectedRows Array of row indices.
+    * @param selectedColumns Array of column indices.
+   * @param destination The arrays where the submatrix data should be copied
+   * (if larger than rows/columns counts, only the upper-left part will be used)
+   * @exception MatrixIndexException if the indices are not valid
+   * @exception IllegalArgumentException if the destination array is too small
+   */
+  void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination)
+      throws MatrixIndexException, IllegalArgumentException;
+
+   /**
+    * Replace the submatrix starting at <code>row, column</code> using data in
+    * the input <code>subMatrix</code> array. Indexes are 0-based.
+    * <p>
+    * Example:<br>
+    * Starting with <pre>
+    * 1  2  3  4
+    * 5  6  7  8
+    * 9  0  1  2
+    * </pre>
+    * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
+    * <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
+    * 1  2  3  4
+    * 5  3  4  8
+    * 9  5  6  2
+    * </pre></p>
+    *
+    * @param subMatrix  array containing the submatrix replacement data
+    * @param row  row coordinate of the top, left element to be replaced
+    * @param column  column coordinate of the top, left element to be replaced
+    * @throws MatrixIndexException  if subMatrix does not fit into this
+    *    matrix from element in (row, column)
+    * @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
+    *  (not all rows have the same length) or empty
+    * @throws NullPointerException if <code>subMatrix</code> is null
+    * @since 2.0
+    */
+   void setSubMatrix(double[][] subMatrix, int row, int column)
+       throws MatrixIndexException;
+
+   /**
+    * Returns the entries in row number <code>row</code>
+    * as a row matrix.  Row indices start at 0.
+    *
+    * @param row the row to be fetched
+    * @return row matrix
+    * @throws MatrixIndexException if the specified row index is invalid
+    */
+   RealMatrix getRowMatrix(int row) throws MatrixIndexException;
+
+   /**
+    * Sets the entries in row number <code>row</code>
+    * as a row matrix.  Row indices start at 0.
+    *
+    * @param row the row to be set
+    * @param matrix row matrix (must have one row and the same number of columns
+    * as the instance)
+    * @throws MatrixIndexException if the specified row index is invalid
+    * @throws InvalidMatrixException if the matrix dimensions do not match one
+    * instance row
+    */
+   void setRowMatrix(int row, RealMatrix matrix)
+       throws MatrixIndexException, InvalidMatrixException;
+
+   /**
+    * Returns the entries in column number <code>column</code>
+    * as a column matrix.  Column indices start at 0.
+    *
+    * @param column the column to be fetched
+    * @return column matrix
+    * @throws MatrixIndexException if the specified column index is invalid
+    */
+   RealMatrix getColumnMatrix(int column) throws MatrixIndexException;
+
+   /**
+    * Sets the entries in column number <code>column</code>
+    * as a column matrix.  Column indices start at 0.
+    *
+    * @param column the column to be set
+    * @param matrix column matrix (must have one column and the same number of rows
+    * as the instance)
+    * @throws MatrixIndexException if the specified column index is invalid
+    * @throws InvalidMatrixException if the matrix dimensions do not match one
+    * instance column
+    */
+   void setColumnMatrix(int column, RealMatrix matrix)
+       throws MatrixIndexException, InvalidMatrixException;
+
+   /**
+    * Returns the entries in row number <code>row</code>
+    * 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;
+
+   /**
+    * Sets the entries in row number <code>row</code>
+    * as a vector.  Row indices start at 0.
+    *
+    * @param row the row to be set
+    * @param vector row vector (must have the same number of columns
+    * as the instance)
+    * @throws MatrixIndexException if the specified row index is invalid
+    * @throws InvalidMatrixException if the vector dimension does not match one
+    * instance row
+    */
+   void setRowVector(int row, RealVector vector)
+       throws MatrixIndexException, InvalidMatrixException;
+
+   /**
+    * Returns the entries in column number <code>column</code>
+    * as a 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;
+
+   /**
+    * Sets the entries in column number <code>column</code>
+    * as a vector.  Column indices start at 0.
+    *
+    * @param column the column to be set
+    * @param vector column vector (must have the same number of rows as the instance)
+    * @throws MatrixIndexException if the specified column index is invalid
+    * @throws InvalidMatrixException if the vector dimension does not match one
+    * instance column
+    */
+   void setColumnVector(int column, RealVector vector)
+       throws MatrixIndexException, InvalidMatrixException;
+
+    /**
+     * Returns the entries in row number <code>row</code> as an array.
+     * <p>
+     * Row indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= row < rowDimension.</code></p>
+     *
+     * @param row the row to be fetched
+     * @return array of entries in the row
+     * @throws MatrixIndexException if the specified row index is not valid
+     */
+    double[] getRow(int row) throws MatrixIndexException;
+
+    /**
+     * Sets the entries in row number <code>row</code>
+     * as a row matrix.  Row indices start at 0.
+     *
+     * @param row the row to be set
+     * @param array row matrix (must have the same number of columns as the instance)
+     * @throws MatrixIndexException if the specified row index is invalid
+     * @throws InvalidMatrixException if the array size does not match one
+     * instance row
+     */
+    void setRow(int row, double[] array)
+        throws MatrixIndexException, InvalidMatrixException;
+
+    /**
+     * Returns the entries in column number <code>col</code> as an array.
+     * <p>
+     * Column indices start at 0.  A <code>MatrixIndexException</code> is thrown
+     * unless <code>0 <= column < columnDimension.</code></p>
+     *
+     * @param column the column to be fetched
+     * @return array of entries in the column
+     * @throws MatrixIndexException if the specified column index is not valid
+     */
+    double[] getColumn(int column) throws MatrixIndexException;
+
+    /**
+     * Sets the entries in column number <code>column</code>
+     * as a column matrix.  Column indices start at 0.
+     *
+     * @param column the column to be set
+     * @param array column array (must have the same number of rows as the instance)
+     * @throws MatrixIndexException if the specified column index is invalid
+     * @throws InvalidMatrixException if the array size does not match one
+     * instance column
+     */
+    void setColumn(int column, double[] array)
+        throws MatrixIndexException, InvalidMatrixException;
+
+    /**
+     * Returns the entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be fetched
+     * @param column  column location of entry to be fetched
+     * @return matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     */
+    double getEntry(int row, int column) throws MatrixIndexException;
+
+    /**
+     * Set the entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be set
+     * @param column  column location of entry to be set
+     * @param value matrix entry to be set in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     * @since 2.0
+     */
+    void setEntry(int row, int column, double value) throws MatrixIndexException;
+
+    /**
+     * Change an entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be set
+     * @param column  column location of entry to be set
+     * @param increment value to add to the current matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     * @since 2.0
+     */
+    void addToEntry(int row, int column, double increment) throws MatrixIndexException;
+
+    /**
+     * Change an entry in the specified row and column.
+     * <p>
+     * Row and column indices start at 0 and must satisfy
+     * <ul>
+     * <li><code>0 <= row < rowDimension</code></li>
+     * <li><code> 0 <= column < columnDimension</code></li>
+     * </ul>
+     * otherwise a <code>MatrixIndexException</code> is thrown.</p>
+     *
+     * @param row  row location of entry to be set
+     * @param column  column location of entry to be set
+     * @param factor multiplication factor for the current matrix entry in row,column
+     * @throws MatrixIndexException if the row or column index is not valid
+     * @since 2.0
+     */
+    void multiplyEntry(int row, int column, double factor) throws MatrixIndexException;
+
+    /**
+     * Returns the transpose of this matrix.
+     *
+     * @return transpose matrix
+     */
+    RealMatrix transpose();
+
+    /**
+     * Returns the inverse of this matrix.
+     *
+     * @return inverse matrix
+     * @throws InvalidMatrixException if  this is not invertible
+     * @deprecated as of release 2.0, replaced by <code>
+     * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix)
+     * new LUDecompositionImpl(m)}.{@link LUDecomposition#getSolver()
+     * getSolver()}.{@link DecompositionSolver#getInverse()
+     * getInverse()}</code>
+     */
+    @Deprecated
+    RealMatrix inverse() throws InvalidMatrixException;
+
+    /**
+     * Returns the determinant of this matrix.
+     *
+     * @return determinant
+     * @deprecated as of release 2.0, replaced by <code>
+     * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix)
+     * new LUDecompositionImpl(m)}.{@link LUDecomposition#getDeterminant()
+     * getDeterminant()}</code>
+     */
+    @Deprecated
+    double getDeterminant();
+
+    /**
+     * Is this a singular matrix?
+     * @return true if the matrix is singular
+     * @deprecated as of release 2.0, replaced by the boolean negation of
+     * <code>{@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix)
+     * new LUDecompositionImpl(m)}.{@link LUDecomposition#getSolver()
+     * getSolver()}.{@link DecompositionSolver#isNonSingular()
+     * isNonSingular()}</code>
+     */
+    @Deprecated
+    boolean isSingular();
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
+     * trace</a> of the matrix (the sum of the elements on the main diagonal).
+     *
+     * @return trace
+     * @throws NonSquareMatrixException if the matrix is not square
+     */
+    double getTrace() throws NonSquareMatrixException;
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @param v the vector to operate on
+     * @return this*v
+     * @throws IllegalArgumentException if columnDimension != v.size()
+     */
+    double[] operate(double[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns the result of multiplying this by the vector <code>v</code>.
+     *
+     * @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 <code>v</code>.
+     *
+     * @param v the row vector to premultiply by
+     * @return v*this
+     * @throws IllegalArgumentException if rowDimension != v.size()
+     */
+    double[] preMultiply(double[] v) throws IllegalArgumentException;
+
+    /**
+     * Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
+     *
+     * @param v the row vector to premultiply by
+     * @return v*this
+     * @throws IllegalArgumentException if rowDimension != v.size()
+     */
+    RealVector preMultiply(RealVector v) throws IllegalArgumentException;
+
+    /**
+     * Visit (and possibly change) all matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInRowOrder(RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) all matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInRowOrder(RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) some matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInRowOrder(RealMatrixChangingVisitor visitor,
+                          int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) some matrix entries in row order.
+     * <p>Row order starts at upper left and iterating through all elements
+     * of a row from left to right before going to the leftmost element
+     * of the next row.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInRowOrder(RealMatrixPreservingVisitor visitor,
+                          int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) all matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInColumnOrder(RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) all matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInColumnOrder(RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) some matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInColumnOrder(RealMatrixChangingVisitor visitor,
+                             int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) some matrix entries in column order.
+     * <p>Column order starts at upper left and iterating through all elements
+     * of a column from top to bottom before going to the topmost element
+     * of the next column.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInColumnOrder(RealMatrixPreservingVisitor visitor,
+                             int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) all matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInOptimizedOrder(RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) all matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException;
+
+    /**
+     * Visit (and possibly change) some matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInOptimizedOrder(RealMatrixChangingVisitor visitor,
+                                int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Visit (but don't change) some matrix entries using the fastest possible order.
+     * <p>The fastest walking order depends on the exact matrix class. It may be
+     * different from traditional row or column orders.</p>
+     * @param visitor visitor used to process all matrix entries
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     * @exception  MatrixVisitorException if the visitor cannot process an entry
+     * @exception MatrixIndexException  if the indices are not valid
+     * @see #walkInRowOrder(RealMatrixChangingVisitor)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
+     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
+     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
+     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
+     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
+     * of the walk
+     */
+    double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor,
+                                int startRow, int endRow, int startColumn, int endColumn)
+        throws MatrixIndexException, MatrixVisitorException;
+
+    /**
+     * Returns the solution vector for a linear system with coefficient
+     * matrix = this and constant vector = <code>b</code>.
+     *
+     * @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
+     * @deprecated as of release 2.0, replaced by {@link DecompositionSolver#solve(double[])}
+     */
+    @Deprecated
+    double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException;
+
+    /**
+     * Returns a matrix of (column) solution vectors for linear systems with
+     * coefficient matrix = this and constant vectors = columns of
+     * <code>b</code>.
+     *
+     * @param b  matrix of constant vectors forming RHS of linear systems to
+     * to solve
+     * @return matrix of solution vectors
+     * @throws IllegalArgumentException if this.rowDimension != row dimension
+     * @throws InvalidMatrixException if this matrix is not square or is singular
+     * @deprecated as of release 2.0, replaced by {@link DecompositionSolver#solve(RealMatrix)}
+     */
+    @Deprecated
+    RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/RealMatrixChangingVisitor.java b/src/main/java/org/apache/commons/math/linear/RealMatrixChangingVisitor.java
new file mode 100644
index 0000000..25e8f96
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/RealMatrixChangingVisitor.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Interface defining a visitor for matrix entries.
+ *
+ * @see DefaultRealMatrixChangingVisitor
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface RealMatrixChangingVisitor {
+
+    /**
+     * Start visiting a matrix.
+     * <p>This method is called once before any entry of the matrix is visited.</p>
+     * @param rows number of rows of the matrix
+     * @param columns number of columns of the matrix
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     */
+    void start(int rows, int columns,
+               int startRow, int endRow, int startColumn, int endColumn);
+
+    /**
+     * Visit one matrix entry.
+     * @param row row index of the entry
+     * @param column column index of the entry
+     * @param value current value of the entry
+     * @return the new value to be set for the entry
+     * @throws MatrixVisitorException if something wrong occurs
+     */
+    double visit(int row, int column, double value)
+        throws MatrixVisitorException;
+
+    /**
+     * End visiting a matrix.
+     * <p>This method is called once after all entries of the matrix have been visited.</p>
+     * @return the value that the <code>walkInXxxOrder</code> must return
+     */
+    double end();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/RealMatrixImpl.java b/src/main/java/org/apache/commons/math/linear/RealMatrixImpl.java
new file mode 100644
index 0000000..7dbfdba
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/RealMatrixImpl.java
@@ -0,0 +1,629 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.linear.MatrixVisitorException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Implementation of RealMatrix using a double[][] array to store entries and
+ * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
+ * LU decomposition</a> to support linear system
+ * solution and inverse.
+ * <p>
+ * The LU decomposition is performed as needed, to support the following operations: <ul>
+ * <li>solve</li>
+ * <li>isSingular</li>
+ * <li>getDeterminant</li>
+ * <li>inverse</li> </ul></p>
+ * <p>
+ * <strong>Usage notes</strong>:<br>
+ * <ul><li>
+ * The LU decomposition is cached and reused on subsequent calls.
+ * If data are modified via references to the underlying array obtained using
+ * <code>getDataRef()</code>, then the stored LU decomposition will not be
+ * discarded.  In this case, you need to explicitly invoke
+ * <code>LUDecompose()</code> to recompute the decomposition
+ * before using any of the methods above.</li>
+ * <li>
+ * As specified in the {@link RealMatrix} interface, matrix element indexing
+ * is 0-based -- e.g., <code>getEntry(0, 0)</code>
+ * returns the element in the first row, first column of the matrix.</li></ul>
+ * </p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @deprecated as of 2.0 replaced by {@link Array2DRowRealMatrix}
+ */
+@Deprecated
+public class RealMatrixImpl extends AbstractRealMatrix implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1067294169172445528L;
+
+    /** Entries of the matrix */
+    protected double data[][];
+
+    /**
+     * Creates a matrix with no data
+     */
+    public RealMatrixImpl() {
+    }
+
+    /**
+     * Create a new RealMatrix with the supplied row and column dimensions.
+     *
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not
+     *  positive
+     */
+    public RealMatrixImpl(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        super(rowDimension, columnDimension);
+        data = new double[rowDimension][columnDimension];
+    }
+
+    /**
+     * Create a new RealMatrix using the input array as the underlying
+     * data array.
+     * <p>The input array is copied, not referenced. This constructor has
+     * the same effect as calling {@link #RealMatrixImpl(double[][], boolean)}
+     * with the second argument set to <code>true</code>.</p>
+     *
+     * @param d data for new matrix
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #RealMatrixImpl(double[][], boolean)
+     */
+    public RealMatrixImpl(final double[][] d)
+        throws IllegalArgumentException, NullPointerException {
+        copyIn(d);
+    }
+
+    /**
+     * Create a new RealMatrix using the input array as the underlying
+     * data array.
+     * <p>If an array is built specially in order to be embedded in a
+     * RealMatrix 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 matrix
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     * @throws IllegalArgumentException if <code>d</code> is not rectangular
+     *  (not all rows have the same length) or empty
+     * @throws NullPointerException if <code>d</code> is null
+     * @see #RealMatrixImpl(double[][])
+     */
+    public RealMatrixImpl(final double[][] d, final boolean copyArray)
+        throws IllegalArgumentException, NullPointerException {
+        if (copyArray) {
+            copyIn(d);
+        } else {
+            if (d == null) {
+                throw new NullPointerException();
+            }
+            final int nRows = d.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+            final int nCols = d[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            for (int r = 1; r < nRows; r++) {
+                if (d[r].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                            nCols, d[r].length);
+                }
+            }
+            data = d;
+        }
+    }
+
+    /**
+     * Create a new (column) RealMatrix using <code>v</code> as the
+     * data for the unique column of the <code>v.length x 1</code> matrix
+     * created.
+     * <p>The input array is copied, not referenced.</p>
+     *
+     * @param v column vector holding data for new matrix
+     */
+    public RealMatrixImpl(final double[] v) {
+        final int nRows = v.length;
+        data = new double[nRows][1];
+        for (int row = 0; row < nRows; row++) {
+            data[row][0] = v[row];
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix createMatrix(final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        return new RealMatrixImpl(rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix copy() {
+        return new RealMatrixImpl(copyOut(), false);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix add(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return add((RealMatrixImpl) m);
+        } catch (ClassCastException cce) {
+            return super.add(m);
+        }
+    }
+
+    /**
+     * Compute the sum of this and <code>m</code>.
+     *
+     * @param m    matrix to be added
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public RealMatrixImpl add(final RealMatrixImpl m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkAdditionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final double[][] outData = new double[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final double[] dataRow    = data[row];
+            final double[] mRow       = m.data[row];
+            final double[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col] + mRow[col];
+            }
+        }
+
+        return new RealMatrixImpl(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix subtract(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return subtract((RealMatrixImpl) m);
+        } catch (ClassCastException cce) {
+            return super.subtract(m);
+        }
+    }
+
+    /**
+     * Compute  this minus <code>m</code>.
+     *
+     * @param m    matrix to be subtracted
+     * @return     this + m
+     * @throws  IllegalArgumentException if m is not the same size as this
+     */
+    public RealMatrixImpl subtract(final RealMatrixImpl m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkSubtractionCompatible(this, m);
+
+        final int rowCount    = getRowDimension();
+        final int columnCount = getColumnDimension();
+        final double[][] outData = new double[rowCount][columnCount];
+        for (int row = 0; row < rowCount; row++) {
+            final double[] dataRow    = data[row];
+            final double[] mRow       = m.data[row];
+            final double[] outDataRow = outData[row];
+            for (int col = 0; col < columnCount; col++) {
+                outDataRow[col] = dataRow[col] - mRow[col];
+            }
+        }
+
+        return new RealMatrixImpl(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealMatrix multiply(final RealMatrix m)
+        throws IllegalArgumentException {
+        try {
+            return multiply((RealMatrixImpl) m);
+        } catch (ClassCastException cce) {
+            return super.multiply(m);
+        }
+    }
+
+    /**
+     * Returns the result of postmultiplying this by <code>m</code>.
+     * @param m    matrix to postmultiply by
+     * @return     this*m
+     * @throws     IllegalArgumentException
+     *             if columnDimension(this) != rowDimension(m)
+     */
+    public RealMatrixImpl multiply(final RealMatrixImpl m)
+        throws IllegalArgumentException {
+
+        // safety check
+        MatrixUtils.checkMultiplicationCompatible(this, m);
+
+        final int nRows = this.getRowDimension();
+        final int nCols = m.getColumnDimension();
+        final int nSum = this.getColumnDimension();
+        final double[][] outData = new double[nRows][nCols];
+        for (int row = 0; row < nRows; row++) {
+            final double[] dataRow    = data[row];
+            final double[] outDataRow = outData[row];
+            for (int col = 0; col < nCols; col++) {
+                double sum = 0;
+                for (int i = 0; i < nSum; i++) {
+                    sum += dataRow[i] * m.data[i][col];
+                }
+                outDataRow[col] = sum;
+            }
+        }
+
+        return new RealMatrixImpl(outData, false);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[][] getData() {
+        return copyOut();
+    }
+
+    /**
+     * Returns a reference to the underlying data array.
+     * <p>
+     * Does <strong>not</strong> make a fresh copy of the underlying data.</p>
+     *
+     * @return 2-dimensional array of entries
+     */
+    public double[][] getDataRef() {
+        return data;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
+    throws MatrixIndexException {
+        if (data == null) {
+            if (row > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                        LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET,
+                        row);
+            }
+            if (column > 0) {
+                throw MathRuntimeException.createIllegalStateException(
+                        LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET,
+                        column);
+            }
+            final int nRows = subMatrix.length;
+            if (nRows == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_ROW);
+            }
+
+            final int nCols = subMatrix[0].length;
+            if (nCols == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
+            }
+            data = new double[subMatrix.length][nCols];
+            for (int i = 0; i < data.length; ++i) {
+                if (subMatrix[i].length != nCols) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                            nCols, subMatrix[i].length);
+                }
+                System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
+            }
+        } else {
+            super.setSubMatrix(subMatrix, row, column);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double getEntry(final int row, final int column)
+        throws MatrixIndexException {
+        try {
+            return data[row][column];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(final int row, final int column, final double value)
+        throws MatrixIndexException {
+        try {
+            data[row][column] = value;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(final int row, final int column, final double increment)
+        throws MatrixIndexException {
+        try {
+            data[row][column] += increment;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(final int row, final int column, final double factor)
+        throws MatrixIndexException {
+        try {
+            data[row][column] *= factor;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new MatrixIndexException(
+                    LocalizedFormats.NO_SUCH_MATRIX_ENTRY,
+                    row, column, getRowDimension(), getColumnDimension());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return (data == null) ? 0 : data.length;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] operate(final double[] v)
+        throws IllegalArgumentException {
+        final int nRows = this.getRowDimension();
+        final int nCols = this.getColumnDimension();
+        if (v.length != nCols) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nCols);
+        }
+        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[i];
+            }
+            out[row] = sum;
+        }
+        return out;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double[] preMultiply(final double[] v)
+        throws IllegalArgumentException {
+
+        final int nRows = getRowDimension();
+        final int nCols = getColumnDimension();
+        if (v.length != nRows) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    v.length, nRows);
+        }
+
+        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[i];
+            }
+            out[col] = sum;
+        }
+
+        return out;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int i = 0; i < rows; ++i) {
+            final double[] rowI = data[i];
+            for (int j = 0; j < columns; ++j) {
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int i = 0; i < rows; ++i) {
+            final double[] rowI = data[i];
+            for (int j = 0; j < columns; ++j) {
+                visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int i = startRow; i <= endRow; ++i) {
+            final double[] rowI = data[i];
+            for (int j = startColumn; j <= endColumn; ++j) {
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
+                                 final int startRow, final int endRow,
+                                 final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int i = startRow; i <= endRow; ++i) {
+            final double[] rowI = data[i];
+            for (int j = startColumn; j <= endColumn; ++j) {
+                visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixChangingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int j = 0; j < columns; ++j) {
+            for (int i = 0; i < rows; ++i) {
+                final double[] rowI = data[i];
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor)
+        throws MatrixVisitorException {
+        final int rows    = getRowDimension();
+        final int columns = getColumnDimension();
+        visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
+        for (int j = 0; j < columns; ++j) {
+            for (int i = 0; i < rows; ++i) {
+                visitor.visit(i, j, data[i][j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixChangingVisitor visitor,
+                                    final int startRow, final int endRow,
+                                    final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int j = startColumn; j <= endColumn; ++j) {
+            for (int i = startRow; i <= endRow; ++i) {
+                final double[] rowI = data[i];
+                rowI[j] = visitor.visit(i, j, rowI[j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor,
+                                    final int startRow, final int endRow,
+                                    final int startColumn, final int endColumn)
+        throws MatrixIndexException, MatrixVisitorException {
+        MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
+        visitor.start(getRowDimension(), getColumnDimension(),
+                      startRow, endRow, startColumn, endColumn);
+        for (int j = startColumn; j <= endColumn; ++j) {
+            for (int i = startRow; i <= endRow; ++i) {
+                visitor.visit(i, j, data[i][j]);
+            }
+        }
+        return visitor.end();
+    }
+
+    /**
+     * Returns a fresh copy of the underlying data array.
+     *
+     * @return a copy of the underlying data array.
+     */
+    private double[][] copyOut() {
+        final int nRows = this.getRowDimension();
+        final double[][] out = new double[nRows][this.getColumnDimension()];
+        // can't copy 2-d array in one shot, otherwise get row references
+        for (int i = 0; i < nRows; i++) {
+            System.arraycopy(data[i], 0, out[i], 0, data[i].length);
+        }
+        return out;
+    }
+
+    /**
+     * Replaces data with a fresh copy of the input array.
+     * <p>
+     * Verifies that the input array is rectangular and non-empty.</p>
+     *
+     * @param in data to copy in
+     * @throws IllegalArgumentException if input array is empty or not
+     *    rectangular
+     * @throws NullPointerException if input array is null
+     */
+    private void copyIn(final double[][] in) {
+        setSubMatrix(in, 0, 0);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/RealMatrixPreservingVisitor.java b/src/main/java/org/apache/commons/math/linear/RealMatrixPreservingVisitor.java
new file mode 100644
index 0000000..2186b79
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/RealMatrixPreservingVisitor.java
@@ -0,0 +1,61 @@
+/*
+ * 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 org.apache.commons.math.linear.MatrixVisitorException;
+
+/**
+ * Interface defining a visitor for matrix entries.
+ *
+ * @see DefaultRealMatrixPreservingVisitor
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface RealMatrixPreservingVisitor {
+
+    /**
+     * Start visiting a matrix.
+     * <p>This method is called once before any entry of the matrix is visited.</p>
+     * @param rows number of rows of the matrix
+     * @param columns number of columns of the matrix
+     * @param startRow Initial row index
+     * @param endRow Final row index (inclusive)
+     * @param startColumn Initial column index
+     * @param endColumn Final column index (inclusive)
+     */
+    void start(int rows, int columns,
+               int startRow, int endRow, int startColumn, int endColumn);
+
+    /**
+     * Visit one matrix entry.
+     * @param row row index of the entry
+     * @param column column index of the entry
+     * @param value current value of the entry
+     * @throws MatrixVisitorException if something wrong occurs
+     */
+    void visit(int row, int column, double value)
+        throws MatrixVisitorException;
+
+    /**
+     * End visiting a matrix.
+     * <p>This method is called once after all entries of the matrix have been visited.</p>
+     * @return the value that the <code>walkInXxxOrder</code> must return
+     */
+    double end();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/RealVector.java b/src/main/java/org/apache/commons/math/linear/RealVector.java
new file mode 100644
index 0000000..0d7982b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/RealVector.java
@@ -0,0 +1,1005 @@
+/*
+ * 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.Iterator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+
+/**
+ * Interface defining a real-valued vector with basic algebraic operations.
+ * <p>
+ * vector element indexing is 0-based -- e.g., <code>getEntry(0)</code>
+ * returns the first element of the vector.
+ * </p>
+ * <p>
+ * The various <code>mapXxx</code> and <code>mapXxxToSelf</code> 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 <code>mapXxx</code>
+ * versions create a new vector to hold the result and do not change the instance.
+ * The <code>mapXxxToSelf</code> 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 <i>fluent API</i>
+ * style, like this:
+ * </p>
+ * <pre>
+ *   RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
+ * </pre>
+ * <p>
+ *  Remark on the deprecated {@code mapXxx} and {@code mapXxxToSelf} methods: In
+ *  Commons-Math v3.0, the same functionality will be achieved by directly using the
+ *  {@link #map(UnivariateRealFunction)} and {@link #mapToSelf(UnivariateRealFunction)}
+ *  together with new function objects (not available in v2.2).
+ * </p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public interface RealVector {
+    /**
+     * Acts as if it is implemented as:
+     * <pre>
+     *  Entry e = null;
+     *  for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) {
+     *      e.setValue(function.value(e.getValue()));
+     *  }
+     * </pre>
+     *
+     * @param function Function to apply to each entry.
+     * @return this vector.
+     * @throws FunctionEvaluationException if the function throws it.
+     */
+    RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException;
+
+    /**
+     * Acts as if implemented as:
+     * <pre>
+     *  return copy().map(function);
+     * </pre>
+     *
+     * @param function Function to apply to each entry.
+     * @return a new vector.
+     * @throws FunctionEvaluationException if the function throws it.
+     */
+    RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException;
+
+    /** Class representing a modifiable entry in the vector. */
+    public abstract class Entry {
+        /** Index of the entry. */
+        private int index;
+
+        /**
+         * Get the value of the entry.
+         *
+         * @return the value of the entry.
+         */
+        public abstract double getValue();
+        /**
+         * Set the value of the entry.
+         *
+         * @param value New value for the entry.
+         */
+        public abstract void setValue(double value);
+        /**
+         * Get the index of the entry.
+         *
+         * @return the index of the entry.
+         */
+        public int getIndex() {
+            return index;
+        }
+        /**
+         * Set the index of the entry.
+         *
+         * @param index New index for the entry.
+         */
+        public void setIndex(int index) {
+            this.index = index;
+        }
+    }
+
+    /**
+     * Generic dense iterator.
+     * It iterates in increasing order of the vector index.
+     *
+     * @return a dense iterator
+     */
+    Iterator<Entry> iterator();
+
+    /**
+     * Specialized implementations may choose to not iterate over all
+     * dimensions, either because those values are unset, or are equal
+     * to defaultValue(), or are small enough to be ignored for the
+     * purposes of iteration.
+     * No guarantees are made about order of iteration.
+     * In dense implementations, this method will often delegate to
+     * {@link #iterator()}.
+     *
+     * @return a sparse iterator
+     */
+    Iterator<Entry> sparseIterator();
+
+    /**
+     * Returns a (deep) copy of this vector.
+     *
+     * @return a vector copy.
+     */
+    RealVector copy();
+
+    /**
+     * Compute the sum of this vector and {@code v}.
+     *
+     * @param v Vector to be added.
+     * @return {@code this} + {@code v}.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector add(RealVector v);
+
+    /**
+     * Compute the sum of this vector and {@code v}.
+     *
+     * @param v Vector to be added.
+     * @return {@code this} + {@code v}.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector add(double[] v);
+
+
+    /**
+     * Subtract {@code v} from this vector.
+     *
+     * @param v Vector to be subtracted.
+     * @return {@code this} - {@code v}.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector subtract(RealVector v);
+
+    /**
+     * Subtract {@code v} from this vector.
+     *
+     * @param v Vector to be subtracted.
+     * @return {@code this} - {@code v}.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector subtract(double[] v);
+
+    /**
+     * Add a value to each entry.
+     *
+     * @param d Value to be added to each entry.
+     * @return {@code this} + {@code d}.
+     */
+    RealVector mapAdd(double d);
+
+    /**
+     * Add a value to each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Value to be added to each entry.
+     * @return {@code this}.
+     */
+    RealVector mapAddToSelf(double d);
+
+    /**
+     * Subtract a value from each entry.
+     *
+     * @param d Value to be subtracted.
+     * @return {@code this} - {@code d}.
+     */
+    RealVector mapSubtract(double d);
+
+    /**
+     * Subtract a value from each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Value to be subtracted.
+     * @return {@code this}.
+     */
+    RealVector mapSubtractToSelf(double d);
+
+    /**
+     * Multiply each entry.
+     *
+     * @param d Multiplication factor.
+     * @return {@code this} * {@code d}.
+     */
+    RealVector mapMultiply(double d);
+
+    /**
+     * Multiply each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Multiplication factor.
+     * @return {@code this}.
+     */
+    RealVector mapMultiplyToSelf(double d);
+
+    /**
+     * Divide each entry.
+     *
+     * @param d Value to divide by.
+     * @return {@code this} / {@code d}.
+     */
+    RealVector mapDivide(double d);
+
+    /**
+     * Divide each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Value to divide by.
+     * @return {@code this}.
+     */
+    RealVector mapDivideToSelf(double d);
+
+    /**
+     * Map a power operation to each entry.
+     *
+     * @param d Operator value.
+     * @return a mapped copy of the vector.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapPow(double d);
+
+    /**
+     * Map a power operation to each entry.
+     * The instance is changed in-place.
+     *
+     * @param d Operator value.
+     * @return the mapped vector.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapPowToSelf(double d);
+
+    /**
+     * Map the {@link Math#exp(double)} function to each entry.
+     *
+     * @return a mapped copy of the vector.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapExp();
+
+    /**
+     * Map {@link Math#exp(double)} operation to each entry.
+     * The instance is changed in-place.
+     *
+     * @return the mapped vector.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapExpm1();
+
+    /**
+     * Map the {@link Math#expm1(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapLog();
+
+    /**
+     * Map the {@link Math#log(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapLog10();
+
+    /**
+     * Map the {@link Math#log10(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapLog1p();
+
+    /**
+     * Map the {@link Math#log1p(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapCosh();
+
+    /**
+     * Map the {@link Math#cosh(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapSinh();
+
+    /**
+     * Map the {@link Math#sinh(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapTanh();
+
+    /**
+     * Map the {@link Math#tanh(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapCos();
+
+    /**
+     * Map the {@link Math#cos(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapSin();
+
+    /**
+     * Map the {@link Math#sin(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapTan();
+
+    /**
+     * Map the {@link Math#tan(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapAcos();
+
+    /**
+     * Map the {@link Math#acos(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapAsin();
+
+    /**
+     * Map the {@link Math#asin(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapAtan();
+
+    /**
+     * Map the {@link Math#atan(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapAtanToSelf();
+
+    /**
+     * Map the 1/x function to each entry.
+     * @return a vector containing the result of applying the function to each entry
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapInv();
+
+    /**
+     * Map the 1/x function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapAbs();
+
+    /**
+     * Map the {@link Math#abs(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapSqrt();
+
+    /**
+     * Map the {@link Math#sqrt(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapCbrt();
+
+    /**
+     * Map the {@link Math#cbrt(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapCeil();
+
+    /**
+     * Map the {@link Math#ceil(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapFloor();
+
+    /**
+     * Map the {@link Math#floor(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapRint();
+
+    /**
+     * Map the {@link Math#rint(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapSignum();
+
+    /**
+     * Map the {@link Math#signum(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    RealVector mapUlp();
+
+    /**
+     * Map the {@link Math#ulp(double)} function to each entry.
+     * <p>The instance <strong>is</strong> changed by this method.</p>
+     * @return for convenience, return this
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    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 org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector ebeMultiply(RealVector v);
+
+    /**
+     * 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 org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector ebeMultiply(double[] v);
+
+    /**
+     * 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 org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector ebeDivide(RealVector v);
+
+    /**
+     * 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 org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector ebeDivide(double[] v);
+
+    /**
+     * 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
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    double dotProduct(RealVector v);
+
+    /**
+     * Compute the dot product.
+     * @param v vector with which dot product should be computed
+     * @return the scalar dot product between instance and v
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    double dotProduct(double[] v);
+
+    /**
+     * Returns the L<sub>2</sub> norm of the vector.
+     * <p>The L<sub>2</sub> norm is the root of the sum of
+     * the squared elements.</p>
+     * @return norm
+     * @see #getL1Norm()
+     * @see #getLInfNorm()
+     * @see #getDistance(RealVector)
+     */
+    double getNorm();
+
+    /**
+     * Returns the L<sub>1</sub> norm of the vector.
+     * <p>The L<sub>1</sub> norm is the sum of the absolute
+     * values of elements.</p>
+     * @return norm
+     * @see #getNorm()
+     * @see #getLInfNorm()
+     * @see #getL1Distance(RealVector)
+     */
+    double getL1Norm();
+
+    /**
+     * Returns the L<sub>&infin;</sub> norm of the vector.
+     * <p>The L<sub>&infin;</sub> norm is the max of the absolute
+     * values of elements.</p>
+     * @return norm
+     * @see #getNorm()
+     * @see #getL1Norm()
+     * @see #getLInfDistance(RealVector)
+     */
+    double getLInfNorm();
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with the
+     * L<sub>2</sub> norm, i.e. the square root of the sum of
+     * elements differences, or euclidian distance.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     * @see #getL1Distance(RealVector)
+     * @see #getLInfDistance(RealVector)
+     * @see #getNorm()
+     */
+    double getDistance(RealVector v);
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with the
+     * L<sub>2</sub> norm, i.e. the square root of the sum of
+     * elements differences, or euclidian distance.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     * @see #getL1Distance(double[])
+     * @see #getLInfDistance(double[])
+     * @see #getNorm()
+     */
+    double getDistance(double[] v);
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>1</sub> norm, i.e. the sum of the absolute values of
+     * elements differences.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     * @see #getDistance(RealVector)
+     * @see #getLInfDistance(RealVector)
+     * @see #getL1Norm()
+     */
+    double getL1Distance(RealVector v);
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>1</sub> norm, i.e. the sum of the absolute values of
+     * elements differences.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     * @see #getDistance(double[])
+     * @see #getLInfDistance(double[])
+     * @see #getL1Norm()
+     */
+    double getL1Distance(double[] v);
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>&infin;</sub> norm, i.e. the max of the absolute values of
+     * elements differences.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     * @see #getDistance(RealVector)
+     * @see #getL1Distance(RealVector)
+     * @see #getLInfNorm()
+     */
+    double getLInfDistance(RealVector v);
+
+    /**
+     * Distance between two vectors.
+     * <p>This method computes the distance consistent with
+     * L<sub>&infin;</sub> norm, i.e. the max of the absolute values of
+     * elements differences.</p>
+     * @param v vector to which distance is requested
+     * @return distance between two vectors.
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     * @see #getDistance(double[])
+     * @see #getL1Distance(double[])
+     * @see #getLInfNorm()
+     */
+    double getLInfDistance(double[] v);
+
+    /** Creates a unit vector pointing in the direction of this vector.
+     * <p>The instance is not changed by this method.</p>
+     * @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.
+     * <p>The instance itself is changed by this method.</p>
+     * @throws ArithmeticException
+     * if the norm is zero.
+     */
+    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 org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector projection(RealVector 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 org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealVector projection(double[] v);
+
+    /**
+     * Compute the outer product.
+     * @param v vector with which outer product should be computed
+     * @return the square matrix outer product between instance and v
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealMatrix outerProduct(RealVector v);
+
+    /**
+     * Compute the outer product.
+     * @param v vector with which outer product should be computed
+     * @return the square matrix outer product between instance and v
+     * @throws org.apache.commons.math.exception.DimensionMismatchException
+     * if {@code v} is not the same size as this vector.
+     */
+    RealMatrix outerProduct(double[] v);
+
+    /**
+     * Returns the entry in the specified index.
+     *
+     * @param index Index location of entry to be fetched.
+     * @return the vector entry at {@code index}.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #setEntry(int, double)
+     */
+    double getEntry(int index);
+
+    /**
+     * Set a single element.
+     * @param index element index.
+     * @param value new value for the element.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #getEntry(int)
+     */
+    void setEntry(int index, double value);
+
+    /**
+     * 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.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     */
+    RealVector getSubVector(int index, int n);
+
+    /**
+     * Set a set of consecutive elements.
+     * @param index index of first element to be set.
+     * @param v vector containing the values to set.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #setSubVector(int, double[])
+     */
+    void setSubVector(int index, RealVector v);
+
+    /**
+     * Set a set of consecutive elements.
+     * @param index index of first element to be set.
+     * @param v vector containing the values to set.
+     * @throws org.apache.commons.math.exception.OutOfRangeException
+     * if the index is not valid.
+     * @see #setSubVector(int, RealVector)
+     */
+    void setSubVector(int index, double[] v);
+
+    /**
+     * 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.
+     * <p>The array is independent from vector data, it's elements
+     * are copied.</p>
+     * @return array containing a copy of vector elements
+     */
+    double[] toArray();
+
+    /**
+     * Check whether any coordinate of this vector is {@code NaN}.
+     * @return {@code true} if any coordinate of this vector is {@code NaN},
+     * {@code false} otherwise.
+     */
+    boolean isNaN();
+
+    /**
+     * Check whether any coordinate of this vector is infinite and none are {@code NaN}.
+     *
+     * @return {@code true} if any coordinate of this vector is infinite and
+     * none are {@code NaN}, {@code false} otherwise.
+     */
+    boolean isInfinite();
+}
diff --git a/src/main/java/org/apache/commons/math/linear/RealVectorFormat.java b/src/main/java/org/apache/commons/math/linear/RealVectorFormat.java
new file mode 100644
index 0000000..ecefba2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/RealVectorFormat.java
@@ -0,0 +1,341 @@
+/*
+ * 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.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.CompositeFormat;
+
+/**
+ * Formats a vector in components list format "{v0; v1; ...; vk-1}".
+ * <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by
+ * any user-defined strings. The number format for components can be configured.</p>
+ * <p>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.</p>
+ *
+ * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $
+ * @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 final NumberFormat format;
+
+    /**
+     * Create an instance with default settings.
+     * <p>The instance uses the default prefix, suffix and separator:
+     * "{", "}", and "; " and the default number format for components.</p>
+     */
+    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.
+     * <p>This is the same set as the {@link NumberFormat} set.</p>
+     * @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.
+     * <p><code>obj</code> must be a  {@link RealVector} object. Any other type of
+     * object will result in an {@link IllegalArgumentException} being thrown.</p>
+     * @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 <code>obj</code> is not a valid type.
+     */
+    @Override
+    public StringBuffer format(Object obj, StringBuffer toAppendTo,
+                               FieldPosition pos) {
+
+        if (obj instanceof RealVector) {
+            return format( (RealVector)obj, toAppendTo, pos);
+        }
+
+        throw MathRuntimeException.createIllegalArgumentException(
+              LocalizedFormats.CANNOT_FORMAT_INSTANCE_AS_REAL_VECTOR,
+              obj.getClass().getName());
+
+    }
+
+    /**
+     * 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 ArrayRealVector parse(String source) throws ParseException {
+        ParsePosition parsePosition = new ParsePosition(0);
+        ArrayRealVector result = parse(source, parsePosition);
+        if (parsePosition.getIndex() == 0) {
+            throw MathRuntimeException.createParseException(
+                    parsePosition.getErrorIndex(),
+                    LocalizedFormats.UNPARSEABLE_REAL_VECTOR, source);
+        }
+        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 ArrayRealVector parse(String source, ParsePosition pos) {
+        int initialIndex = pos.getIndex();
+
+        // parse prefix
+        parseAndIgnoreWhitespace(source, pos);
+        if (!parseFixedstring(source, trimmedPrefix, pos)) {
+            return null;
+        }
+
+        // parse components
+        List<Number> components = new ArrayList<Number>();
+        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 ArrayRealVector(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)
+     */
+    @Override
+    public Object parseObject(String source, ParsePosition pos) {
+        return parse(source, pos);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SingularMatrixException.java b/src/main/java/org/apache/commons/math/linear/SingularMatrixException.java
new file mode 100644
index 0000000..a14cf69
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SingularMatrixException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 org.apache.commons.math.exception.util.LocalizedFormats;
+
+
+/**
+ * Thrown when a matrix is singular.
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class SingularMatrixException extends InvalidMatrixException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -7379143356784298432L;
+
+    /**
+     * Construct an exception with a default message.
+     */
+    public SingularMatrixException() {
+        super(LocalizedFormats.SINGULAR_MATRIX);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SingularValueDecomposition.java b/src/main/java/org/apache/commons/math/linear/SingularValueDecomposition.java
new file mode 100644
index 0000000..5b45cde
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SingularValueDecomposition.java
@@ -0,0 +1,147 @@
+/*
+ * 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;
+
+
+
+/**
+ * An interface to classes that implement an algorithm to calculate the
+ * Singular Value Decomposition of a real matrix.
+ * <p>
+ * The Singular Value Decomposition of matrix A is a set of three matrices: U,
+ * &Sigma; and V such that A = U &times; &Sigma; &times; V<sup>T</sup>. Let A be
+ * a m &times; n matrix, then U is a m &times; p orthogonal matrix, &Sigma; is a
+ * p &times; p diagonal matrix with positive or null elements, V is a p &times;
+ * n orthogonal matrix (hence V<sup>T</sup> is also orthogonal) where
+ * p=min(m,n).
+ * </p>
+ * <p>This interface is similar to the class with similar name from the
+ * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the
+ * following changes:</p>
+ * <ul>
+ *   <li>the <code>norm2</code> method which has been renamed as {@link #getNorm()
+ *   getNorm},</li>
+ *   <li>the <code>cond</code> method which has been renamed as {@link
+ *   #getConditionNumber() getConditionNumber},</li>
+ *   <li>the <code>rank</code> method which has been renamed as {@link #getRank()
+ *   getRank},</li>
+ *   <li>a {@link #getUT() getUT} method has been added,</li>
+ *   <li>a {@link #getVT() getVT} method has been added,</li>
+ *   <li>a {@link #getSolver() getSolver} method has been added,</li>
+ *   <li>a {@link #getCovariance(double) getCovariance} method has been added.</li>
+ * </ul>
+ * @see <a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">MathWorld</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">Wikipedia</a>
+ * @version $Revision: 928081 $ $Date: 2010-03-26 23:36:38 +0100 (ven. 26 mars 2010) $
+ * @since 2.0
+ */
+public interface SingularValueDecomposition {
+
+    /**
+     * Returns the matrix U of the decomposition.
+     * <p>U is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the U matrix
+     * @see #getUT()
+     */
+    RealMatrix getU();
+
+    /**
+     * Returns the transpose of the matrix U of the decomposition.
+     * <p>U is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the U matrix (or null if decomposed matrix is singular)
+     * @see #getU()
+     */
+    RealMatrix getUT();
+
+    /**
+     * Returns the diagonal matrix &Sigma; of the decomposition.
+     * <p>&Sigma; is a diagonal matrix. The singular values are provided in
+     * non-increasing order, for compatibility with Jama.</p>
+     * @return the &Sigma; matrix
+     */
+    RealMatrix getS();
+
+    /**
+     * Returns the diagonal elements of the matrix &Sigma; of the decomposition.
+     * <p>The singular values are provided in non-increasing order, for
+     * compatibility with Jama.</p>
+     * @return the diagonal elements of the &Sigma; matrix
+     */
+    double[] getSingularValues();
+
+    /**
+     * Returns the matrix V of the decomposition.
+     * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the V matrix (or null if decomposed matrix is singular)
+     * @see #getVT()
+     */
+    RealMatrix getV();
+
+    /**
+     * Returns the transpose of the matrix V of the decomposition.
+     * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the V matrix (or null if decomposed matrix is singular)
+     * @see #getV()
+     */
+    RealMatrix getVT();
+
+    /**
+     * Returns the n &times; n covariance matrix.
+     * <p>The covariance matrix is V &times; J &times; V<sup>T</sup>
+     * where J is the diagonal matrix of the inverse of the squares of
+     * the singular values.</p>
+     * @param minSingularValue value below which singular values are ignored
+     * (a 0 or negative value implies all singular value will be used)
+     * @return covariance matrix
+     * @exception IllegalArgumentException if minSingularValue is larger than
+     * the largest singular value, meaning all singular values are ignored
+     */
+    RealMatrix getCovariance(double minSingularValue) throws IllegalArgumentException;
+
+    /**
+     * Returns the L<sub>2</sub> norm of the matrix.
+     * <p>The L<sub>2</sub> norm is max(|A &times; u|<sub>2</sub> /
+     * |u|<sub>2</sub>), where |.|<sub>2</sub> denotes the vectorial 2-norm
+     * (i.e. the traditional euclidian norm).</p>
+     * @return norm
+     */
+    double getNorm();
+
+    /**
+     * Return the condition number of the matrix.
+     * @return condition number of the matrix
+     */
+    double getConditionNumber();
+
+    /**
+     * Return the effective numerical matrix rank.
+     * <p>The effective numerical rank is the number of non-negligible
+     * singular values. The threshold used to identify non-negligible
+     * terms is max(m,n) &times; ulp(s<sub>1</sub>) where ulp(s<sub>1</sub>)
+     * is the least significant bit of the largest singular value.</p>
+     * @return effective numerical matrix rank
+     */
+    int getRank();
+
+    /**
+     * Get a solver for finding the A &times; X = B solution in least square sense.
+     * @return a solver
+     */
+    DecompositionSolver getSolver();
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java b/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java
new file mode 100644
index 0000000..d776b66
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SingularValueDecompositionImpl.java
@@ -0,0 +1,379 @@
+/*
+ * 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 org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Calculates the compact Singular Value Decomposition of a matrix.
+ * <p>
+ * The Singular Value Decomposition of matrix A is a set of three matrices: U,
+ * &Sigma; and V such that A = U &times; &Sigma; &times; V<sup>T</sup>. Let A be
+ * a m &times; n matrix, then U is a m &times; p orthogonal matrix, &Sigma; is a
+ * p &times; p diagonal matrix with positive or null elements, V is a p &times;
+ * n orthogonal matrix (hence V<sup>T</sup> is also orthogonal) where
+ * p=min(m,n).
+ * </p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class SingularValueDecompositionImpl implements
+        SingularValueDecomposition {
+
+    /** Number of rows of the initial matrix. */
+    private int m;
+
+    /** Number of columns of the initial matrix. */
+    private int n;
+
+    /** Eigen decomposition of the tridiagonal matrix. */
+    private EigenDecomposition eigenDecomposition;
+
+    /** Singular values. */
+    private double[] singularValues;
+
+    /** Cached value of U. */
+    private RealMatrix cachedU;
+
+    /** Cached value of U<sup>T</sup>. */
+    private RealMatrix cachedUt;
+
+    /** Cached value of S. */
+    private RealMatrix cachedS;
+
+    /** Cached value of V. */
+    private RealMatrix cachedV;
+
+    /** Cached value of V<sup>T</sup>. */
+    private RealMatrix cachedVt;
+
+    /**
+     * Calculates the compact Singular Value Decomposition of the given matrix.
+     * @param matrix
+     *            The matrix to decompose.
+     * @exception InvalidMatrixException
+     *                (wrapping a
+     *                {@link org.apache.commons.math.ConvergenceException} if
+     *                algorithm fails to converge
+     */
+    public SingularValueDecompositionImpl(final RealMatrix matrix)
+            throws InvalidMatrixException {
+
+        m = matrix.getRowDimension();
+        n = matrix.getColumnDimension();
+
+        cachedU = null;
+        cachedS = null;
+        cachedV = null;
+        cachedVt = null;
+
+        double[][] localcopy = matrix.getData();
+        double[][] matATA = new double[n][n];
+        //
+        // create A^T*A
+        //
+        for (int i = 0; i < n; i++) {
+            for (int j = i; j < n; j++) {
+                matATA[i][j] = 0.0;
+                for (int k = 0; k < m; k++) {
+                    matATA[i][j] += localcopy[k][i] * localcopy[k][j];
+                }
+                matATA[j][i]=matATA[i][j];
+            }
+        }
+
+        double[][] matAAT = new double[m][m];
+        //
+        // create A*A^T
+        //
+        for (int i = 0; i < m; i++) {
+            for (int j = i; j < m; j++) {
+                matAAT[i][j] = 0.0;
+                for (int k = 0; k < n; k++) {
+                    matAAT[i][j] += localcopy[i][k] * localcopy[j][k];
+                }
+                 matAAT[j][i]=matAAT[i][j];
+            }
+        }
+        int p;
+        if (m>=n) {
+            p=n;
+            // compute eigen decomposition of A^T*A
+            eigenDecomposition = new EigenDecompositionImpl(
+                    new Array2DRowRealMatrix(matATA),1.0);
+            singularValues = eigenDecomposition.getRealEigenvalues();
+            cachedV = eigenDecomposition.getV();
+            // compute eigen decomposition of A*A^T
+            eigenDecomposition = new EigenDecompositionImpl(
+                    new Array2DRowRealMatrix(matAAT),1.0);
+            cachedU = eigenDecomposition.getV().getSubMatrix(0, m - 1, 0, p - 1);
+        } else {
+            p=m;
+            // compute eigen decomposition of A*A^T
+            eigenDecomposition = new EigenDecompositionImpl(
+                    new Array2DRowRealMatrix(matAAT),1.0);
+            singularValues = eigenDecomposition.getRealEigenvalues();
+            cachedU = eigenDecomposition.getV();
+
+            // compute eigen decomposition of A^T*A
+            eigenDecomposition = new EigenDecompositionImpl(
+                    new Array2DRowRealMatrix(matATA),1.0);
+            cachedV = eigenDecomposition.getV().getSubMatrix(0,n-1,0,p-1);
+        }
+        for (int i = 0; i < p; i++) {
+            singularValues[i] = FastMath.sqrt(FastMath.abs(singularValues[i]));
+        }
+        // Up to this point, U and V are computed independently of each other.
+        // There still a sign indetermination of each column of, say, U.
+        // The sign is set such that A.V_i=sigma_i.U_i (i<=p)
+        // The right sign corresponds to a positive dot product of A.V_i and U_i
+        for (int i = 0; i < p; i++) {
+          RealVector tmp = cachedU.getColumnVector(i);
+          double product=matrix.operate(cachedV.getColumnVector(i)).dotProduct(tmp);
+          if (product<0) {
+            cachedU.setColumnVector(i, tmp.mapMultiply(-1.0));
+          }
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getU() throws InvalidMatrixException {
+        // return the cached matrix
+        return cachedU;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getUT() throws InvalidMatrixException {
+
+        if (cachedUt == null) {
+            cachedUt = getU().transpose();
+        }
+
+        // return the cached matrix
+        return cachedUt;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getS() throws InvalidMatrixException {
+
+        if (cachedS == null) {
+
+            // cache the matrix for subsequent calls
+            cachedS = MatrixUtils.createRealDiagonalMatrix(singularValues);
+
+        }
+        return cachedS;
+    }
+
+    /** {@inheritDoc} */
+    public double[] getSingularValues() throws InvalidMatrixException {
+        return singularValues.clone();
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getV() throws InvalidMatrixException {
+        // return the cached matrix
+        return cachedV;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getVT() throws InvalidMatrixException {
+
+        if (cachedVt == null) {
+            cachedVt = getV().transpose();
+        }
+
+        // return the cached matrix
+        return cachedVt;
+
+    }
+
+    /** {@inheritDoc} */
+    public RealMatrix getCovariance(final double minSingularValue) {
+
+        // get the number of singular values to consider
+        final int p = singularValues.length;
+        int dimension = 0;
+        while ((dimension < p) && (singularValues[dimension] >= minSingularValue)) {
+            ++dimension;
+        }
+
+        if (dimension == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.TOO_LARGE_CUTOFF_SINGULAR_VALUE,
+                    minSingularValue, singularValues[0]);
+        }
+
+        final double[][] data = new double[dimension][p];
+        getVT().walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
+            /** {@inheritDoc} */
+            @Override
+            public void visit(final int row, final int column,
+                    final double value) {
+                data[row][column] = value / singularValues[row];
+            }
+        }, 0, dimension - 1, 0, p - 1);
+
+        RealMatrix jv = new Array2DRowRealMatrix(data, false);
+        return jv.transpose().multiply(jv);
+
+    }
+
+    /** {@inheritDoc} */
+    public double getNorm() throws InvalidMatrixException {
+        return singularValues[0];
+    }
+
+    /** {@inheritDoc} */
+    public double getConditionNumber() throws InvalidMatrixException {
+        return singularValues[0] / singularValues[singularValues.length - 1];
+    }
+
+    /** {@inheritDoc} */
+    public int getRank() throws IllegalStateException {
+
+        final double threshold = FastMath.max(m, n) * FastMath.ulp(singularValues[0]);
+
+        for (int i = singularValues.length - 1; i >= 0; --i) {
+            if (singularValues[i] > threshold) {
+                return i + 1;
+            }
+        }
+        return 0;
+
+    }
+
+    /** {@inheritDoc} */
+    public DecompositionSolver getSolver() {
+        return new Solver(singularValues, getUT(), getV(), getRank() == Math
+                .max(m, n));
+    }
+
+    /** Specialized solver. */
+    private static class Solver implements DecompositionSolver {
+
+        /** Pseudo-inverse of the initial matrix. */
+        private final RealMatrix pseudoInverse;
+
+        /** Singularity indicator. */
+        private boolean nonSingular;
+
+        /**
+         * Build a solver from decomposed matrix.
+         * @param singularValues
+         *            singularValues
+         * @param uT
+         *            U<sup>T</sup> matrix of the decomposition
+         * @param v
+         *            V matrix of the decomposition
+         * @param nonSingular
+         *            singularity indicator
+         */
+        private Solver(final double[] singularValues, final RealMatrix uT,
+                final RealMatrix v, final boolean nonSingular) {
+            double[][] suT = uT.getData();
+            for (int i = 0; i < singularValues.length; ++i) {
+                final double a;
+                if (singularValues[i]>0) {
+                 a=1.0 / singularValues[i];
+                } else {
+                 a=0.0;
+                }
+                final double[] suTi = suT[i];
+                for (int j = 0; j < suTi.length; ++j) {
+                    suTi[j] *= a;
+                }
+            }
+            pseudoInverse = v.multiply(new Array2DRowRealMatrix(suT, false));
+            this.nonSingular = nonSingular;
+        }
+
+        /**
+         * Solve the linear equation A &times; X = B in least square sense.
+         * <p>
+         * The m&times;n matrix A may not be square, the solution X is such that
+         * ||A &times; X - B|| is minimal.
+         * </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
+         */
+        public double[] solve(final double[] b) throws IllegalArgumentException {
+            return pseudoInverse.operate(b);
+        }
+
+        /**
+         * Solve the linear equation A &times; X = B in least square sense.
+         * <p>
+         * The m&times;n matrix A may not be square, the solution X is such that
+         * ||A &times; X - B|| is minimal.
+         * </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
+         */
+        public RealVector solve(final RealVector b)
+                throws IllegalArgumentException {
+            return pseudoInverse.operate(b);
+        }
+
+        /**
+         * Solve the linear equation A &times; X = B in least square sense.
+         * <p>
+         * The m&times;n matrix A may not be square, the solution X is such that
+         * ||A &times; X - B|| is minimal.
+         * </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
+         */
+        public RealMatrix solve(final RealMatrix b)
+                throws IllegalArgumentException {
+            return pseudoInverse.multiply(b);
+        }
+
+        /**
+         * Check if the decomposed matrix is non-singular.
+         * @return true if the decomposed matrix is non-singular
+         */
+        public boolean isNonSingular() {
+            return nonSingular;
+        }
+
+        /**
+         * Get the pseudo-inverse of the decomposed matrix.
+         * @return inverse matrix
+         */
+        public RealMatrix getInverse() {
+            return pseudoInverse;
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SparseFieldMatrix.java b/src/main/java/org/apache/commons/math/linear/SparseFieldMatrix.java
new file mode 100644
index 0000000..1fbfb5c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SparseFieldMatrix.java
@@ -0,0 +1,190 @@
+/*
+ * 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 org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.util.OpenIntToFieldHashMap;
+
+/**
+ * Sparse matrix implementation based on an open addressed map.
+ *
+ * @param <T> the type of the field elements
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public class SparseFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> {
+    /**
+     *  Serial id
+     */
+    private static final long serialVersionUID = 9078068119297757342L;
+    /** Storage for (sparse) matrix elements. */
+    private final OpenIntToFieldHashMap<T> entries;
+    /**
+     * row dimension
+     */
+    private final int rows;
+    /**
+     * column dimension
+     */
+    private final int columns;
+
+
+    /**
+     * Creates a matrix with no data.
+     * @param field field to which the elements belong
+     */
+    public SparseFieldMatrix(final Field<T> field) {
+        super(field);
+        rows = 0;
+        columns= 0;
+        entries = new OpenIntToFieldHashMap<T>(field);
+    }
+
+    /**
+     * Create a new SparseFieldMatrix<T> with the supplied row and column dimensions.
+     *
+     * @param field field to which the elements belong
+     * @param rowDimension  the number of rows in the new matrix
+     * @param columnDimension  the number of columns in the new matrix
+     * @throws IllegalArgumentException if row or column dimension is not positive
+     */
+    public SparseFieldMatrix(final Field<T> field,
+                             final int rowDimension, final int columnDimension)
+        throws IllegalArgumentException {
+        super(field, rowDimension, columnDimension);
+        this.rows = rowDimension;
+        this.columns = columnDimension;
+        entries = new OpenIntToFieldHashMap<T>(field);
+    }
+
+    /**
+     * Copy constructor.
+     * @param other The instance to copy
+     */
+    public SparseFieldMatrix(SparseFieldMatrix<T> other) {
+        super(other.getField(), other.getRowDimension(), other.getColumnDimension());
+        rows = other.getRowDimension();
+        columns = other.getColumnDimension();
+        entries = new OpenIntToFieldHashMap<T>(other.entries);
+    }
+
+    /**
+     * Generic copy constructor.
+     * @param other The instance to copy
+     */
+    public SparseFieldMatrix(FieldMatrix<T> other){
+        super(other.getField(), other.getRowDimension(), other.getColumnDimension());
+        rows = other.getRowDimension();
+        columns = other.getColumnDimension();
+        entries = new OpenIntToFieldHashMap<T>(getField());
+        for (int i = 0; i < rows; i++) {
+            for (int j = 0; j < columns; j++) {
+                setEntry(i, j, other.getEntry(i, j));
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void addToEntry(int row, int column, T increment)
+            throws MatrixIndexException {
+        checkRowIndex(row);
+        checkColumnIndex(column);
+        final int key = computeKey(row, column);
+        final T value = entries.get(key).add(increment);
+        if (getField().getZero().equals(value)) {
+            entries.remove(key);
+        } else {
+            entries.put(key, value);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> copy() {
+        return new SparseFieldMatrix<T>(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FieldMatrix<T> createMatrix(int rowDimension, int columnDimension)
+            throws IllegalArgumentException {
+        return new SparseFieldMatrix<T>(getField(), rowDimension, columnDimension);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getColumnDimension() {
+        return columns;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T getEntry(int row, int column) throws MatrixIndexException {
+        checkRowIndex(row);
+        checkColumnIndex(column);
+        return entries.get(computeKey(row, column));
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getRowDimension() {
+        return rows;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void multiplyEntry(int row, int column, T factor)
+            throws MatrixIndexException {
+        checkRowIndex(row);
+        checkColumnIndex(column);
+        final int key = computeKey(row, column);
+        final T value = entries.get(key).multiply(factor);
+        if (getField().getZero().equals(value)) {
+            entries.remove(key);
+        } else {
+            entries.put(key, value);
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setEntry(int row, int column, T value)
+            throws MatrixIndexException {
+        checkRowIndex(row);
+        checkColumnIndex(column);
+        if (getField().getZero().equals(value)) {
+            entries.remove(computeKey(row, column));
+        } else {
+            entries.put(computeKey(row, column), value);
+        }
+
+    }
+    /**
+     * Compute the key to access a matrix element
+     * @param row row index of the matrix element
+     * @param column column index of the matrix element
+     * @return key within the map to access the matrix element
+     */
+    private int computeKey(int row, int column) {
+        return row * columns + column;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SparseFieldVector.java b/src/main/java/org/apache/commons/math/linear/SparseFieldVector.java
new file mode 100644
index 0000000..7f4848c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SparseFieldVector.java
@@ -0,0 +1,657 @@
+/*
+ * 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.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.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.OpenIntToFieldHashMap;
+
+/**
+ * This class implements the {@link FieldVector} interface with a {@link OpenIntToFieldHashMap} backing store.
+ * @param <T> the type of the field elements
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class SparseFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable {
+
+    /**
+     *  Serial version id
+     */
+    private static final long serialVersionUID = 7841233292190413362L;
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+    /** Entries of the vector. */
+    private final OpenIntToFieldHashMap<T> entries;
+    /** Dimension of the vector. */
+    private final int virtualSize;
+
+    /**
+     * Build a 0-length vector.
+     * <p>Zero-length vectors may be used to initialize construction of vectors
+     * by data gathering. We start with zero-length and use either the {@link
+     * #SparseFieldVector(SparseFieldVector, int)} constructor
+     * or one of the <code>append</code> method ({@link #append(FieldElement)},
+     * {@link #append(FieldElement[])}, {@link #append(FieldVector)},
+     * {@link #append(SparseFieldVector)}) to gather data into this vector.</p>
+     * @param field field to which the elements belong
+     */
+    public SparseFieldVector(Field<T> field) {
+        this(field, 0);
+    }
+
+
+    /**
+     * Construct a (dimension)-length vector of zeros.
+     * @param field field to which the elements belong
+     * @param dimension Size of the vector
+     */
+    public SparseFieldVector(Field<T> field, int dimension) {
+        this.field = field;
+        virtualSize = dimension;
+        entries = new OpenIntToFieldHashMap<T>(field);
+    }
+
+    /**
+     * Build a resized vector, for use with append.
+     * @param v The original vector
+     * @param resize The amount to resize it
+     */
+    protected SparseFieldVector(SparseFieldVector<T> v, int resize) {
+        field = v.field;
+        virtualSize = v.getDimension() + resize;
+        entries = new OpenIntToFieldHashMap<T>(v.entries);
+    }
+
+
+    /**
+     * Build a vector with known the sparseness (for advanced use only).
+     * @param field field to which the elements belong
+     * @param dimension The size of the vector
+     * @param expectedSize The expected number of non-zero entries
+     */
+    public SparseFieldVector(Field<T> field, int dimension, int expectedSize) {
+        this.field = field;
+        virtualSize = dimension;
+        entries = new OpenIntToFieldHashMap<T>(field,expectedSize);
+    }
+
+    /**
+     * Create from a Field array.
+     * Only non-zero entries will be stored
+     * @param field field to which the elements belong
+     * @param values The set of values to create from
+     */
+    public SparseFieldVector(Field<T> field, T[] values) {
+        this.field = field;
+        virtualSize = values.length;
+        entries = new OpenIntToFieldHashMap<T>(field);
+        for (int key = 0; key < values.length; key++) {
+            T value = values[key];
+            entries.put(key, value);
+        }
+    }
+
+
+
+    /**
+     * Copy constructor.
+     * @param v The instance to copy from
+     */
+    public SparseFieldVector(SparseFieldVector<T> v) {
+        field = v.field;
+        virtualSize = v.getDimension();
+        entries = new OpenIntToFieldHashMap<T>(v.getEntries());
+    }
+
+    /**
+     * Get the entries of this instance.
+     * @return entries of this instance
+     */
+    private OpenIntToFieldHashMap<T> getEntries() {
+        return entries;
+    }
+
+    /**
+     * Optimized method to add sparse vectors.
+     * @param v vector to add
+     * @return The sum of <code>this</code> and <code>v</code>
+     * @throws IllegalArgumentException If the dimensions don't match
+     */
+    public FieldVector<T> add(SparseFieldVector<T> v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
+        OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            T value = iter.value();
+            if (entries.containsKey(key)) {
+                res.setEntry(key, entries.get(key).add(value));
+            } else {
+                res.setEntry(key, value);
+            }
+        }
+        return res;
+
+    }
+
+
+    /** {@inheritDoc} */
+    public FieldVector<T> add(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        SparseFieldVector<T> res = new SparseFieldVector<T>(field,getDimension());
+        for (int i = 0; i < v.length; i++) {
+            res.setEntry(i, v[i].add(getEntry(i)));
+        }
+        return res;
+    }
+
+    /**
+     * Construct a vector by appending a vector to this vector.
+     * @param v vector to append to this one.
+     * @return a new vector
+     */
+    public FieldVector<T> append(SparseFieldVector<T> v) {
+        SparseFieldVector<T> res = new SparseFieldVector<T>(this, v.getDimension());
+        OpenIntToFieldHashMap<T>.Iterator iter = v.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key() + virtualSize, iter.value());
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(FieldVector<T> v) {
+        if (v instanceof SparseFieldVector<?>) {
+            return append((SparseFieldVector<T>) v);
+        } else {
+            return append(v.toArray());
+        }
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(T d) {
+        FieldVector<T> res = new SparseFieldVector<T>(this, 1);
+        res.setEntry(virtualSize, d);
+        return res;
+     }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> append(T[] a) {
+        FieldVector<T> res = new SparseFieldVector<T>(this, a.length);
+        for (int i = 0; i < a.length; i++) {
+            res.setEntry(i + virtualSize, a[i]);
+        }
+        return res;
+     }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> copy() {
+        return new SparseFieldVector<T>(this);
+   }
+
+    /** {@inheritDoc} */
+    public T dotProduct(FieldVector<T> v) throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        T res = field.getZero();
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res = res.add(v.getEntry(iter.key()).multiply(iter.value()));
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public T dotProduct(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        T res = field.getZero();
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            int idx = iter.key();
+            T value = field.getZero();
+            if (idx < v.length) {
+                value = v[idx];
+            }
+            res = res.add(value.multiply(iter.value()));
+        }
+        return res;
+     }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeDivide(FieldVector<T> v)
+        throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
+        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value().divide(v.getEntry(iter.key())));
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
+        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value().divide(v[iter.key()]));
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> ebeMultiply(FieldVector<T> v)throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
+        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value().multiply(v.getEntry(iter.key())));
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+     public FieldVector<T> ebeMultiply(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
+        OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res.setEntry(iter.key(), iter.value().multiply(v[iter.key()]));
+        }
+        return res;
+    }
+
+     /** {@inheritDoc} */
+     public T[] getData() {
+        T[] res = buildArray(virtualSize);
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            res[iter.key()] = iter.value();
+        }
+        return res;
+     }
+
+     /** {@inheritDoc} */
+     public int getDimension() {
+        return virtualSize;
+    }
+
+     /** {@inheritDoc} */
+     public T getEntry(int index) throws MatrixIndexException {
+        checkIndex(index);
+        return entries.get(index);
+   }
+
+     /** {@inheritDoc} */
+     public Field<T> getField() {
+        return field;
+    }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> getSubVector(int index, int n)
+            throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + n - 1);
+        SparseFieldVector<T> res = new SparseFieldVector<T>(field,n);
+        int end = index + n;
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (key >= index && key < end) {
+                res.setEntry(key - index, iter.value());
+            }
+        }
+        return res;
+    }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapAdd(T d) {
+        return copy().mapAddToSelf(d);
+   }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapAddToSelf(T d) {
+        for (int i = 0; i < virtualSize; i++) {
+            setEntry(i, getEntry(i).add(d));
+        }
+        return this;
+    }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapDivide(T d) {
+        return copy().mapDivideToSelf(d);
+    }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapDivideToSelf(T d) {
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            entries.put(iter.key(), iter.value().divide(d));
+        }
+        return this;
+   }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapInv() {
+        return copy().mapInvToSelf();
+   }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapInvToSelf() {
+        for (int i = 0; i < virtualSize; i++) {
+            setEntry(i, field.getOne().divide(getEntry(i)));
+        }
+        return this;
+   }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapMultiply(T d) {
+        return copy().mapMultiplyToSelf(d);
+    }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapMultiplyToSelf(T d) {
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            entries.put(iter.key(), iter.value().multiply(d));
+        }
+        return this;
+   }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapSubtract(T d) {
+        return copy().mapSubtractToSelf(d);
+    }
+
+     /** {@inheritDoc} */
+     public FieldVector<T> mapSubtractToSelf(T d) {
+        return mapAddToSelf(field.getZero().subtract(d));
+    }
+
+     /**
+      * Optimized method to compute outer product when both vectors are sparse.
+      * @param v vector with which outer product should be computed
+      * @return the square matrix outer product between instance and v
+      * @throws IllegalArgumentException if v is not the same size as {@code this}
+      */
+    public FieldMatrix<T> outerProduct(SparseFieldVector<T> v)
+            throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        SparseFieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize);
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            OpenIntToFieldHashMap<T>.Iterator iter2 = v.entries.iterator();
+            while (iter2.hasNext()) {
+                iter2.advance();
+                res.setEntry(iter.key(), iter2.key(), iter.value().multiply(iter2.value()));
+            }
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> outerProduct(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        FieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize);
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int row = iter.key();
+            FieldElement<T>value = iter.value();
+            for (int col = 0; col < virtualSize; col++) {
+                res.setEntry(row, col, value.multiply(v[col]));
+            }
+        }
+        return res;
+     }
+
+    /** {@inheritDoc} */
+    public FieldMatrix<T> outerProduct(FieldVector<T> v)
+    throws IllegalArgumentException {
+        if(v instanceof SparseFieldVector<?>)
+            return outerProduct((SparseFieldVector<T>)v);
+        else
+            return outerProduct(v.toArray());
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> projection(FieldVector<T> v)
+    throws IllegalArgumentException {
+        checkVectorDimensions(v.getDimension());
+        return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> projection(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        return projection(new SparseFieldVector<T>(field,v));
+    }
+
+    /** {@inheritDoc} */
+    public void set(T value) {
+        for (int i = 0; i < virtualSize; i++) {
+            setEntry(i, value);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void setEntry(int index, T value) throws MatrixIndexException {
+        checkIndex(index);
+        entries.put(index, value);
+   }
+
+    /** {@inheritDoc} */
+    public void setSubVector(int index, FieldVector<T> v)
+            throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + v.getDimension() - 1);
+        setSubVector(index, v.getData());
+    }
+
+    /** {@inheritDoc} */
+    public void setSubVector(int index, T[] v) throws MatrixIndexException {
+        checkIndex(index);
+        checkIndex(index + v.length - 1);
+        for (int i = 0; i < v.length; i++) {
+            setEntry(i + index, v[i]);
+        }
+
+    }
+
+    /**
+     * Optimized method to subtract SparseRealVectors.
+     * @param v The vector to subtract from <code>this</code>
+     * @return The difference of <code>this</code> and <code>v</code>
+     * @throws IllegalArgumentException If the dimensions don't match
+     */
+    public SparseFieldVector<T> subtract(SparseFieldVector<T> v) throws IllegalArgumentException{
+        checkVectorDimensions(v.getDimension());
+        SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
+        OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int key = iter.key();
+            if (entries.containsKey(key)) {
+                res.setEntry(key, entries.get(key).subtract(iter.value()));
+            } else {
+                res.setEntry(key, field.getZero().subtract(iter.value()));
+            }
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> subtract(FieldVector<T> v)
+           throws IllegalArgumentException {
+        if(v instanceof SparseFieldVector<?>)
+            return subtract((SparseFieldVector<T>)v);
+        else
+            return subtract(v.toArray());
+    }
+
+    /** {@inheritDoc} */
+    public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
+        checkVectorDimensions(v.length);
+        SparseFieldVector<T> res = new SparseFieldVector<T>(this);
+        for (int i = 0; i < v.length; i++) {
+            if (entries.containsKey(i)) {
+                res.setEntry(i, entries.get(i).subtract(v[i]));
+            } else {
+                res.setEntry(i, field.getZero().subtract(v[i]));
+            }
+        }
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    public T[] toArray() {
+        return getData();
+    }
+
+    /**
+     * 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(LocalizedFormats.INDEX_OUT_OF_RANGE,
+                                           index, 0, getDimension() - 1);
+        }
+    }
+
+    /**
+     * 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 (getDimension() != n) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.VECTOR_LENGTH_MISMATCH,
+                    getDimension(), n);
+        }
+    }
+
+
+    /** {@inheritDoc} */
+    public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
+        if (v instanceof SparseFieldVector<?>) {
+            return add((SparseFieldVector<T>)v);
+        } else {
+            return add(v.toArray());
+        }
+    }
+
+    /** Build an array of elements.
+     * @param length size of the array to build
+     * @return a new array
+     */
+    @SuppressWarnings("unchecked") // field is type T
+    private T[] buildArray(final int length) {
+        return (T[]) Array.newInstance(field.getZero().getClass(), length);
+    }
+
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((field == null) ? 0 : field.hashCode());
+        result = prime * result + virtualSize;
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            int temp = iter.value().hashCode();
+            result = prime * result + temp;
+        }
+        return result;
+    }
+
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (!(obj instanceof SparseFieldVector<?>)) {
+            return false;
+        }
+
+        @SuppressWarnings("unchecked") // OK, because "else if" check below ensures that
+                                       // other must be the same type as this
+        SparseFieldVector<T> other = (SparseFieldVector<T>) obj;
+        if (field == null) {
+            if (other.field != null) {
+                return false;
+            }
+        } else if (!field.equals(other.field)) {
+            return false;
+        }
+        if (virtualSize != other.virtualSize) {
+            return false;
+        }
+
+        OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            T test = other.getEntry(iter.key());
+            if (!test.equals(iter.value())) {
+                return false;
+            }
+        }
+        iter = other.getEntries().iterator();
+        while (iter.hasNext()) {
+            iter.advance();
+            T test = iter.value();
+            if (!test.equals(getEntry(iter.key()))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SparseRealMatrix.java b/src/main/java/org/apache/commons/math/linear/SparseRealMatrix.java
new file mode 100644
index 0000000..ad1fa19
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SparseRealMatrix.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Marker interface for {@link RealMatrix} implementations that require sparse backing storage
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ *
+ */
+public interface SparseRealMatrix extends RealMatrix {
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/SparseRealVector.java b/src/main/java/org/apache/commons/math/linear/SparseRealVector.java
new file mode 100644
index 0000000..adba604
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/SparseRealVector.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ * Marker interface for RealVectors that require sparse backing storage
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ *
+ */
+public interface SparseRealVector extends RealVector {
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/TriDiagonalTransformer.java b/src/main/java/org/apache/commons/math/linear/TriDiagonalTransformer.java
new file mode 100644
index 0000000..9260aa0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/TriDiagonalTransformer.java
@@ -0,0 +1,270 @@
+/*
+ * 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.Arrays;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Class transforming a symmetrical matrix to tridiagonal shape.
+ * <p>A symmetrical m &times; m matrix A can be written as the product of three matrices:
+ * A = Q &times; T &times; Q<sup>T</sup> with Q an orthogonal matrix and T a symmetrical
+ * tridiagonal matrix. Both Q and T are m &times; m matrices.</p>
+ * <p>This implementation only uses the upper part of the matrix, the part below the
+ * diagonal is not accessed at all.</p>
+ * <p>Transformation to tridiagonal shape is often not a goal by itself, but it is
+ * an intermediate step in more general decomposition algorithms like {@link
+ * EigenDecomposition eigen decomposition}. This class is therefore intended for internal
+ * use by the library and is not public. As a consequence of this explicitly limited scope,
+ * many methods directly returns references to internal arrays, not copies.</p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+class TriDiagonalTransformer {
+
+    /** Householder vectors. */
+    private final double householderVectors[][];
+
+    /** Main diagonal. */
+    private final double[] main;
+
+    /** Secondary diagonal. */
+    private final double[] secondary;
+
+    /** Cached value of Q. */
+    private RealMatrix cachedQ;
+
+    /** Cached value of Qt. */
+    private RealMatrix cachedQt;
+
+    /** Cached value of T. */
+    private RealMatrix cachedT;
+
+    /**
+     * Build the transformation to tridiagonal shape of a symmetrical matrix.
+     * <p>The specified matrix is assumed to be symmetrical without any check.
+     * Only the upper triangular part of the matrix is used.</p>
+     * @param matrix the symmetrical matrix to transform.
+     * @exception InvalidMatrixException if matrix is not square
+     */
+    public TriDiagonalTransformer(RealMatrix matrix)
+        throws InvalidMatrixException {
+        if (!matrix.isSquare()) {
+            throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension());
+        }
+
+        final int m = matrix.getRowDimension();
+        householderVectors = matrix.getData();
+        main      = new double[m];
+        secondary = new double[m - 1];
+        cachedQ   = null;
+        cachedQt  = null;
+        cachedT   = null;
+
+        // transform matrix
+        transform();
+
+    }
+
+    /**
+     * Returns the matrix Q of the transform.
+     * <p>Q is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the Q matrix
+     */
+    public RealMatrix getQ() {
+        if (cachedQ == null) {
+            cachedQ = getQT().transpose();
+        }
+        return cachedQ;
+    }
+
+    /**
+     * Returns the transpose of the matrix Q of the transform.
+     * <p>Q is an orthogonal matrix, i.e. its transpose is also its inverse.</p>
+     * @return the Q matrix
+     */
+    public RealMatrix getQT() {
+
+        if (cachedQt == null) {
+
+            final int m = householderVectors.length;
+            cachedQt = MatrixUtils.createRealMatrix(m, m);
+
+            // build up first part of the matrix by applying Householder transforms
+            for (int k = m - 1; k >= 1; --k) {
+                final double[] hK = householderVectors[k - 1];
+                final double inv = 1.0 / (secondary[k - 1] * hK[k]);
+                cachedQt.setEntry(k, k, 1);
+                if (hK[k] != 0.0) {
+                    double beta = 1.0 / secondary[k - 1];
+                    cachedQt.setEntry(k, k, 1 + beta * hK[k]);
+                    for (int i = k + 1; i < m; ++i) {
+                        cachedQt.setEntry(k, i, beta * hK[i]);
+                    }
+                    for (int j = k + 1; j < m; ++j) {
+                        beta = 0;
+                        for (int i = k + 1; i < m; ++i) {
+                            beta += cachedQt.getEntry(j, i) * hK[i];
+                        }
+                        beta *= inv;
+                        cachedQt.setEntry(j, k, beta * hK[k]);
+                        for (int i = k + 1; i < m; ++i) {
+                            cachedQt.addToEntry(j, i, beta * hK[i]);
+                        }
+                    }
+                }
+            }
+            cachedQt.setEntry(0, 0, 1);
+
+        }
+
+        // return the cached matrix
+        return cachedQt;
+
+    }
+
+    /**
+     * Returns the tridiagonal matrix T of the transform.
+     * @return the T matrix
+     */
+    public RealMatrix getT() {
+
+        if (cachedT == null) {
+
+            final int m = main.length;
+            cachedT = MatrixUtils.createRealMatrix(m, m);
+            for (int i = 0; i < m; ++i) {
+                cachedT.setEntry(i, i, main[i]);
+                if (i > 0) {
+                    cachedT.setEntry(i, i - 1, secondary[i - 1]);
+                }
+                if (i < main.length - 1) {
+                    cachedT.setEntry(i, i + 1, secondary[i]);
+                }
+            }
+
+        }
+
+        // return the cached matrix
+        return cachedT;
+
+    }
+
+    /**
+     * Get the Householder vectors of the transform.
+     * <p>Note that since this class is only intended for internal use,
+     * it returns directly a reference to its internal arrays, not a copy.</p>
+     * @return the main diagonal elements of the B matrix
+     */
+    double[][] getHouseholderVectorsRef() {
+        return householderVectors;
+    }
+
+    /**
+     * Get the main diagonal elements of the matrix T of the transform.
+     * <p>Note that since this class is only intended for internal use,
+     * it returns directly a reference to its internal arrays, not a copy.</p>
+     * @return the main diagonal elements of the T matrix
+     */
+    double[] getMainDiagonalRef() {
+        return main;
+    }
+
+    /**
+     * Get the secondary diagonal elements of the matrix T of the transform.
+     * <p>Note that since this class is only intended for internal use,
+     * it returns directly a reference to its internal arrays, not a copy.</p>
+     * @return the secondary diagonal elements of the T matrix
+     */
+    double[] getSecondaryDiagonalRef() {
+        return secondary;
+    }
+
+    /**
+     * Transform original matrix to tridiagonal form.
+     * <p>Transformation is done using Householder transforms.</p>
+     */
+    private void transform() {
+
+        final int m = householderVectors.length;
+        final double[] z = new double[m];
+        for (int k = 0; k < m - 1; k++) {
+
+            //zero-out a row and a column simultaneously
+            final double[] hK = householderVectors[k];
+            main[k] = hK[k];
+            double xNormSqr = 0;
+            for (int j = k + 1; j < m; ++j) {
+                final double c = hK[j];
+                xNormSqr += c * c;
+            }
+            final double a = (hK[k + 1] > 0) ? -FastMath.sqrt(xNormSqr) : FastMath.sqrt(xNormSqr);
+            secondary[k] = a;
+            if (a != 0.0) {
+                // apply Householder transform from left and right simultaneously
+
+                hK[k + 1] -= a;
+                final double beta = -1 / (a * hK[k + 1]);
+
+                // compute a = beta A v, where v is the Householder vector
+                // this loop is written in such a way
+                //   1) only the upper triangular part of the matrix is accessed
+                //   2) access is cache-friendly for a matrix stored in rows
+                Arrays.fill(z, k + 1, m, 0);
+                for (int i = k + 1; i < m; ++i) {
+                    final double[] hI = householderVectors[i];
+                    final double hKI = hK[i];
+                    double zI = hI[i] * hKI;
+                    for (int j = i + 1; j < m; ++j) {
+                        final double hIJ = hI[j];
+                        zI   += hIJ * hK[j];
+                        z[j] += hIJ * hKI;
+                    }
+                    z[i] = beta * (z[i] + zI);
+                }
+
+                // compute gamma = beta vT z / 2
+                double gamma = 0;
+                for (int i = k + 1; i < m; ++i) {
+                    gamma += z[i] * hK[i];
+                }
+                gamma *= beta / 2;
+
+                // compute z = z - gamma v
+                for (int i = k + 1; i < m; ++i) {
+                    z[i] -= gamma * hK[i];
+                }
+
+                // update matrix: A = A - v zT - z vT
+                // only the upper triangular part of the matrix is updated
+                for (int i = k + 1; i < m; ++i) {
+                    final double[] hI = householderVectors[i];
+                    for (int j = i; j < m; ++j) {
+                        hI[j] -= hK[i] * z[j] + z[i] * hK[j];
+                    }
+                }
+
+            }
+
+        }
+        main[m - 1] = householderVectors[m - 1][m - 1];
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/linear/package.html b/src/main/java/org/apache/commons/math/linear/package.html
new file mode 100644
index 0000000..fc1034e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/linear/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Linear algebra support.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/ode/AbstractIntegrator.java b/src/main/java/org/apache/commons/math/ode/AbstractIntegrator.java
new file mode 100644
index 0000000..c17f436
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/AbstractIntegrator.java
@@ -0,0 +1,440 @@
+/*
+ * 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.ode;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.ode.events.CombinedEventsManager;
+import org.apache.commons.math.ode.events.EventException;
+import org.apache.commons.math.ode.events.EventHandler;
+import org.apache.commons.math.ode.events.EventState;
+import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Base class managing common boilerplate for all integrators.
+ * @version $Revision: 1073267 $ $Date: 2011-02-22 10:06:20 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AbstractIntegrator implements FirstOrderIntegrator {
+
+    /** Step handler. */
+    protected Collection<StepHandler> stepHandlers;
+
+    /** Current step start time. */
+    protected double stepStart;
+
+    /** Current stepsize. */
+    protected double stepSize;
+
+    /** Indicator for last step. */
+    protected boolean isLastStep;
+
+    /** Indicator that a state or derivative reset was triggered by some event. */
+    protected boolean resetOccurred;
+
+    /** Events states. */
+    private Collection<EventState> eventsStates;
+
+    /** Initialization indicator of events states. */
+    private boolean statesInitialized;
+
+    /** Name of the method. */
+    private final String name;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed. */
+    private int evaluations;
+
+    /** Differential equations to integrate. */
+    private transient FirstOrderDifferentialEquations equations;
+
+    /** Build an instance.
+     * @param name name of the method
+     */
+    public AbstractIntegrator(final String name) {
+        this.name = name;
+        stepHandlers = new ArrayList<StepHandler>();
+        stepStart = Double.NaN;
+        stepSize  = Double.NaN;
+        eventsStates = new ArrayList<EventState>();
+        statesInitialized = false;
+        setMaxEvaluations(-1);
+        resetEvaluations();
+    }
+
+    /** Build an instance with a null name.
+     */
+    protected AbstractIntegrator() {
+        this(null);
+    }
+
+    /** {@inheritDoc} */
+    public String getName() {
+        return name;
+    }
+
+    /** {@inheritDoc} */
+    public void addStepHandler(final StepHandler handler) {
+        stepHandlers.add(handler);
+    }
+
+    /** {@inheritDoc} */
+    public Collection<StepHandler> getStepHandlers() {
+        return Collections.unmodifiableCollection(stepHandlers);
+    }
+
+    /** {@inheritDoc} */
+    public void clearStepHandlers() {
+        stepHandlers.clear();
+    }
+
+    /** {@inheritDoc} */
+    public void addEventHandler(final EventHandler handler,
+                                final double maxCheckInterval,
+                                final double convergence,
+                                final int maxIterationCount) {
+        eventsStates.add(new EventState(handler, maxCheckInterval, convergence, maxIterationCount));
+    }
+
+    /** {@inheritDoc} */
+    public Collection<EventHandler> getEventHandlers() {
+        final List<EventHandler> list = new ArrayList<EventHandler>();
+        for (EventState state : eventsStates) {
+            list.add(state.getEventHandler());
+        }
+        return Collections.unmodifiableCollection(list);
+    }
+
+    /** {@inheritDoc} */
+    public void clearEventHandlers() {
+        eventsStates.clear();
+    }
+
+    /** Check if dense output is needed.
+     * @return true if there is at least one event handler or if
+     * one of the step handlers requires dense output
+     */
+    protected boolean requiresDenseOutput() {
+        if (!eventsStates.isEmpty()) {
+            return true;
+        }
+        for (StepHandler handler : stepHandlers) {
+            if (handler.requiresDenseOutput()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    public double getCurrentStepStart() {
+        return stepStart;
+    }
+
+    /** {@inheritDoc} */
+    public double getCurrentSignedStepsize() {
+        return stepSize;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = (maxEvaluations < 0) ? Integer.MAX_VALUE : maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return evaluations;
+    }
+
+    /** Reset the number of evaluations to zero.
+     */
+    protected void resetEvaluations() {
+        evaluations = 0;
+    }
+
+    /** Set the differential equations.
+     * @param equations differential equations to integrate
+     * @see #computeDerivatives(double, double[], double[])
+     */
+    protected void setEquations(final FirstOrderDifferentialEquations equations) {
+        this.equations = equations;
+    }
+
+    /** Compute the derivatives and check the number of evaluations.
+     * @param t current value of the independent <I>time</I> variable
+     * @param y array containing the current value of the state vector
+     * @param yDot placeholder array where to put the time derivative of the state vector
+     * @throws DerivativeException this user-defined exception should be used if an error is
+     * is triggered by user code
+     */
+    public void computeDerivatives(final double t, final double[] y, final double[] yDot)
+        throws DerivativeException {
+        if (++evaluations > maxEvaluations) {
+            throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations));
+        }
+        equations.computeDerivatives(t, y, yDot);
+    }
+
+    /** Set the stateInitialized flag.
+     * <p>This method must be called by integrators with the value
+     * {@code false} before they start integration, so a proper lazy
+     * initialization is done automatically on the first step.</p>
+     * @param stateInitialized new value for the flag
+     * @since 2.2
+     */
+    protected void setStateInitialized(final boolean stateInitialized) {
+        this.statesInitialized = stateInitialized;
+    }
+
+    /** Accept a step, triggering events and step handlers.
+     * @param interpolator step interpolator
+     * @param y state vector at step end time, must be reset if an event
+     * asks for resetting or if an events stops integration during the step
+     * @param yDot placeholder array where to put the time derivative of the state vector
+     * @param tEnd final integration time
+     * @return time at end of step
+     * @throws DerivativeException this exception is propagated to the caller if
+     * the underlying user function triggers one
+     * @exception IntegratorException if the value of one event state cannot be evaluated
+     * @since 2.2
+     */
+    protected double acceptStep(final AbstractStepInterpolator interpolator,
+                                final double[] y, final double[] yDot, final double tEnd)
+        throws DerivativeException, IntegratorException {
+
+        try {
+            double previousT = interpolator.getGlobalPreviousTime();
+            final double currentT = interpolator.getGlobalCurrentTime();
+            resetOccurred = false;
+
+            // initialize the events states if needed
+            if (! statesInitialized) {
+                for (EventState state : eventsStates) {
+                    state.reinitializeBegin(interpolator);
+                }
+                statesInitialized = true;
+            }
+
+            // search for next events that may occur during the step
+            final int orderingSign = interpolator.isForward() ? +1 : -1;
+            SortedSet<EventState> occuringEvents = new TreeSet<EventState>(new Comparator<EventState>() {
+
+                /** {@inheritDoc} */
+                public int compare(EventState es0, EventState es1) {
+                    return orderingSign * Double.compare(es0.getEventTime(), es1.getEventTime());
+                }
+
+            });
+
+            for (final EventState state : eventsStates) {
+                if (state.evaluateStep(interpolator)) {
+                    // the event occurs during the current step
+                    occuringEvents.add(state);
+                }
+            }
+
+            while (!occuringEvents.isEmpty()) {
+
+                // handle the chronologically first event
+                final Iterator<EventState> iterator = occuringEvents.iterator();
+                final EventState currentEvent = iterator.next();
+                iterator.remove();
+
+                // restrict the interpolator to the first part of the step, up to the event
+                final double eventT = currentEvent.getEventTime();
+                interpolator.setSoftPreviousTime(previousT);
+                interpolator.setSoftCurrentTime(eventT);
+
+                // trigger the event
+                interpolator.setInterpolatedTime(eventT);
+                final double[] eventY = interpolator.getInterpolatedState();
+                currentEvent.stepAccepted(eventT, eventY);
+                isLastStep = currentEvent.stop();
+
+                // handle the first part of the step, up to the event
+                for (final StepHandler handler : stepHandlers) {
+                    handler.handleStep(interpolator, isLastStep);
+                }
+
+                if (isLastStep) {
+                    // the event asked to stop integration
+                    System.arraycopy(eventY, 0, y, 0, y.length);
+                    return eventT;
+                }
+
+                if (currentEvent.reset(eventT, eventY)) {
+                    // some event handler has triggered changes that
+                    // invalidate the derivatives, we need to recompute them
+                    System.arraycopy(eventY, 0, y, 0, y.length);
+                    computeDerivatives(eventT, y, yDot);
+                    resetOccurred = true;
+                    return eventT;
+                }
+
+                // prepare handling of the remaining part of the step
+                previousT = eventT;
+                interpolator.setSoftPreviousTime(eventT);
+                interpolator.setSoftCurrentTime(currentT);
+
+                // check if the same event occurs again in the remaining part of the step
+                if (currentEvent.evaluateStep(interpolator)) {
+                    // the event occurs during the current step
+                    occuringEvents.add(currentEvent);
+                }
+
+            }
+
+            interpolator.setInterpolatedTime(currentT);
+            final double[] currentY = interpolator.getInterpolatedState();
+            for (final EventState state : eventsStates) {
+                state.stepAccepted(currentT, currentY);
+                isLastStep = isLastStep || state.stop();
+            }
+            isLastStep = isLastStep || MathUtils.equals(currentT, tEnd, 1);
+
+            // handle the remaining part of the step, after all events if any
+            for (StepHandler handler : stepHandlers) {
+                handler.handleStep(interpolator, isLastStep);
+            }
+
+            return currentT;
+        } catch (EventException se) {
+            final Throwable cause = se.getCause();
+            if ((cause != null) && (cause instanceof DerivativeException)) {
+                throw (DerivativeException) cause;
+            }
+            throw new IntegratorException(se);
+        } catch (ConvergenceException ce) {
+            throw new IntegratorException(ce);
+        }
+
+    }
+
+    /** Perform some sanity checks on the integration parameters.
+     * @param ode differential equations set
+     * @param t0 start time
+     * @param y0 state vector at t0
+     * @param t target time for the integration
+     * @param y placeholder where to put the state vector
+     * @exception IntegratorException if some inconsistency is detected
+     */
+    protected void sanityChecks(final FirstOrderDifferentialEquations ode,
+                                final double t0, final double[] y0,
+                                final double t, final double[] y)
+        throws IntegratorException {
+
+        if (ode.getDimension() != y0.length) {
+            throw new IntegratorException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, ode.getDimension(), y0.length);
+        }
+
+        if (ode.getDimension() != y.length) {
+            throw new IntegratorException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, ode.getDimension(), y.length);
+        }
+
+        if (FastMath.abs(t - t0) <= 1.0e-12 * FastMath.max(FastMath.abs(t0), FastMath.abs(t))) {
+            throw new IntegratorException(
+                    LocalizedFormats.TOO_SMALL_INTEGRATION_INTERVAL,
+                    FastMath.abs(t - t0));
+        }
+
+    }
+
+    /** Add an event handler for end time checking.
+     * <p>This method can be used to simplify handling of integration end time.
+     * It leverages the nominal stop condition with the exceptional stop
+     * conditions.</p>
+     * @param startTime integration start time
+     * @param endTime desired end time
+     * @param manager manager containing the user-defined handlers
+     * @return a new manager containing all the user-defined handlers plus a
+     * dedicated manager triggering a stop event at entTime
+     * @deprecated as of 2.2, this method is not used any more
+     */
+    @Deprecated
+    protected CombinedEventsManager addEndTimeChecker(final double startTime,
+                                                      final double endTime,
+                                                      final CombinedEventsManager manager) {
+        CombinedEventsManager newManager = new CombinedEventsManager();
+        for (final EventState state : manager.getEventsStates()) {
+            newManager.addEventHandler(state.getEventHandler(),
+                                       state.getMaxCheckInterval(),
+                                       state.getConvergence(),
+                                       state.getMaxIterationCount());
+        }
+        newManager.addEventHandler(new EndTimeChecker(endTime),
+                                   Double.POSITIVE_INFINITY,
+                                   FastMath.ulp(FastMath.max(FastMath.abs(startTime), FastMath.abs(endTime))),
+                                   100);
+        return newManager;
+    }
+
+    /** Specialized event handler to stop integration.
+     * @deprecated as of 2.2, this class is not used anymore
+     */
+    @Deprecated
+    private static class EndTimeChecker implements EventHandler {
+
+        /** Desired end time. */
+        private final double endTime;
+
+        /** Build an instance.
+         * @param endTime desired time
+         */
+        public EndTimeChecker(final double endTime) {
+            this.endTime = endTime;
+        }
+
+        /** {@inheritDoc} */
+        public int eventOccurred(double t, double[] y, boolean increasing) {
+            return STOP;
+        }
+
+        /** {@inheritDoc} */
+        public double g(double t, double[] y) {
+            return t - endTime;
+        }
+
+        /** {@inheritDoc} */
+        public void resetState(double t, double[] y) {
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/ContinuousOutputModel.java b/src/main/java/org/apache/commons/math/ode/ContinuousOutputModel.java
new file mode 100644
index 0000000..acafdcb
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/ContinuousOutputModel.java
@@ -0,0 +1,379 @@
+/*
+ * 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.ode;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class stores all information provided by an ODE integrator
+ * during the integration process and build a continuous model of the
+ * solution from this.
+ *
+ * <p>This class act as a step handler from the integrator point of
+ * view. It is called iteratively during the integration process and
+ * stores a copy of all steps information in a sorted collection for
+ * later use. Once the integration process is over, the user can use
+ * the {@link #setInterpolatedTime setInterpolatedTime} and {@link
+ * #getInterpolatedState getInterpolatedState} to retrieve this
+ * information at any time. It is important to wait for the
+ * integration to be over before attempting to call {@link
+ * #setInterpolatedTime setInterpolatedTime} because some internal
+ * variables are set only once the last step has been handled.</p>
+ *
+ * <p>This is useful for example if the main loop of the user
+ * application should remain independent from the integration process
+ * or if one needs to mimic the behaviour of an analytical model
+ * despite a numerical model is used (i.e. one needs the ability to
+ * get the model value at any time or to navigate through the
+ * data).</p>
+ *
+ * <p>If problem modeling is done with several separate
+ * integration phases for contiguous intervals, the same
+ * ContinuousOutputModel can be used as step handler for all
+ * integration phases as long as they are performed in order and in
+ * the same direction. As an example, one can extrapolate the
+ * trajectory of a satellite with one model (i.e. one set of
+ * differential equations) up to the beginning of a maneuver, use
+ * another more complex model including thrusters modeling and
+ * accurate attitude control during the maneuver, and revert to the
+ * first model after the end of the maneuver. If the same continuous
+ * output model handles the steps of all integration phases, the user
+ * do not need to bother when the maneuver begins or ends, he has all
+ * the data available in a transparent manner.</p>
+ *
+ * <p>An important feature of this class is that it implements the
+ * <code>Serializable</code> interface. This means that the result of
+ * an integration can be serialized and reused later (if stored into a
+ * persistent medium like a filesystem or a database) or elsewhere (if
+ * sent to another application). Only the result of the integration is
+ * stored, there is no reference to the integrated problem by
+ * itself.</p>
+ *
+ * <p>One should be aware that the amount of data stored in a
+ * ContinuousOutputModel instance can be important if the state vector
+ * is large, if the integration interval is long or if the steps are
+ * small (which can result from small tolerance settings in {@link
+ * org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator adaptive
+ * step size integrators}).</p>
+ *
+ * @see StepHandler
+ * @see StepInterpolator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public class ContinuousOutputModel
+  implements StepHandler, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1417964919405031606L;
+
+    /** Initial integration time. */
+    private double initialTime;
+
+    /** Final integration time. */
+    private double finalTime;
+
+    /** Integration direction indicator. */
+    private boolean forward;
+
+    /** Current interpolator index. */
+    private int index;
+
+    /** Steps table. */
+    private List<StepInterpolator> steps;
+
+  /** Simple constructor.
+   * Build an empty continuous output model.
+   */
+  public ContinuousOutputModel() {
+    steps = new ArrayList<StepInterpolator>();
+    reset();
+  }
+
+  /** Append another model at the end of the instance.
+   * @param model model to add at the end of the instance
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   * @exception IllegalArgumentException if the model to append is not
+   * compatible with the instance (dimension of the state vector,
+   * propagation direction, hole between the dates)
+   */
+  public void append(final ContinuousOutputModel model)
+    throws DerivativeException {
+
+    if (model.steps.size() == 0) {
+      return;
+    }
+
+    if (steps.size() == 0) {
+      initialTime = model.initialTime;
+      forward     = model.forward;
+    } else {
+
+      if (getInterpolatedState().length != model.getInterpolatedState().length) {
+          throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                getInterpolatedState().length, model.getInterpolatedState().length);
+      }
+
+      if (forward ^ model.forward) {
+          throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.PROPAGATION_DIRECTION_MISMATCH);
+      }
+
+      final StepInterpolator lastInterpolator = steps.get(index);
+      final double current  = lastInterpolator.getCurrentTime();
+      final double previous = lastInterpolator.getPreviousTime();
+      final double step = current - previous;
+      final double gap = model.getInitialTime() - current;
+      if (FastMath.abs(gap) > 1.0e-3 * FastMath.abs(step)) {
+        throw MathRuntimeException.createIllegalArgumentException(
+              LocalizedFormats.HOLE_BETWEEN_MODELS_TIME_RANGES, FastMath.abs(gap));
+      }
+
+    }
+
+    for (StepInterpolator interpolator : model.steps) {
+      steps.add(interpolator.copy());
+    }
+
+    index = steps.size() - 1;
+    finalTime = (steps.get(index)).getCurrentTime();
+
+  }
+
+  /** Determines whether this handler needs dense output.
+   * <p>The essence of this class is to provide dense output over all
+   * steps, hence it requires the internal steps to provide themselves
+   * dense output. The method therefore returns always true.</p>
+   * @return always true
+   */
+  public boolean requiresDenseOutput() {
+    return true;
+  }
+
+  /** Reset the step handler.
+   * Initialize the internal data as required before the first step is
+   * handled.
+   */
+  public void reset() {
+    initialTime = Double.NaN;
+    finalTime   = Double.NaN;
+    forward     = true;
+    index       = 0;
+    steps.clear();
+   }
+
+  /** Handle the last accepted step.
+   * A copy of the information provided by the last step is stored in
+   * the instance for later use.
+   * @param interpolator interpolator for the last accepted step.
+   * @param isLast true if the step is the last one
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   */
+  public void handleStep(final StepInterpolator interpolator, final boolean isLast)
+    throws DerivativeException {
+
+    if (steps.size() == 0) {
+      initialTime = interpolator.getPreviousTime();
+      forward     = interpolator.isForward();
+    }
+
+    steps.add(interpolator.copy());
+
+    if (isLast) {
+      finalTime = interpolator.getCurrentTime();
+      index     = steps.size() - 1;
+    }
+
+  }
+
+  /**
+   * Get the initial integration time.
+   * @return initial integration time
+   */
+  public double getInitialTime() {
+    return initialTime;
+  }
+
+  /**
+   * Get the final integration time.
+   * @return final integration time
+   */
+  public double getFinalTime() {
+    return finalTime;
+  }
+
+  /**
+   * Get the time of the interpolated point.
+   * If {@link #setInterpolatedTime} has not been called, it returns
+   * the final integration time.
+   * @return interpolation point time
+   */
+  public double getInterpolatedTime() {
+    return steps.get(index).getInterpolatedTime();
+  }
+
+  /** Set the time of the interpolated point.
+   * <p>This method should <strong>not</strong> be called before the
+   * integration is over because some internal variables are set only
+   * once the last step has been handled.</p>
+   * <p>Setting the time outside of the integration interval is now
+   * allowed (it was not allowed up to version 5.9 of Mantissa), but
+   * should be used with care since the accuracy of the interpolator
+   * will probably be very poor far from this interval. This allowance
+   * has been added to simplify implementation of search algorithms
+   * near the interval endpoints.</p>
+   * @param time time of the interpolated point
+   */
+  public void setInterpolatedTime(final double time) {
+
+      // initialize the search with the complete steps table
+      int iMin = 0;
+      final StepInterpolator sMin = steps.get(iMin);
+      double tMin = 0.5 * (sMin.getPreviousTime() + sMin.getCurrentTime());
+
+      int iMax = steps.size() - 1;
+      final StepInterpolator sMax = steps.get(iMax);
+      double tMax = 0.5 * (sMax.getPreviousTime() + sMax.getCurrentTime());
+
+      // handle points outside of the integration interval
+      // or in the first and last step
+      if (locatePoint(time, sMin) <= 0) {
+        index = iMin;
+        sMin.setInterpolatedTime(time);
+        return;
+      }
+      if (locatePoint(time, sMax) >= 0) {
+        index = iMax;
+        sMax.setInterpolatedTime(time);
+        return;
+      }
+
+      // reduction of the table slice size
+      while (iMax - iMin > 5) {
+
+        // use the last estimated index as the splitting index
+        final StepInterpolator si = steps.get(index);
+        final int location = locatePoint(time, si);
+        if (location < 0) {
+          iMax = index;
+          tMax = 0.5 * (si.getPreviousTime() + si.getCurrentTime());
+        } else if (location > 0) {
+          iMin = index;
+          tMin = 0.5 * (si.getPreviousTime() + si.getCurrentTime());
+        } else {
+          // we have found the target step, no need to continue searching
+          si.setInterpolatedTime(time);
+          return;
+        }
+
+        // compute a new estimate of the index in the reduced table slice
+        final int iMed = (iMin + iMax) / 2;
+        final StepInterpolator sMed = steps.get(iMed);
+        final double tMed = 0.5 * (sMed.getPreviousTime() + sMed.getCurrentTime());
+
+        if ((FastMath.abs(tMed - tMin) < 1e-6) || (FastMath.abs(tMax - tMed) < 1e-6)) {
+          // too close to the bounds, we estimate using a simple dichotomy
+          index = iMed;
+        } else {
+          // estimate the index using a reverse quadratic polynom
+          // (reverse means we have i = P(t), thus allowing to simply
+          // compute index = P(time) rather than solving a quadratic equation)
+          final double d12 = tMax - tMed;
+          final double d23 = tMed - tMin;
+          final double d13 = tMax - tMin;
+          final double dt1 = time - tMax;
+          final double dt2 = time - tMed;
+          final double dt3 = time - tMin;
+          final double iLagrange = ((dt2 * dt3 * d23) * iMax -
+                                    (dt1 * dt3 * d13) * iMed +
+                                    (dt1 * dt2 * d12) * iMin) /
+                                   (d12 * d23 * d13);
+          index = (int) FastMath.rint(iLagrange);
+        }
+
+        // force the next size reduction to be at least one tenth
+        final int low  = FastMath.max(iMin + 1, (9 * iMin + iMax) / 10);
+        final int high = FastMath.min(iMax - 1, (iMin + 9 * iMax) / 10);
+        if (index < low) {
+          index = low;
+        } else if (index > high) {
+          index = high;
+        }
+
+      }
+
+      // now the table slice is very small, we perform an iterative search
+      index = iMin;
+      while ((index <= iMax) && (locatePoint(time, steps.get(index)) > 0)) {
+        ++index;
+      }
+
+      steps.get(index).setInterpolatedTime(time);
+
+  }
+
+  /**
+   * Get the state vector of the interpolated point.
+   * @return state vector at time {@link #getInterpolatedTime}
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   */
+  public double[] getInterpolatedState() throws DerivativeException {
+    return steps.get(index).getInterpolatedState();
+  }
+
+  /** Compare a step interval and a double.
+   * @param time point to locate
+   * @param interval step interval
+   * @return -1 if the double is before the interval, 0 if it is in
+   * the interval, and +1 if it is after the interval, according to
+   * the interval direction
+   */
+  private int locatePoint(final double time, final StepInterpolator interval) {
+    if (forward) {
+      if (time < interval.getPreviousTime()) {
+        return -1;
+      } else if (time > interval.getCurrentTime()) {
+        return +1;
+      } else {
+        return 0;
+      }
+    }
+    if (time > interval.getPreviousTime()) {
+      return -1;
+    } else if (time < interval.getCurrentTime()) {
+      return +1;
+    } else {
+      return 0;
+    }
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/DerivativeException.java b/src/main/java/org/apache/commons/math/ode/DerivativeException.java
new file mode 100644
index 0000000..28251ed
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/DerivativeException.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ode;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * This exception is made available to users to report
+ * the error conditions that are triggered while computing
+ * the differential equations.
+ * @version $Revision: 1072413 $ $Date: 2011-02-19 19:59:39 +0100 (sam. 19 févr. 2011) $
+ * @since 1.2
+ */
+public class DerivativeException extends MathException {
+
+  /** Serializable version identifier */
+  private static final long serialVersionUID = 5666710788967425123L;
+
+  /** Simple constructor.
+   * Build an exception by translating and formating a message
+   * @param specifier format specifier (to be translated)
+   * @param parts to insert in the format (no translation)
+   */
+  public DerivativeException(final String specifier, final Object ... parts) {
+    this(new DummyLocalizable(specifier), parts);
+  }
+
+  /** Simple constructor.
+   * Build an exception by translating and formating a message
+   * @param specifier format specifier (to be translated)
+   * @param parts to insert in the format (no translation)
+   * @since 2.2
+   */
+  public DerivativeException(final Localizable specifier, final Object ... parts) {
+    super(specifier, parts);
+  }
+
+ /** Build an instance from an underlying cause.
+   * @param cause cause for the exception
+   */
+  public DerivativeException(final Throwable cause) {
+    super(cause);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/ExtendedFirstOrderDifferentialEquations.java b/src/main/java/org/apache/commons/math/ode/ExtendedFirstOrderDifferentialEquations.java
new file mode 100644
index 0000000..8d0d634
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/ExtendedFirstOrderDifferentialEquations.java
@@ -0,0 +1,66 @@
+/*
+ * 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.ode;
+
+
+/** This interface represents a first order differential equations set
+ * with a main set of equations and an extension set.
+ *
+ * <p>
+ * This interface is a simple extension on the {@link
+ * FirstOrderDifferentialEquations} that allows to identify which part
+ * of a complete set of differential equations correspond to the main
+ * set and which part correspond to the extension set.
+ * </p>
+ * <p>
+ * One typical use case is the computation of Jacobians. The main
+ * set of equations correspond to the raw ode, and we add to this set
+ * another bunch of equations which represent the jacobians of the
+ * main set. In that case, we want the integrator to use <em>only</em>
+ * the main set to estimate the errors and hence the step sizes. It should
+ * <em>not</em> use the additional equations in this computation. If the
+ * complete ode implements this interface, the {@link FirstOrderIntegrator
+ * integrator} will be able to know where the main set ends and where the
+ * extended set begins.
+ * </p>
+ * <p>
+ * We consider that the main set always corresponds to the first equations
+ * and the extended set to the last equations.
+ * </p>
+ *
+ * @see FirstOrderDifferentialEquations
+ *
+ * @version $Revision: 980981 $ $Date: 2010-07-31 00:03:04 +0200 (sam. 31 juil. 2010) $
+ * @since 2.2
+ */
+
+public interface ExtendedFirstOrderDifferentialEquations extends FirstOrderDifferentialEquations {
+
+    /** Return the dimension of the main set of equations.
+     * <p>
+     * The main set of equations represent the first part of an ODE state.
+     * The error estimations and adaptive step size computation should be
+     * done on this first part only, not on the final part of the state
+     * which represent an extension set of equations which are considered
+     * secondary.
+     * </p>
+     * @return dimension of the main set of equations, must be lesser than or
+     * equal to the {@link #getDimension() total dimension}
+     */
+    int getMainSetDimension();
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/FirstOrderConverter.java b/src/main/java/org/apache/commons/math/ode/FirstOrderConverter.java
new file mode 100644
index 0000000..b4712e5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/FirstOrderConverter.java
@@ -0,0 +1,119 @@
+/*
+ * 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.ode;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/** This class converts second order differential equations to first
+ * order ones.
+ *
+ * <p>This class is a wrapper around a {@link
+ * SecondOrderDifferentialEquations} which allow to use a {@link
+ * FirstOrderIntegrator} to integrate it.</p>
+ *
+ * <p>The transformation is done by changing the n dimension state
+ * vector to a 2n dimension vector, where the first n components are
+ * the initial state variables and the n last components are their
+ * first time derivative. The first time derivative of this state
+ * vector then really contains both the first and second time
+ * derivative of the initial state vector, which can be handled by the
+ * underlying second order equations set.</p>
+ *
+ * <p>One should be aware that the data is duplicated during the
+ * transformation process and that for each call to {@link
+ * #computeDerivatives computeDerivatives}, this wrapper does copy 4n
+ * scalars : 2n before the call to {@link
+ * SecondOrderDifferentialEquations#computeSecondDerivatives
+ * computeSecondDerivatives} in order to dispatch the y state vector
+ * into z and zDot, and 2n after the call to gather zDot and zDDot
+ * into yDot. Since the underlying problem by itself perhaps also
+ * needs to copy data and dispatch the arrays into domain objects,
+ * this has an impact on both memory and CPU usage. The only way to
+ * avoid this duplication is to perform the transformation at the
+ * problem level, i.e. to implement the problem as a first order one
+ * and then avoid using this class.</p>
+ *
+ * @see FirstOrderIntegrator
+ * @see FirstOrderDifferentialEquations
+ * @see SecondOrderDifferentialEquations
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public class FirstOrderConverter implements FirstOrderDifferentialEquations {
+
+    /** Underlying second order equations set. */
+    private final SecondOrderDifferentialEquations equations;
+
+    /** second order problem dimension. */
+    private final int dimension;
+
+    /** state vector. */
+    private final double[] z;
+
+    /** first time derivative of the state vector. */
+    private final double[] zDot;
+
+    /** second time derivative of the state vector. */
+    private final double[] zDDot;
+
+  /** Simple constructor.
+   * Build a converter around a second order equations set.
+   * @param equations second order equations set to convert
+   */
+  public FirstOrderConverter (final SecondOrderDifferentialEquations equations) {
+      this.equations = equations;
+      dimension      = equations.getDimension();
+      z              = new double[dimension];
+      zDot           = new double[dimension];
+      zDDot          = new double[dimension];
+  }
+
+  /** Get the dimension of the problem.
+   * <p>The dimension of the first order problem is twice the
+   * dimension of the underlying second order problem.</p>
+   * @return dimension of the problem
+   */
+  public int getDimension() {
+    return 2 * dimension;
+  }
+
+  /** Get the current time derivative of the state vector.
+   * @param t current value of the independent <I>time</I> variable
+   * @param y array containing the current value of the state vector
+   * @param yDot placeholder array where to put the time derivative of the state vector
+   * @throws DerivativeException this exception is propagated to the caller if the
+   * underlying user function triggers one
+   */
+  public void computeDerivatives(final double t, final double[] y, final double[] yDot)
+      throws DerivativeException {
+
+    // split the state vector in two
+    System.arraycopy(y, 0,         z,    0, dimension);
+    System.arraycopy(y, dimension, zDot, 0, dimension);
+
+    // apply the underlying equations set
+    equations.computeSecondDerivatives(t, z, zDot, zDDot);
+
+    // build the result state derivative
+    System.arraycopy(zDot,  0, yDot, 0,         dimension);
+    System.arraycopy(zDDot, 0, yDot, dimension, dimension);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/FirstOrderDifferentialEquations.java b/src/main/java/org/apache/commons/math/ode/FirstOrderDifferentialEquations.java
new file mode 100644
index 0000000..7c6aacc
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/FirstOrderDifferentialEquations.java
@@ -0,0 +1,66 @@
+/*
+ * 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.ode;
+
+
+
+/** This interface represents a first order differential equations set.
+ *
+ * <p>This interface should be implemented by all real first order
+ * differential equation problems before they can be handled by the
+ * integrators {@link FirstOrderIntegrator#integrate} method.</p>
+ *
+ * <p>A first order differential equations problem, as seen by an
+ * integrator is the time derivative <code>dY/dt</code> of a state
+ * vector <code>Y</code>, both being one dimensional arrays. From the
+ * integrator point of view, this derivative depends only on the
+ * current time <code>t</code> and on the state vector
+ * <code>Y</code>.</p>
+ *
+ * <p>For real problems, the derivative depends also on parameters
+ * that do not belong to the state vector (dynamical model constants
+ * for example). These constants are completely outside of the scope
+ * of this interface, the classes that implement it are allowed to
+ * handle them as they want.</p>
+ *
+ * @see FirstOrderIntegrator
+ * @see FirstOrderConverter
+ * @see SecondOrderDifferentialEquations
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface FirstOrderDifferentialEquations {
+
+    /** Get the dimension of the problem.
+     * @return dimension of the problem
+     */
+    int getDimension();
+
+    /** Get the current time derivative of the state vector.
+     * @param t current value of the independent <I>time</I> variable
+     * @param y array containing the current value of the state vector
+     * @param yDot placeholder array where to put the time derivative of the state vector
+     * @throws DerivativeException this user-defined exception should be used if an error is
+     * is triggered by user code
+     */
+    void computeDerivatives(double t, double[] y, double[] yDot)
+        throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/FirstOrderIntegrator.java b/src/main/java/org/apache/commons/math/ode/FirstOrderIntegrator.java
new file mode 100644
index 0000000..b833084
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/FirstOrderIntegrator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.ode;
+
+
+/** This interface represents a first order integrator for
+ * differential equations.
+
+ * <p>The classes which are devoted to solve first order differential
+ * equations should implement this interface. The problems which can
+ * be handled should implement the {@link
+ * FirstOrderDifferentialEquations} interface.</p>
+ *
+ * @see FirstOrderDifferentialEquations
+ * @see org.apache.commons.math.ode.sampling.StepHandler
+ * @see org.apache.commons.math.ode.events.EventHandler
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface FirstOrderIntegrator extends ODEIntegrator {
+
+  /** Integrate the differential equations up to the given time.
+   * <p>This method solves an Initial Value Problem (IVP).</p>
+   * <p>Since this method stores some internal state variables made
+   * available in its public interface during integration ({@link
+   * #getCurrentSignedStepsize()}), it is <em>not</em> thread-safe.</p>
+   * @param equations differential equations to integrate
+   * @param t0 initial time
+   * @param y0 initial value of the state vector at t0
+   * @param t target time for the integration
+   * (can be set to a value smaller than <code>t0</code> for backward integration)
+   * @param y placeholder where to put the state vector at each successful
+   *  step (and hence at the end of integration), can be the same object as y0
+   * @return stop time, will be the same as target time if integration reached its
+   * target, but may be different if some {@link
+   * org.apache.commons.math.ode.events.EventHandler} stops it at some point.
+   * @throws DerivativeException this exception is propagated to the caller if
+   * the underlying user function triggers one
+   * @throws IntegratorException if the integrator cannot perform integration
+   */
+  double integrate (FirstOrderDifferentialEquations equations,
+                    double t0, double[] y0,
+                    double t, double[] y) throws DerivativeException, IntegratorException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/IntegratorException.java b/src/main/java/org/apache/commons/math/ode/IntegratorException.java
new file mode 100644
index 0000000..b116225
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/IntegratorException.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ode;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * This exception is made available to users to report
+ * the error conditions that are triggered during integration
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 1.2
+ */
+public class IntegratorException
+  extends MathException {
+
+  /** Serializable version identifier */
+    private static final long serialVersionUID = -1607588949778036796L;
+
+    /** Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @deprecated as of 2.2 replaced by {@link #IntegratorException(Localizable, Object...)}
+     */
+    @Deprecated
+    public IntegratorException(final String specifier, final Object ... parts) {
+      super(specifier, parts);
+    }
+
+    /** Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @since 2.2
+     */
+    public IntegratorException(final Localizable specifier, final Object ... parts) {
+      super(specifier, parts);
+    }
+
+  /**
+   * Create an exception with a given root cause.
+   * @param cause  the exception or error that caused this exception to be thrown
+   */
+  public IntegratorException(final Throwable cause) {
+    super(cause);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/MultistepIntegrator.java b/src/main/java/org/apache/commons/math/ode/MultistepIntegrator.java
new file mode 100644
index 0000000..1794878
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/MultistepIntegrator.java
@@ -0,0 +1,412 @@
+/*
+ * 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.ode;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator;
+import org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class is the base class for multistep integrators for Ordinary
+ * Differential Equations.
+ * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as:
+ * <pre>
+ * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative
+ * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative
+ * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative
+ * ...
+ * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative
+ * </pre></p>
+ * <p>Rather than storing several previous steps separately, this implementation uses
+ * the Nordsieck vector with higher degrees scaled derivatives all taken at the same
+ * step (y<sub>n</sub>, s<sub>1</sub>(n) and r<sub>n</sub>) where r<sub>n</sub> is defined as:
+ * <pre>
+ * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup>
+ * </pre>
+ * (we omit the k index in the notation for clarity)</p>
+ * <p>
+ * Multistep integrators with Nordsieck representation are highly sensitive to
+ * large step changes because when the step is multiplied by a factor a, the
+ * k<sup>th</sup> component of the Nordsieck vector is multiplied by a<sup>k</sup>
+ * and the last components are the least accurate ones. The default max growth
+ * factor is therefore set to a quite low value: 2<sup>1/order</sup>.
+ * </p>
+ *
+ * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator
+ * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator {
+
+    /** First scaled derivative (h y'). */
+    protected double[] scaled;
+
+    /** Nordsieck matrix of the higher scaled derivatives.
+     * <p>(h<sup>2</sup>/2 y'', h<sup>3</sup>/6 y''' ..., h<sup>k</sup>/k! y(k))</p>
+     */
+    protected Array2DRowRealMatrix nordsieck;
+
+    /** Starter integrator. */
+    private FirstOrderIntegrator starter;
+
+    /** Number of steps of the multistep method (excluding the one being computed). */
+    private final int nSteps;
+
+    /** Stepsize control exponent. */
+    private double exp;
+
+    /** Safety factor for stepsize control. */
+    private double safety;
+
+    /** Minimal reduction factor for stepsize control. */
+    private double minReduction;
+
+    /** Maximal growth factor for stepsize control. */
+    private double maxGrowth;
+
+    /**
+     * Build a multistep integrator with the given stepsize bounds.
+     * <p>The default starter integrator is set to the {@link
+     * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with
+     * some defaults settings.</p>
+     * <p>
+     * The default max growth factor is set to a quite low value: 2<sup>1/order</sup>.
+     * </p>
+     * @param name name of the method
+     * @param nSteps number of steps of the multistep method
+     * (excluding the one being computed)
+     * @param order order of the method
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param scalAbsoluteTolerance allowed absolute error
+     * @param scalRelativeTolerance allowed relative error
+     */
+    protected MultistepIntegrator(final String name, final int nSteps,
+                                  final int order,
+                                  final double minStep, final double maxStep,
+                                  final double scalAbsoluteTolerance,
+                                  final double scalRelativeTolerance) {
+
+        super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+
+        if (nSteps <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INTEGRATION_METHOD_NEEDS_AT_LEAST_ONE_PREVIOUS_POINT,
+                  name);
+        }
+
+        starter = new DormandPrince853Integrator(minStep, maxStep,
+                                                 scalAbsoluteTolerance,
+                                                 scalRelativeTolerance);
+        this.nSteps = nSteps;
+
+        exp = -1.0 / order;
+
+        // set the default values of the algorithm control parameters
+        setSafety(0.9);
+        setMinReduction(0.2);
+        setMaxGrowth(FastMath.pow(2.0, -exp));
+
+    }
+
+    /**
+     * Build a multistep integrator with the given stepsize bounds.
+     * <p>The default starter integrator is set to the {@link
+     * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with
+     * some defaults settings.</p>
+     * <p>
+     * The default max growth factor is set to a quite low value: 2<sup>1/order</sup>.
+     * </p>
+     * @param name name of the method
+     * @param nSteps number of steps of the multistep method
+     * (excluding the one being computed)
+     * @param order order of the method
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param vecAbsoluteTolerance allowed absolute error
+     * @param vecRelativeTolerance allowed relative error
+     */
+    protected MultistepIntegrator(final String name, final int nSteps,
+                                  final int order,
+                                  final double minStep, final double maxStep,
+                                  final double[] vecAbsoluteTolerance,
+                                  final double[] vecRelativeTolerance) {
+        super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+        starter = new DormandPrince853Integrator(minStep, maxStep,
+                                                 vecAbsoluteTolerance,
+                                                 vecRelativeTolerance);
+        this.nSteps = nSteps;
+
+        exp = -1.0 / order;
+
+        // set the default values of the algorithm control parameters
+        setSafety(0.9);
+        setMinReduction(0.2);
+        setMaxGrowth(FastMath.pow(2.0, -exp));
+
+    }
+
+    /**
+     * Get the starter integrator.
+     * @return starter integrator
+     */
+    public ODEIntegrator getStarterIntegrator() {
+        return starter;
+    }
+
+    /**
+     * Set the starter integrator.
+     * <p>The various step and event handlers for this starter integrator
+     * will be managed automatically by the multi-step integrator. Any
+     * user configuration for these elements will be cleared before use.</p>
+     * @param starterIntegrator starter integrator
+     */
+    public void setStarterIntegrator(FirstOrderIntegrator starterIntegrator) {
+        this.starter = starterIntegrator;
+    }
+
+    /** Start the integration.
+     * <p>This method computes one step using the underlying starter integrator,
+     * and initializes the Nordsieck vector at step start. The starter integrator
+     * purpose is only to establish initial conditions, it does not really change
+     * time by itself. The top level multistep integrator remains in charge of
+     * handling time propagation and events handling as it will starts its own
+     * computation right from the beginning. In a sense, the starter integrator
+     * can be seen as a dummy one and so it will never trigger any user event nor
+     * call any user step handler.</p>
+     * @param t0 initial time
+     * @param y0 initial value of the state vector at t0
+     * @param t target time for the integration
+     * (can be set to a value smaller than <code>t0</code> for backward integration)
+     * @throws IntegratorException if the integrator cannot perform integration
+     * @throws DerivativeException this exception is propagated to the caller if
+     * the underlying user function triggers one
+     */
+    protected void start(final double t0, final double[] y0, final double t)
+        throws DerivativeException, IntegratorException {
+
+        // make sure NO user event nor user step handler is triggered,
+        // this is the task of the top level integrator, not the task
+        // of the starter integrator
+        starter.clearEventHandlers();
+        starter.clearStepHandlers();
+
+        // set up one specific step handler to extract initial Nordsieck vector
+        starter.addStepHandler(new NordsieckInitializer(y0.length));
+
+        // start integration, expecting a InitializationCompletedMarkerException
+        try {
+            starter.integrate(new CountingDifferentialEquations(y0.length),
+                              t0, y0, t, new double[y0.length]);
+        } catch (DerivativeException mue) {
+            if (!(mue instanceof InitializationCompletedMarkerException)) {
+                // this is not the expected nominal interruption of the start integrator
+                throw mue;
+            }
+        }
+
+        // remove the specific step handler
+        starter.clearStepHandlers();
+
+    }
+
+    /** Initialize the high order scaled derivatives at step start.
+     * @param first first scaled derivative at step start
+     * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1)
+     * will be modified
+     * @return high order scaled derivatives at step start
+     */
+    protected abstract Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first,
+                                                                           final double[][] multistep);
+
+    /** Get the minimal reduction factor for stepsize control.
+     * @return minimal reduction factor
+     */
+    public double getMinReduction() {
+        return minReduction;
+    }
+
+    /** Set the minimal reduction factor for stepsize control.
+     * @param minReduction minimal reduction factor
+     */
+    public void setMinReduction(final double minReduction) {
+        this.minReduction = minReduction;
+    }
+
+    /** Get the maximal growth factor for stepsize control.
+     * @return maximal growth factor
+     */
+    public double getMaxGrowth() {
+        return maxGrowth;
+    }
+
+    /** Set the maximal growth factor for stepsize control.
+     * @param maxGrowth maximal growth factor
+     */
+    public void setMaxGrowth(final double maxGrowth) {
+        this.maxGrowth = maxGrowth;
+    }
+
+    /** Get the safety factor for stepsize control.
+     * @return safety factor
+     */
+    public double getSafety() {
+      return safety;
+    }
+
+    /** Set the safety factor for stepsize control.
+     * @param safety safety factor
+     */
+    public void setSafety(final double safety) {
+      this.safety = safety;
+    }
+
+    /** Compute step grow/shrink factor according to normalized error.
+     * @param error normalized error of the current step
+     * @return grow/shrink factor for next step
+     */
+    protected double computeStepGrowShrinkFactor(final double error) {
+        return FastMath.min(maxGrowth, FastMath.max(minReduction, safety * FastMath.pow(error, exp)));
+    }
+
+    /** Transformer used to convert the first step to Nordsieck representation. */
+    public static interface NordsieckTransformer {
+        /** Initialize the high order scaled derivatives at step start.
+         * @param first first scaled derivative at step start
+         * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1)
+         * will be modified
+         * @return high order derivatives at step start
+         */
+        RealMatrix initializeHighOrderDerivatives(double[] first, double[][] multistep);
+    }
+
+    /** Specialized step handler storing the first step. */
+    private class NordsieckInitializer implements StepHandler {
+
+        /** Problem dimension. */
+        private final int n;
+
+        /** Simple constructor.
+         * @param n problem dimension
+         */
+        public NordsieckInitializer(final int n) {
+            this.n = n;
+        }
+
+        /** {@inheritDoc} */
+        public void handleStep(StepInterpolator interpolator, boolean isLast)
+            throws DerivativeException {
+
+            final double prev = interpolator.getPreviousTime();
+            final double curr = interpolator.getCurrentTime();
+            stepStart = prev;
+            stepSize  = (curr - prev) / (nSteps + 1);
+
+            // compute the first scaled derivative
+            interpolator.setInterpolatedTime(prev);
+            scaled = interpolator.getInterpolatedDerivatives().clone();
+            for (int j = 0; j < n; ++j) {
+                scaled[j] *= stepSize;
+            }
+
+            // compute the high order scaled derivatives
+            final double[][] multistep = new double[nSteps][];
+            for (int i = 1; i <= nSteps; ++i) {
+                interpolator.setInterpolatedTime(prev + stepSize * i);
+                final double[] msI = interpolator.getInterpolatedDerivatives().clone();
+                for (int j = 0; j < n; ++j) {
+                    msI[j] *= stepSize;
+                }
+                multistep[i - 1] = msI;
+            }
+            nordsieck = initializeHighOrderDerivatives(scaled, multistep);
+
+            // stop the integrator after the first step has been handled
+            throw new InitializationCompletedMarkerException();
+
+        }
+
+        /** {@inheritDoc} */
+        public boolean requiresDenseOutput() {
+            return true;
+        }
+
+        /** {@inheritDoc} */
+        public void reset() {
+            // nothing to do
+        }
+
+    }
+
+    /** Marker exception used ONLY to stop the starter integrator after first step. */
+    private static class InitializationCompletedMarkerException
+        extends DerivativeException {
+
+        /** Serializable version identifier. */
+        private static final long serialVersionUID = -4105805787353488365L;
+
+        /** Simple constructor. */
+        public InitializationCompletedMarkerException() {
+            super((Throwable) null);
+        }
+
+    }
+
+    /** Wrapper for differential equations, ensuring start evaluations are counted. */
+    private class CountingDifferentialEquations implements ExtendedFirstOrderDifferentialEquations {
+
+        /** Dimension of the problem. */
+        private final int dimension;
+
+        /** Simple constructor.
+         * @param dimension dimension of the problem
+         */
+        public CountingDifferentialEquations(final int dimension) {
+            this.dimension = dimension;
+        }
+
+        /** {@inheritDoc} */
+        public void computeDerivatives(double t, double[] y, double[] dot)
+                throws DerivativeException {
+            MultistepIntegrator.this.computeDerivatives(t, y, dot);
+        }
+
+        /** {@inheritDoc} */
+        public int getDimension() {
+            return dimension;
+        }
+
+        /** {@inheritDoc} */
+        public int getMainSetDimension() {
+            return mainSetDimension;
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/ODEIntegrator.java b/src/main/java/org/apache/commons/math/ode/ODEIntegrator.java
new file mode 100644
index 0000000..6343478
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/ODEIntegrator.java
@@ -0,0 +1,138 @@
+/*
+ * 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.ode;
+
+import java.util.Collection;
+
+import org.apache.commons.math.ode.events.EventHandler;
+import org.apache.commons.math.ode.sampling.StepHandler;
+
+/**
+ * This interface defines the common parts shared by integrators
+ * for first and second order differential equations.
+ * @see FirstOrderIntegrator
+ * @see SecondOrderIntegrator
+ * @version $Revision: 1061507 $ $Date: 2011-01-20 21:55:00 +0100 (jeu. 20 janv. 2011) $
+ * @since 2.0
+ */
+public interface ODEIntegrator  {
+
+    /** Get the name of the method.
+     * @return name of the method
+     */
+    String getName();
+
+    /** Add a step handler to this integrator.
+     * <p>The handler will be called by the integrator for each accepted
+     * step.</p>
+     * @param handler handler for the accepted steps
+     * @see #getStepHandlers()
+     * @see #clearStepHandlers()
+     * @since 2.0
+     */
+    void addStepHandler(StepHandler handler);
+
+    /** Get all the step handlers that have been added to the integrator.
+     * @return an unmodifiable collection of the added events handlers
+     * @see #addStepHandler(StepHandler)
+     * @see #clearStepHandlers()
+     * @since 2.0
+     */
+    Collection<StepHandler> getStepHandlers();
+
+    /** Remove all the step handlers that have been added to the integrator.
+     * @see #addStepHandler(StepHandler)
+     * @see #getStepHandlers()
+     * @since 2.0
+     */
+    void clearStepHandlers();
+
+    /** Add an event handler to the integrator.
+     * @param handler event handler
+     * @param maxCheckInterval maximal time interval between switching
+     * function checks (this interval prevents missing sign changes in
+     * case the integration steps becomes very large)
+     * @param convergence convergence threshold in the event time search
+     * @param maxIterationCount upper limit of the iteration count in
+     * the event time search
+     * @see #getEventHandlers()
+     * @see #clearEventHandlers()
+     */
+    void addEventHandler(EventHandler handler, double maxCheckInterval,
+                         double convergence, int maxIterationCount);
+
+    /** Get all the event handlers that have been added to the integrator.
+     * @return an unmodifiable collection of the added events handlers
+     * @see #addEventHandler(EventHandler, double, double, int)
+     * @see #clearEventHandlers()
+     */
+    Collection<EventHandler> getEventHandlers();
+
+    /** Remove all the event handlers that have been added to the integrator.
+     * @see #addEventHandler(EventHandler, double, double, int)
+     * @see #getEventHandlers()
+     */
+    void clearEventHandlers();
+
+    /** Get the current value of the step start time t<sub>i</sub>.
+     * <p>This method can be called during integration (typically by
+     * the object implementing the {@link FirstOrderDifferentialEquations
+     * differential equations} problem) if the value of the current step that
+     * is attempted is needed.</p>
+     * <p>The result is undefined if the method is called outside of
+     * calls to <code>integrate</code>.</p>
+     * @return current value of the step start time t<sub>i</sub>
+     */
+    double getCurrentStepStart();
+
+    /** Get the current signed value of the integration stepsize.
+     * <p>This method can be called during integration (typically by
+     * the object implementing the {@link FirstOrderDifferentialEquations
+     * differential equations} problem) if the signed value of the current stepsize
+     * that is tried is needed.</p>
+     * <p>The result is undefined if the method is called outside of
+     * calls to <code>integrate</code>.</p>
+     * @return current signed value of the stepsize
+     */
+    double getCurrentSignedStepsize();
+
+    /** Set the maximal number of differential equations function evaluations.
+     * <p>The purpose of this method is to avoid infinite loops which can occur
+     * for example when stringent error constraints are set or when lots of
+     * discrete events are triggered, thus leading to many rejected steps.</p>
+     * @param maxEvaluations maximal number of function evaluations (negative
+     * values are silently converted to maximal integer value, thus representing
+     * almost unlimited evaluations)
+     */
+    void setMaxEvaluations(int maxEvaluations);
+
+    /** Get the maximal number of functions evaluations.
+     * @return maximal number of functions evaluations
+     */
+    int getMaxEvaluations();
+
+    /** Get the number of evaluations of the differential equations function.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * <code>integrate</code> method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the differential equations function
+     */
+    int getEvaluations();
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/SecondOrderDifferentialEquations.java b/src/main/java/org/apache/commons/math/ode/SecondOrderDifferentialEquations.java
new file mode 100644
index 0000000..d5e7324
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/SecondOrderDifferentialEquations.java
@@ -0,0 +1,69 @@
+/*
+ * 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.ode;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/** This interface represents a second order differential equations set.
+
+ * <p>This interface should be implemented by all real second order
+ * differential equation problems before they can be handled by the
+ * integrators {@link SecondOrderIntegrator#integrate} method.</p>
+ *
+ * <p>A second order differential equations problem, as seen by an
+ * integrator is the second time derivative <code>d2Y/dt^2</code> of a
+ * state vector <code>Y</code>, both being one dimensional
+ * arrays. From the integrator point of view, this derivative depends
+ * only on the current time <code>t</code>, on the state vector
+ * <code>Y</code> and on the first time derivative of the state
+ * vector.</p>
+ *
+ * <p>For real problems, the derivative depends also on parameters
+ * that do not belong to the state vector (dynamical model constants
+ * for example). These constants are completely outside of the scope
+ * of this interface, the classes that implement it are allowed to
+ * handle them as they want.</p>
+ *
+ * @see SecondOrderIntegrator
+ * @see FirstOrderConverter
+ * @see FirstOrderDifferentialEquations
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface SecondOrderDifferentialEquations {
+
+    /** Get the dimension of the problem.
+     * @return dimension of the problem
+     */
+    int getDimension();
+
+    /** Get the current time derivative of the state vector.
+     * @param t current value of the independent <I>time</I> variable
+     * @param y array containing the current value of the state vector
+     * @param yDot array containing the current value of the first derivative
+     * of the state vector
+     * @param yDDot placeholder array where to put the second time derivative
+     * of the state vector
+     * @throws DerivativeException this user-defined exception should be used if an error is
+     * is triggered by user code
+     */
+    void computeSecondDerivatives(double t, double[] y, double[] yDot, double[] yDDot)
+        throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/SecondOrderIntegrator.java b/src/main/java/org/apache/commons/math/ode/SecondOrderIntegrator.java
new file mode 100644
index 0000000..f744e85
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/SecondOrderIntegrator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.ode;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+
+/** This interface represents a second order integrator for
+ * differential equations.
+ *
+ * <p>The classes which are devoted to solve second order differential
+ * equations should implement this interface. The problems which can
+ * be handled should implement the {@link
+ * SecondOrderDifferentialEquations} interface.</p>
+ *
+ * @see SecondOrderDifferentialEquations
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface SecondOrderIntegrator extends ODEIntegrator {
+
+  /** Integrate the differential equations up to the given time
+   * @param equations differential equations to integrate
+   * @param t0 initial time
+   * @param y0 initial value of the state vector at t0
+   * @param yDot0 initial value of the first derivative of the state
+   * vector at t0
+   * @param t target time for the integration
+   * (can be set to a value smaller thant <code>t0</code> for backward integration)
+   * @param y placeholder where to put the state vector at each
+   * successful step (and hence at the end of integration), can be the
+   * same object as y0
+   * @param yDot placeholder where to put the first derivative of
+   * the state vector at time t, can be the same object as yDot0
+   * @throws IntegratorException if the integrator cannot perform integration
+   * @throws DerivativeException this exception is propagated to the caller if the
+   * underlying user function triggers one
+   */
+  void integrate(SecondOrderDifferentialEquations equations,
+                 double t0, double[] y0, double[] yDot0,
+                 double t, double[] y, double[] yDot)
+      throws DerivativeException, IntegratorException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/events/CombinedEventsManager.java b/src/main/java/org/apache/commons/math/ode/events/CombinedEventsManager.java
new file mode 100644
index 0000000..1886702
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/events/CombinedEventsManager.java
@@ -0,0 +1,249 @@
+/*
+ * 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.ode.events;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/** This class manages several {@link EventHandler event handlers} during integration.
+ *
+ * @see EventHandler
+ * @see EventState
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ * @deprecated as of 2.2, this class is not used anymore
+ */
+@Deprecated
+public class CombinedEventsManager {
+
+    /** Events states. */
+    private final List<EventState> states;
+
+    /** First active event. */
+    private EventState first;
+
+    /** Initialization indicator. */
+    private boolean initialized;
+
+    /** Simple constructor.
+     * Create an empty manager
+     */
+    public CombinedEventsManager() {
+        states      = new ArrayList<EventState>();
+        first       = null;
+        initialized = false;
+    }
+
+    /** Add an events handler.
+     * @param handler event handler
+     * @param maxCheckInterval maximal time interval between events
+     * checks (this interval prevents missing sign changes in
+     * case the integration steps becomes very large)
+     * @param convergence convergence threshold in the event time search
+     * @param maxIterationCount upper limit of the iteration count in
+     * the event time search
+     * @see #getEventsHandlers()
+     * @see #clearEventsHandlers()
+     */
+    public void addEventHandler(final EventHandler handler, final double maxCheckInterval,
+                                final double convergence, final int maxIterationCount) {
+        states.add(new EventState(handler, maxCheckInterval,
+                                  convergence, maxIterationCount));
+    }
+
+    /** Get all the events handlers that have been added to the manager.
+     * @return an unmodifiable collection of the added event handlers
+     * @see #addEventHandler(EventHandler, double, double, int)
+     * @see #clearEventsHandlers()
+     * @see #getEventsStates()
+     */
+    public Collection<EventHandler> getEventsHandlers() {
+        final List<EventHandler> list = new ArrayList<EventHandler>();
+        for (EventState state : states) {
+            list.add(state.getEventHandler());
+        }
+        return Collections.unmodifiableCollection(list);
+    }
+
+    /** Remove all the events handlers that have been added to the manager.
+     * @see #addEventHandler(EventHandler, double, double, int)
+     * @see #getEventsHandlers()
+     */
+    public void clearEventsHandlers() {
+        states.clear();
+    }
+
+    /** Get all the events state wrapping the handlers that have been added to the manager.
+     * @return a collection of the events states
+     * @see #getEventsHandlers()
+     */
+    public Collection<EventState> getEventsStates() {
+        return states;
+    }
+
+    /** Check if the manager does not manage any event handlers.
+     * @return true if manager is empty
+     */
+    public boolean isEmpty() {
+        return states.isEmpty();
+    }
+
+    /** Evaluate the impact of the proposed step on all managed
+     * event handlers.
+     * @param interpolator step interpolator for the proposed step
+     * @return true if at least one event handler triggers an event
+     * before the end of the proposed step (this implies the step should
+     * be rejected)
+     * @exception DerivativeException if the interpolator fails to
+     * compute the function somewhere within the step
+     * @exception IntegratorException if an event cannot be located
+     */
+    public boolean evaluateStep(final StepInterpolator interpolator)
+    throws DerivativeException, IntegratorException {
+
+        try {
+
+            first = null;
+            if (states.isEmpty()) {
+                // there is nothing to do, return now to avoid setting the
+                // interpolator time (and hence avoid unneeded calls to the
+                // user function due to interpolator finalization)
+                return false;
+            }
+
+            if (! initialized) {
+
+                // initialize the events states
+                for (EventState state : states) {
+                    state.reinitializeBegin(interpolator);
+                }
+
+                initialized = true;
+
+            }
+
+            // check events occurrence
+            for (EventState state : states) {
+
+                if (state.evaluateStep(interpolator)) {
+                    if (first == null) {
+                        first = state;
+                    } else {
+                        if (interpolator.isForward()) {
+                            if (state.getEventTime() < first.getEventTime()) {
+                                first = state;
+                            }
+                        } else {
+                            if (state.getEventTime() > first.getEventTime()) {
+                                first = state;
+                            }
+                        }
+                    }
+                }
+
+            }
+
+            return first != null;
+
+        } catch (EventException se) {
+            final Throwable cause = se.getCause();
+            if ((cause != null) && (cause instanceof DerivativeException)) {
+                throw (DerivativeException) cause;
+            }
+            throw new IntegratorException(se);
+        } catch (ConvergenceException ce) {
+            throw new IntegratorException(ce);
+        }
+
+    }
+
+    /** Get the occurrence time of the first event triggered in the
+     * last evaluated step.
+     * @return occurrence time of the first event triggered in the last
+     * evaluated step, or </code>Double.NaN</code> if no event is
+     * triggered
+     */
+    public double getEventTime() {
+        return (first == null) ? Double.NaN : first.getEventTime();
+    }
+
+    /** Inform the event handlers that the step has been accepted
+     * by the integrator.
+     * @param t value of the independent <i>time</i> variable at the
+     * end of the step
+     * @param y array containing the current value of the state vector
+     * at the end of the step
+     * @exception IntegratorException if the value of one of the
+     * events states cannot be evaluated
+     */
+    public void stepAccepted(final double t, final double[] y)
+    throws IntegratorException {
+        try {
+            for (EventState state : states) {
+                state.stepAccepted(t, y);
+            }
+        } catch (EventException se) {
+            throw new IntegratorException(se);
+        }
+    }
+
+    /** Check if the integration should be stopped at the end of the
+     * current step.
+     * @return true if the integration should be stopped
+     */
+    public boolean stop() {
+        for (EventState state : states) {
+            if (state.stop()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** Let the event handlers reset the state if they want.
+     * @param t value of the independent <i>time</i> variable at the
+     * beginning of the next step
+     * @param y array were to put the desired state vector at the beginning
+     * of the next step
+     * @return true if the integrator should reset the derivatives too
+     * @exception IntegratorException if one of the events states
+     * that should reset the state fails to do it
+     */
+    public boolean reset(final double t, final double[] y)
+        throws IntegratorException {
+        try {
+            boolean resetDerivatives = false;
+            for (EventState state : states) {
+                if (state.reset(t, y)) {
+                    resetDerivatives = true;
+                }
+            }
+            return resetDerivatives;
+        } catch (EventException se) {
+            throw new IntegratorException(se);
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/events/EventException.java b/src/main/java/org/apache/commons/math/ode/events/EventException.java
new file mode 100644
index 0000000..92e8e0c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/events/EventException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ode.events;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * This exception is made available to users to report
+ * the error conditions that are triggered by {@link EventHandler}
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class EventException extends MathException {
+
+    /** Serialization UID. */
+    private static final long serialVersionUID = -898215297400035290L;
+
+    /** Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @deprecated as of 2.2 replaced by {@link #EventException(Localizable, Object...)}
+     */
+     @Deprecated
+    public EventException(final String specifier, final Object ... parts) {
+        super(specifier, parts);
+    }
+
+    /** Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @since 2.2
+     */
+    public EventException(final Localizable specifier, final Object ... parts) {
+        super(specifier, parts);
+    }
+
+    /**
+     * Create an exception with a given root cause.
+     * @param cause  the exception or error that caused this exception to be thrown
+     */
+    public EventException(final Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/events/EventHandler.java b/src/main/java/org/apache/commons/math/ode/events/EventHandler.java
new file mode 100644
index 0000000..4e50db6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/events/EventHandler.java
@@ -0,0 +1,183 @@
+/*
+ * 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.ode.events;
+
+/** This interface represents a handler for discrete events triggered
+ * during ODE integration.
+ *
+ * <p>Some events can be triggered at discrete times as an ODE problem
+ * is solved. This occurs for example when the integration process
+ * should be stopped as some state is reached (G-stop facility) when the
+ * precise date is unknown a priori, or when the derivatives have
+ * discontinuities, or simply when the user wants to monitor some
+ * states boundaries crossings.
+ * </p>
+ *
+ * <p>These events are defined as occurring when a <code>g</code>
+ * switching function sign changes.</p>
+ *
+ * <p>Since events are only problem-dependent and are triggered by the
+ * independent <i>time</i> variable and the state vector, they can
+ * occur at virtually any time, unknown in advance. The integrators will
+ * take care to avoid sign changes inside the steps, they will reduce
+ * the step size when such an event is detected in order to put this
+ * event exactly at the end of the current step. This guarantees that
+ * step interpolation (which always has a one step scope) is relevant
+ * even in presence of discontinuities. This is independent from the
+ * stepsize control provided by integrators that monitor the local
+ * error (this event handling feature is available for all integrators,
+ * including fixed step ones).</p>
+ *
+ * @version $Revision: 1067500 $ $Date: 2011-02-05 21:11:30 +0100 (sam. 05 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface EventHandler  {
+
+  /** Stop indicator.
+   * <p>This value should be used as the return value of the {@link
+   * #eventOccurred eventOccurred} method when the integration should be
+   * stopped after the event ending the current step.</p>
+   */
+  int STOP = 0;
+
+  /** Reset state indicator.
+   * <p>This value should be used as the return value of the {@link
+   * #eventOccurred eventOccurred} method when the integration should
+   * go on after the event ending the current step, with a new state
+   * vector (which will be retrieved thanks to the {@link #resetState
+   * resetState} method).</p>
+   */
+  int RESET_STATE = 1;
+
+  /** Reset derivatives indicator.
+   * <p>This value should be used as the return value of the {@link
+   * #eventOccurred eventOccurred} method when the integration should
+   * go on after the event ending the current step, with a new derivatives
+   * vector (which will be retrieved thanks to the {@link
+   * org.apache.commons.math.ode.FirstOrderDifferentialEquations#computeDerivatives}
+   * method).</p>
+   */
+  int RESET_DERIVATIVES = 2;
+
+  /** Continue indicator.
+   * <p>This value should be used as the return value of the {@link
+   * #eventOccurred eventOccurred} method when the integration should go
+   * on after the event ending the current step.</p>
+   */
+  int CONTINUE = 3;
+
+  /** Compute the value of the switching function.
+
+   * <p>The discrete events are generated when the sign of this
+   * switching function changes. The integrator will take care to change
+   * the stepsize in such a way these events occur exactly at step boundaries.
+   * The switching function must be continuous in its roots neighborhood
+   * (but not necessarily smooth), as the integrator will need to find its
+   * roots to locate precisely the events.</p>
+   *
+   * @param t current value of the independent <i>time</i> variable
+   * @param y array containing the current value of the state vector
+   * @return value of the g switching function
+   * @exception EventException if the switching function cannot be evaluated
+   */
+  double g(double t, double[] y) throws EventException;
+
+  /** Handle an event and choose what to do next.
+
+   * <p>This method is called when the integrator has accepted a step
+   * ending exactly on a sign change of the function, just <em>before</em>
+   * the step handler itself is called (see below for scheduling). It
+   * allows the user to update his internal data to acknowledge the fact
+   * the event has been handled (for example setting a flag in the {@link
+   * org.apache.commons.math.ode.FirstOrderDifferentialEquations
+   * differential equations} to switch the derivatives computation in
+   * case of discontinuity), or to direct the integrator to either stop
+   * or continue integration, possibly with a reset state or derivatives.</p>
+   *
+   * <ul>
+   *   <li>if {@link #STOP} is returned, the step handler will be called
+   *   with the <code>isLast</code> flag of the {@link
+   *   org.apache.commons.math.ode.sampling.StepHandler#handleStep handleStep}
+   *   method set to true and the integration will be stopped,</li>
+   *   <li>if {@link #RESET_STATE} is returned, the {@link #resetState
+   *   resetState} method will be called once the step handler has
+   *   finished its task, and the integrator will also recompute the
+   *   derivatives,</li>
+   *   <li>if {@link #RESET_DERIVATIVES} is returned, the integrator
+   *   will recompute the derivatives,
+   *   <li>if {@link #CONTINUE} is returned, no specific action will
+   *   be taken (apart from having called this method) and integration
+   *   will continue.</li>
+   * </ul>
+   *
+   * <p>The scheduling between this method and the {@link
+   * org.apache.commons.math.ode.sampling.StepHandler StepHandler} method {@link
+   * org.apache.commons.math.ode.sampling.StepHandler#handleStep(
+   * org.apache.commons.math.ode.sampling.StepInterpolator, boolean)
+   * handleStep(interpolator, isLast)} is to call this method first and
+   * <code>handleStep</code> afterwards. This scheduling allows the integrator to
+   * pass <code>true</code> as the <code>isLast</code> parameter to the step
+   * handler to make it aware the step will be the last one if this method
+   * returns {@link #STOP}. As the interpolator may be used to navigate back
+   * throughout the last step (as {@link
+   * org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer}
+   * does for example), user code called by this method and user
+   * code called by step handlers may experience apparently out of order values
+   * of the independent time variable. As an example, if the same user object
+   * implements both this {@link EventHandler EventHandler} interface and the
+   * {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler}
+   * interface, a <em>forward</em> integration may call its
+   * <code>eventOccurred</code> method with t = 10 first and call its
+   * <code>handleStep</code> method with t = 9 afterwards. Such out of order
+   * calls are limited to the size of the integration step for {@link
+   * org.apache.commons.math.ode.sampling.StepHandler variable step handlers} and
+   * to the size of the fixed step for {@link
+   * org.apache.commons.math.ode.sampling.FixedStepHandler fixed step handlers}.</p>
+   *
+   * @param t current value of the independent <i>time</i> variable
+   * @param y array containing the current value of the state vector
+   * @param increasing if true, the value of the switching function increases
+   * when times increases around event (note that increase is measured with respect
+   * to physical time, not with respect to integration which may go backward in time)
+   * @return indication of what the integrator should do next, this
+   * value must be one of {@link #STOP}, {@link #RESET_STATE},
+   * {@link #RESET_DERIVATIVES} or {@link #CONTINUE}
+   * @exception EventException if the event occurrence triggers an error
+   */
+  int eventOccurred(double t, double[] y, boolean increasing) throws EventException;
+
+  /** Reset the state prior to continue the integration.
+
+   * <p>This method is called after the step handler has returned and
+   * before the next step is started, but only when {@link
+   * #eventOccurred} has itself returned the {@link #RESET_STATE}
+   * indicator. It allows the user to reset the state vector for the
+   * next step, without perturbing the step handler of the finishing
+   * step. If the {@link #eventOccurred} never returns the {@link
+   * #RESET_STATE} indicator, this function will never be called, and it is
+   * safe to leave its body empty.</p>
+   *
+   * @param t current value of the independent <i>time</i> variable
+   * @param y array containing the current value of the state vector
+   * the new state should be put in the same array
+   * @exception EventException if the state cannot be reseted
+   */
+  void resetState(double t, double[] y) throws EventException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/events/EventState.java b/src/main/java/org/apache/commons/math/ode/events/EventState.java
new file mode 100644
index 0000000..30cb47e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/events/EventState.java
@@ -0,0 +1,431 @@
+/*
+ * 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.ode.events;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.solvers.BrentSolver;
+import org.apache.commons.math.exception.MathInternalError;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+import org.apache.commons.math.util.FastMath;
+
+/** This class handles the state for one {@link EventHandler
+ * event handler} during integration steps.
+ *
+ * <p>Each time the integrator proposes a step, the event handler
+ * switching function should be checked. This class handles the state
+ * of one handler during one integration step, with references to the
+ * state at the end of the preceding step. This information is used to
+ * decide if the handler should trigger an event or not during the
+ * proposed step (and hence the step should be reduced to ensure the
+ * event occurs at a bound rather than inside the step).</p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+public class EventState {
+
+    /** Event handler. */
+    private final EventHandler handler;
+
+    /** Maximal time interval between events handler checks. */
+    private final double maxCheckInterval;
+
+    /** Convergence threshold for event localization. */
+    private final double convergence;
+
+    /** Upper limit in the iteration count for event localization. */
+    private final int maxIterationCount;
+
+    /** Time at the beginning of the step. */
+    private double t0;
+
+    /** Value of the events handler at the beginning of the step. */
+    private double g0;
+
+    /** Simulated sign of g0 (we cheat when crossing events). */
+    private boolean g0Positive;
+
+    /** Indicator of event expected during the step. */
+    private boolean pendingEvent;
+
+    /** Occurrence time of the pending event. */
+    private double pendingEventTime;
+
+    /** Occurrence time of the previous event. */
+    private double previousEventTime;
+
+    /** Integration direction. */
+    private boolean forward;
+
+    /** Variation direction around pending event.
+     *  (this is considered with respect to the integration direction)
+     */
+    private boolean increasing;
+
+    /** Next action indicator. */
+    private int nextAction;
+
+    /** Simple constructor.
+     * @param handler event handler
+     * @param maxCheckInterval maximal time interval between switching
+     * function checks (this interval prevents missing sign changes in
+     * case the integration steps becomes very large)
+     * @param convergence convergence threshold in the event time search
+     * @param maxIterationCount upper limit of the iteration count in
+     * the event time search
+     */
+    public EventState(final EventHandler handler, final double maxCheckInterval,
+                      final double convergence, final int maxIterationCount) {
+        this.handler           = handler;
+        this.maxCheckInterval  = maxCheckInterval;
+        this.convergence       = FastMath.abs(convergence);
+        this.maxIterationCount = maxIterationCount;
+
+        // some dummy values ...
+        t0                = Double.NaN;
+        g0                = Double.NaN;
+        g0Positive        = true;
+        pendingEvent      = false;
+        pendingEventTime  = Double.NaN;
+        previousEventTime = Double.NaN;
+        increasing        = true;
+        nextAction        = EventHandler.CONTINUE;
+
+    }
+
+    /** Get the underlying event handler.
+     * @return underlying event handler
+     */
+    public EventHandler getEventHandler() {
+        return handler;
+    }
+
+    /** Get the maximal time interval between events handler checks.
+     * @return maximal time interval between events handler checks
+     */
+    public double getMaxCheckInterval() {
+        return maxCheckInterval;
+    }
+
+    /** Get the convergence threshold for event localization.
+     * @return convergence threshold for event localization
+     */
+    public double getConvergence() {
+        return convergence;
+    }
+
+    /** Get the upper limit in the iteration count for event localization.
+     * @return upper limit in the iteration count for event localization
+     */
+    public int getMaxIterationCount() {
+        return maxIterationCount;
+    }
+
+    /** Reinitialize the beginning of the step.
+     * @param interpolator valid for the current step
+     * @exception EventException if the event handler
+     * value cannot be evaluated at the beginning of the step
+     */
+    public void reinitializeBegin(final StepInterpolator interpolator)
+        throws EventException {
+        try {
+            // excerpt from MATH-421 issue:
+            // If an ODE solver is setup with an EventHandler that return STOP
+            // when the even is triggered, the integrator stops (which is exactly
+            // the expected behavior). If however the user want to restart the
+            // solver from the final state reached at the event with the same
+            // configuration (expecting the event to be triggered again at a
+            // later time), then the integrator may fail to start. It can get stuck
+            // at the previous event.
+
+            // The use case for the bug MATH-421 is fairly general, so events occurring
+            // less than epsilon after the solver start in the first step should be ignored,
+            // where epsilon is the convergence threshold of the event. The sign of the g
+            // function should be evaluated after this initial ignore zone, not exactly at
+            // beginning (if there are no event at the very beginning g(t0) and g(t0+epsilon)
+            // have the same sign, so this does not hurt ; if there is an event at the very
+            // beginning, g(t0) and g(t0+epsilon) have opposite signs and we want to start
+            // with the second one. Of course, the sign of epsilon depend on the integration
+            // direction (forward or backward). This explains what is done below.
+
+            final double ignoreZone = interpolator.isForward() ? getConvergence() : -getConvergence();
+            t0 = interpolator.getPreviousTime() + ignoreZone;
+            interpolator.setInterpolatedTime(t0);
+            g0 = handler.g(t0, interpolator.getInterpolatedState());
+            if (g0 == 0) {
+                // extremely rare case: there is a zero EXACTLY at end of ignore zone
+                // we will use the opposite of sign at step beginning to force ignoring this zero
+                final double tStart = interpolator.getPreviousTime();
+                interpolator.setInterpolatedTime(tStart);
+                g0Positive = handler.g(tStart, interpolator.getInterpolatedState()) <= 0;
+            } else {
+                g0Positive = g0 >= 0;
+            }
+
+        } catch (DerivativeException mue) {
+            throw new EventException(mue);
+        }
+    }
+
+    /** Evaluate the impact of the proposed step on the event handler.
+     * @param interpolator step interpolator for the proposed step
+     * @return true if the event handler triggers an event before
+     * the end of the proposed step
+     * @exception DerivativeException if the interpolator fails to
+     * compute the switching function somewhere within the step
+     * @exception EventException if the switching function
+     * cannot be evaluated
+     * @exception ConvergenceException if an event cannot be located
+     */
+    public boolean evaluateStep(final StepInterpolator interpolator)
+        throws DerivativeException, EventException, ConvergenceException {
+
+        try {
+
+            forward = interpolator.isForward();
+            final double t1 = interpolator.getCurrentTime();
+            if (FastMath.abs(t1 - t0) < convergence) {
+                // we cannot do anything on such a small step, don't trigger any events
+                return false;
+            }
+            final double start = forward ? (t0 + convergence) : t0 - convergence;
+            final double dt    = t1 - start;
+            final int    n     = FastMath.max(1, (int) FastMath.ceil(FastMath.abs(dt) / maxCheckInterval));
+            final double h     = dt / n;
+
+            double ta = t0;
+            double ga = g0;
+            for (int i = 0; i < n; ++i) {
+
+                // evaluate handler value at the end of the substep
+                final double tb = start + (i + 1) * h;
+                interpolator.setInterpolatedTime(tb);
+                final double gb = handler.g(tb, interpolator.getInterpolatedState());
+
+                // check events occurrence
+                if (g0Positive ^ (gb >= 0)) {
+                    // there is a sign change: an event is expected during this step
+
+                    // variation direction, with respect to the integration direction
+                    increasing = gb >= ga;
+
+                    final UnivariateRealFunction f = new UnivariateRealFunction() {
+                        public double value(final double t) {
+                            try {
+                                interpolator.setInterpolatedTime(t);
+                                return handler.g(t, interpolator.getInterpolatedState());
+                            } catch (DerivativeException e) {
+                                throw new EmbeddedDerivativeException(e);
+                            } catch (EventException e) {
+                                throw new EmbeddedEventException(e);
+                            }
+                        }
+                    };
+                    final BrentSolver solver = new BrentSolver(convergence);
+
+                    if (ga * gb >= 0) {
+                        // this is a corner case:
+                        // - there was an event near ta,
+                        // - there is another event between ta and tb
+                        // - when ta was computed, convergence was reached on the "wrong side" of the interval
+                        // this implies that the real sign of ga is the same as gb, so we need to slightly
+                        // shift ta to make sure ga and gb get opposite signs and the solver won't complain
+                        // about bracketing
+                        final double epsilon = (forward ? 0.25 : -0.25) * convergence;
+                        for (int k = 0; (k < 4) && (ga * gb > 0); ++k) {
+                            ta += epsilon;
+                            try {
+                                ga = f.value(ta);
+                            } catch (FunctionEvaluationException ex) {
+                                throw new DerivativeException(ex);
+                            }
+                        }
+                        if (ga * gb > 0) {
+                            // this should never happen
+                            throw new MathInternalError();
+                        }
+                    }
+
+                    final double root;
+                    try {
+                        root = (ta <= tb) ?
+                                solver.solve(maxIterationCount, f, ta, tb) :
+                                    solver.solve(maxIterationCount, f, tb, ta);
+                    } catch (FunctionEvaluationException ex) {
+                        throw new DerivativeException(ex);
+                    }
+
+                    if ((!Double.isNaN(previousEventTime)) &&
+                        (FastMath.abs(root - ta) <= convergence) &&
+                        (FastMath.abs(root - previousEventTime) <= convergence)) {
+                        // we have either found nothing or found (again ?) a past event, we simply ignore it
+                        ta = tb;
+                        ga = gb;
+                    } else if (Double.isNaN(previousEventTime) ||
+                               (FastMath.abs(previousEventTime - root) > convergence)) {
+                        pendingEventTime = root;
+                        pendingEvent = true;
+                        return true;
+                    } else {
+                        // no sign change: there is no event for now
+                        ta = tb;
+                        ga = gb;
+                    }
+
+                } else {
+                    // no sign change: there is no event for now
+                    ta = tb;
+                    ga = gb;
+                }
+
+            }
+
+            // no event during the whole step
+            pendingEvent     = false;
+            pendingEventTime = Double.NaN;
+            return false;
+
+        } catch (EmbeddedDerivativeException ede) {
+            throw ede.getDerivativeException();
+        } catch (EmbeddedEventException eee) {
+            throw eee.getEventException();
+        }
+
+    }
+
+    /** Get the occurrence time of the event triggered in the current step.
+     * @return occurrence time of the event triggered in the current
+     * step or positive infinity if no events are triggered
+     */
+    public double getEventTime() {
+        return pendingEvent ? pendingEventTime : Double.POSITIVE_INFINITY;
+    }
+
+    /** Acknowledge the fact the step has been accepted by the integrator.
+     * @param t value of the independent <i>time</i> variable at the
+     * end of the step
+     * @param y array containing the current value of the state vector
+     * at the end of the step
+     * @exception EventException if the value of the event
+     * handler cannot be evaluated
+     */
+    public void stepAccepted(final double t, final double[] y)
+        throws EventException {
+
+        t0 = t;
+        g0 = handler.g(t, y);
+
+        if (pendingEvent && (FastMath.abs(pendingEventTime - t) <= convergence)) {
+            // force the sign to its value "just after the event"
+            previousEventTime = t;
+            g0Positive        = increasing;
+            nextAction        = handler.eventOccurred(t, y, !(increasing ^ forward));
+        } else {
+            g0Positive = g0 >= 0;
+            nextAction = EventHandler.CONTINUE;
+        }
+    }
+
+    /** Check if the integration should be stopped at the end of the
+     * current step.
+     * @return true if the integration should be stopped
+     */
+    public boolean stop() {
+        return nextAction == EventHandler.STOP;
+    }
+
+    /** Let the event handler reset the state if it wants.
+     * @param t value of the independent <i>time</i> variable at the
+     * beginning of the next step
+     * @param y array were to put the desired state vector at the beginning
+     * of the next step
+     * @return true if the integrator should reset the derivatives too
+     * @exception EventException if the state cannot be reseted by the event
+     * handler
+     */
+    public boolean reset(final double t, final double[] y)
+        throws EventException {
+
+        if (!(pendingEvent && (FastMath.abs(pendingEventTime - t) <= convergence))) {
+            return false;
+        }
+
+        if (nextAction == EventHandler.RESET_STATE) {
+            handler.resetState(t, y);
+        }
+        pendingEvent      = false;
+        pendingEventTime  = Double.NaN;
+
+        return (nextAction == EventHandler.RESET_STATE) ||
+               (nextAction == EventHandler.RESET_DERIVATIVES);
+
+    }
+
+    /** Local exception for embedding DerivativeException. */
+    private static class EmbeddedDerivativeException extends RuntimeException {
+
+        /** Serializable UID. */
+        private static final long serialVersionUID = 3574188382434584610L;
+
+        /** Embedded exception. */
+        private final DerivativeException derivativeException;
+
+        /** Simple constructor.
+         * @param derivativeException embedded exception
+         */
+        public EmbeddedDerivativeException(final DerivativeException derivativeException) {
+            this.derivativeException = derivativeException;
+        }
+
+        /** Get the embedded exception.
+         * @return embedded exception
+         */
+        public DerivativeException getDerivativeException() {
+            return derivativeException;
+        }
+
+    }
+
+    /** Local exception for embedding EventException. */
+    private static class EmbeddedEventException extends RuntimeException {
+
+        /** Serializable UID. */
+        private static final long serialVersionUID = -1337749250090455474L;
+
+        /** Embedded exception. */
+        private final EventException eventException;
+
+        /** Simple constructor.
+         * @param eventException embedded exception
+         */
+        public EmbeddedEventException(final EventException eventException) {
+            this.eventException = eventException;
+        }
+
+        /** Get the embedded exception.
+         * @return embedded exception
+         */
+        public EventException getEventException() {
+            return eventException;
+        }
+
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/ode/events/package.html b/src/main/java/org/apache/commons/math/ode/events/package.html
new file mode 100644
index 0000000..68dcd97
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/events/package.html
@@ -0,0 +1,96 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 613620 $ -->
+<body>
+<p>
+This package provides classes to handle discrete events occurring during
+Ordinary Differential Equations integration.
+</p>
+
+<p>
+Discrete events detection is based on switching functions. The user provides
+a simple {@link org.apache.commons.math.ode.events.EventHandler#g g(t, y)}
+function depending on the current time and state. The integrator will monitor
+the value of the function throughout integration range and will trigger the
+event when its sign changes. The magnitude of the value is almost irrelevant,
+it should however be continuous (but not necessarily smooth) for the sake of
+root finding. The steps are shortened as needed to ensure the events occur
+at step boundaries (even if the integrator is a fixed-step integrator).
+</p>
+
+<p>
+When an event is triggered, several different options are available:
+</p>
+<ul>
+  <li>integration can be stopped (this is called a G-stop facility),</li>
+  <li>the state vector or the derivatives can be changed,</li>
+  <li>or integration can simply go on.</li>
+</ul>
+
+<p>
+The first case, G-stop, is the most common one. A typical use case is when an
+ODE must be solved up to some target state is reached, with a known value of
+the state but an unknown occurrence time. As an example, if we want to monitor
+a chemical reaction up to some predefined concentration for the first substance,
+we can use the following switching function setting:
+<pre>
+  public double g(double t, double[] y) {
+    return y[0] - targetConcentration;
+  }
+
+  public int eventOccurred(double t, double[] y) {
+    return STOP;
+  }
+</pre>
+</p>
+
+<p>
+The second case, change state vector or derivatives is encountered when dealing
+with discontinuous dynamical models. A typical case would be the motion of a
+spacecraft when thrusters are fired for orbital maneuvers. The acceleration is
+smooth as long as no maneuver are performed, depending only on gravity, drag,
+third body attraction, radiation pressure. Firing a thruster introduces a
+discontinuity that must be handled appropriately by the integrator. In such a case,
+we would use a switching function setting similar to this:
+<pre>
+  public double g(double t, double[] y) {
+    return (t - tManeuverStart) * (t - tManeuverStop);
+  }
+
+  public int eventOccurred(double t, double[] y) {
+    return RESET_DERIVATIVES;
+  }
+</pre>
+</p>
+
+<p>
+The third case is useful mainly for monitoring purposes, a simple example is:
+<pre>
+  public double g(double t, double[] y) {
+    return y[0] - y[1];
+  }
+
+  public int eventOccurred(double t, double[] y) {
+    logger.log("y0(t) and y1(t) curves cross at t = " + t);
+    return CONTINUE;
+  }
+</pre>
+</p>
+
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.java b/src/main/java/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.java
new file mode 100644
index 0000000..80d6c6e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.java
@@ -0,0 +1,226 @@
+/*
+ * 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.ode.jacobians;
+
+import org.apache.commons.math.ode.events.EventException;
+
+/** This interface represents a handler for discrete events triggered
+ * during ODE integration.
+ *
+ * <p>Some events can be triggered at discrete times as an ODE problem
+ * is solved. This occurs for example when the integration process
+ * should be stopped as some state is reached (G-stop facility) when the
+ * precise date is unknown a priori, or when the derivatives have
+ * discontinuities, or simply when the user wants to monitor some
+ * states boundaries crossings.
+ * </p>
+ *
+ * <p>These events are defined as occurring when a <code>g</code>
+ * switching function sign changes.</p>
+ *
+ * <p>Since events are only problem-dependent and are triggered by the
+ * independent <i>time</i> variable and the state vector, they can
+ * occur at virtually any time, unknown in advance. The integrators will
+ * take care to avoid sign changes inside the steps, they will reduce
+ * the step size when such an event is detected in order to put this
+ * event exactly at the end of the current step. This guarantees that
+ * step interpolation (which always has a one step scope) is relevant
+ * even in presence of discontinuities. This is independent from the
+ * stepsize control provided by integrators that monitor the local
+ * error (this event handling feature is available for all integrators,
+ * including fixed step ones).</p>
+ *
+ * <p>Note that is is possible to register a {@link
+ * org.apache.commons.math.ode.events.EventHandler classical event handler}
+ * in the low level integrator used to build a {@link FirstOrderIntegratorWithJacobians}
+ * rather than implementing this class. The event handlers registered at low level
+ * will see the big compound state whether the event handlers defined by this interface
+ * see the original state, and its jacobians in separate arrays.</p>
+ *
+ * <p>The compound state is guaranteed to contain the original state in the first
+ * elements, followed by the jacobian with respect to initial state (in row order),
+ * followed by the jacobian with respect to parameters (in row order). If for example
+ * the original state dimension is 6 and there are 3 parameters, the compound state will
+ * be a 60 elements array. The first 6 elements will be the original state, the next 36
+ * elements will be the jacobian with respect to initial state, and the remaining 18 elements
+ * will be the jacobian with respect to parameters.</p>
+ *
+ * <p>Dealing with low level event handlers is cumbersome if one really needs the jacobians
+ * in these methods, but it also prevents many data being copied back and forth between
+ * state and jacobians on one side and compound state on the other side. So for performance
+ * reasons, it is recommended to use this interface <em>only</em> if jacobians are really
+ * needed and to use lower level handlers if only state is needed.</p>
+ *
+ * @version $Revision: 1037341 $ $Date: 2010-11-20 22:58:35 +0100 (sam. 20 nov. 2010) $
+ * @since 2.1
+ * @deprecated as of 2.2 the complete package is deprecated, it will be replaced
+ * in 3.0 by a completely rewritten implementation
+ */
+@Deprecated
+public interface EventHandlerWithJacobians  {
+
+    /** Stop indicator.
+     * <p>This value should be used as the return value of the {@link
+     * #eventOccurred eventOccurred} method when the integration should be
+     * stopped after the event ending the current step.</p>
+     */
+    int STOP = 0;
+
+    /** Reset state indicator.
+     * <p>This value should be used as the return value of the {@link
+     * #eventOccurred eventOccurred} method when the integration should
+     * go on after the event ending the current step, with a new state
+     * vector (which will be retrieved thanks to the {@link #resetState
+     * resetState} method).</p>
+     */
+    int RESET_STATE = 1;
+
+    /** Reset derivatives indicator.
+     * <p>This value should be used as the return value of the {@link
+     * #eventOccurred eventOccurred} method when the integration should
+     * go on after the event ending the current step, with a new derivatives
+     * vector (which will be retrieved thanks to the {@link
+     * org.apache.commons.math.ode.FirstOrderDifferentialEquations#computeDerivatives}
+     * method).</p>
+     */
+    int RESET_DERIVATIVES = 2;
+
+    /** Continue indicator.
+     * <p>This value should be used as the return value of the {@link
+     * #eventOccurred eventOccurred} method when the integration should go
+     * on after the event ending the current step.</p>
+     */
+    int CONTINUE = 3;
+
+    /** Compute the value of the switching function.
+
+     * <p>The discrete events are generated when the sign of this
+     * switching function changes. The integrator will take care to change
+     * the stepsize in such a way these events occur exactly at step boundaries.
+     * The switching function must be continuous in its roots neighborhood
+     * (but not necessarily smooth), as the integrator will need to find its
+     * roots to locate precisely the events.</p>
+
+     * @param t current value of the independent <i>time</i> variable
+     * @param y array containing the current value of the state vector
+     * @param dydy0 array containing the current value of the jacobian of
+     * the state vector with respect to initial state
+     * @param dydp array containing the current value of the jacobian of
+     * the state vector with respect to parameters
+     * @return value of the g switching function
+     * @exception EventException if the switching function cannot be evaluated
+     */
+    double g(double t, double[] y, double[][] dydy0, double[][] dydp)
+        throws EventException;
+
+    /** Handle an event and choose what to do next.
+
+     * <p>This method is called when the integrator has accepted a step
+     * ending exactly on a sign change of the function, just <em>before</em>
+     * the step handler itself is called (see below for scheduling). It
+     * allows the user to update his internal data to acknowledge the fact
+     * the event has been handled (for example setting a flag in the {@link
+     * org.apache.commons.math.ode.jacobians.ODEWithJacobians
+     * differential equations} to switch the derivatives computation in
+     * case of discontinuity), or to direct the integrator to either stop
+     * or continue integration, possibly with a reset state or derivatives.</p>
+
+     * <ul>
+     *   <li>if {@link #STOP} is returned, the step handler will be called
+     *   with the <code>isLast</code> flag of the {@link
+     *   org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians#handleStep(
+     *   StepInterpolatorWithJacobians, boolean) handleStep} method set to true and
+     *   the integration will be stopped,</li>
+     *   <li>if {@link #RESET_STATE} is returned, the {@link #resetState
+     *   resetState} method will be called once the step handler has
+     *   finished its task, and the integrator will also recompute the
+     *   derivatives,</li>
+     *   <li>if {@link #RESET_DERIVATIVES} is returned, the integrator
+     *   will recompute the derivatives,
+     *   <li>if {@link #CONTINUE} is returned, no specific action will
+     *   be taken (apart from having called this method) and integration
+     *   will continue.</li>
+     * </ul>
+
+     * <p>The scheduling between this method and the {@link
+     * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians
+     * StepHandlerWithJacobians} method {@link
+     * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians#handleStep(
+     * StepInterpolatorWithJacobians, boolean) handleStep(interpolator, isLast)}
+     * is to call this method first and <code>handleStep</code> afterwards. This
+     * scheduling allows the integrator to pass <code>true</code> as the
+     * <code>isLast</code> parameter to the step handler to make it aware the step
+     * will be the last one if this method returns {@link #STOP}. As the
+     * interpolator may be used to navigate back throughout the last step (as {@link
+     * org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer}
+     * does for example), user code called by this method and user
+     * code called by step handlers may experience apparently out of order values
+     * of the independent time variable. As an example, if the same user object
+     * implements both this {@link EventHandlerWithJacobians EventHandler} interface and the
+     * {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler}
+     * interface, a <em>forward</em> integration may call its
+     * <code>eventOccurred</code> method with t = 10 first and call its
+     * <code>handleStep</code> method with t = 9 afterwards. Such out of order
+     * calls are limited to the size of the integration step for {@link
+     * org.apache.commons.math.ode.sampling.StepHandler variable step handlers} and
+     * to the size of the fixed step for {@link
+     * org.apache.commons.math.ode.sampling.FixedStepHandler fixed step handlers}.</p>
+
+     * @param t current value of the independent <i>time</i> variable
+     * @param y array containing the current value of the state vector
+     * @param dydy0 array containing the current value of the jacobian of
+     * the state vector with respect to initial state
+     * @param dydp array containing the current value of the jacobian of
+     * the state vector with respect to parameters
+     * @param increasing if true, the value of the switching function increases
+     * when times increases around event (note that increase is measured with respect
+     * to physical time, not with respect to integration which may go backward in time)
+     * @return indication of what the integrator should do next, this
+     * value must be one of {@link #STOP}, {@link #RESET_STATE},
+     * {@link #RESET_DERIVATIVES} or {@link #CONTINUE}
+     * @exception EventException if the event occurrence triggers an error
+     */
+    int eventOccurred(double t, double[] y, double[][] dydy0, double[][] dydp,
+                      boolean increasing) throws EventException;
+
+    /** Reset the state prior to continue the integration.
+
+     * <p>This method is called after the step handler has returned and
+     * before the next step is started, but only when {@link
+     * #eventOccurred} has itself returned the {@link #RESET_STATE}
+     * indicator. It allows the user to reset the state vector for the
+     * next step, without perturbing the step handler of the finishing
+     * step. If the {@link #eventOccurred} never returns the {@link
+     * #RESET_STATE} indicator, this function will never be called, and it is
+     * safe to leave its body empty.</p>
+
+     * @param t current value of the independent <i>time</i> variable
+     * @param y array containing the current value of the state vector
+     * the new state should be put in the same array
+     * @param dydy0 array containing the current value of the jacobian of
+     * the state vector with respect to initial state, the new jacobian
+     * should be put in the same array
+     * @param dydp array containing the current value of the jacobian of
+     * the state vector with respect to parameters, the new jacobian
+     * should be put in the same array
+     * @exception EventException if the state cannot be reseted
+     */
+    void resetState(double t, double[] y, double[][] dydy0, double[][] dydp)
+    throws EventException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java b/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java
new file mode 100644
index 0000000..dc5ca18
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.java
@@ -0,0 +1,899 @@
+/*
+ * 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.ode.jacobians;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.ode.ExtendedFirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.FirstOrderIntegrator;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.events.EventException;
+import org.apache.commons.math.ode.events.EventHandler;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/** This class enhances a first order integrator for differential equations to
+ * compute also partial derivatives of the solution with respect to initial state
+ * and parameters.
+ * <p>In order to compute both the state and its derivatives, the ODE problem
+ * is extended with jacobians of the raw ODE and the variational equations are
+ * added to form a new compound problem of higher dimension. If the original ODE
+ * problem has dimension n and there are p parameters, the compound problem will
+ * have dimension n &times; (1 + n + p).</p>
+ * @see ParameterizedODE
+ * @see ODEWithJacobians
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.1
+ * @deprecated as of 2.2 the complete package is deprecated, it will be replaced
+ * in 3.0 by a completely rewritten implementation
+ */
+@Deprecated
+public class FirstOrderIntegratorWithJacobians {
+
+    /** Underlying integrator for compound problem. */
+    private final FirstOrderIntegrator integrator;
+
+    /** Raw equations to integrate. */
+    private final ODEWithJacobians ode;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed. */
+    private int evaluations;
+
+    /** Build an enhanced integrator using internal differentiation to compute jacobians.
+     * @param integrator underlying integrator to solve the compound problem
+     * @param ode original problem (f in the equation y' = f(t, y))
+     * @param p parameters array (may be null if {@link
+     * ParameterizedODE#getParametersDimension()
+     * getParametersDimension()} from original problem is zero)
+     * @param hY step sizes to use for computing the jacobian df/dy, must have the
+     * same dimension as the original problem
+     * @param hP step sizes to use for computing the jacobian df/dp, must have the
+     * same dimension as the original problem parameters dimension
+     * @see #FirstOrderIntegratorWithJacobians(FirstOrderIntegrator,
+     * ODEWithJacobians)
+     */
+    public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator,
+                                             final ParameterizedODE ode,
+                                             final double[] p, final double[] hY, final double[] hP) {
+        checkDimension(ode.getDimension(), hY);
+        checkDimension(ode.getParametersDimension(), p);
+        checkDimension(ode.getParametersDimension(), hP);
+        this.integrator = integrator;
+        this.ode = new FiniteDifferencesWrapper(ode, p, hY, hP);
+        setMaxEvaluations(-1);
+    }
+
+    /** Build an enhanced integrator using ODE builtin jacobian computation features.
+     * @param integrator underlying integrator to solve the compound problem
+     * @param ode original problem, which can compute the jacobians by itself
+     * @see #FirstOrderIntegratorWithJacobians(FirstOrderIntegrator,
+     * ParameterizedODE, double[], double[], double[])
+     */
+    public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator,
+                                             final ODEWithJacobians ode) {
+        this.integrator = integrator;
+        this.ode = ode;
+        setMaxEvaluations(-1);
+    }
+
+    /** Add a step handler to this integrator.
+     * <p>The handler will be called by the integrator for each accepted
+     * step.</p>
+     * @param handler handler for the accepted steps
+     * @see #getStepHandlers()
+     * @see #clearStepHandlers()
+     */
+    public void addStepHandler(StepHandlerWithJacobians handler) {
+        final int n = ode.getDimension();
+        final int k = ode.getParametersDimension();
+        integrator.addStepHandler(new StepHandlerWrapper(handler, n, k));
+    }
+
+    /** Get all the step handlers that have been added to the integrator.
+     * @return an unmodifiable collection of the added events handlers
+     * @see #addStepHandler(StepHandlerWithJacobians)
+     * @see #clearStepHandlers()
+     */
+    public Collection<StepHandlerWithJacobians> getStepHandlers() {
+        final Collection<StepHandlerWithJacobians> handlers =
+            new ArrayList<StepHandlerWithJacobians>();
+        for (final StepHandler handler : integrator.getStepHandlers()) {
+            if (handler instanceof StepHandlerWrapper) {
+                handlers.add(((StepHandlerWrapper) handler).getHandler());
+            }
+        }
+        return handlers;
+    }
+
+    /** Remove all the step handlers that have been added to the integrator.
+     * @see #addStepHandler(StepHandlerWithJacobians)
+     * @see #getStepHandlers()
+     */
+    public void clearStepHandlers() {
+        integrator.clearStepHandlers();
+    }
+
+    /** Add an event handler to the integrator.
+     * @param handler event handler
+     * @param maxCheckInterval maximal time interval between switching
+     * function checks (this interval prevents missing sign changes in
+     * case the integration steps becomes very large)
+     * @param convergence convergence threshold in the event time search
+     * @param maxIterationCount upper limit of the iteration count in
+     * the event time search
+     * @see #getEventHandlers()
+     * @see #clearEventHandlers()
+     */
+    public void addEventHandler(EventHandlerWithJacobians handler,
+                                double maxCheckInterval,
+                                double convergence,
+                                int maxIterationCount) {
+        final int n = ode.getDimension();
+        final int k = ode.getParametersDimension();
+        integrator.addEventHandler(new EventHandlerWrapper(handler, n, k),
+                                   maxCheckInterval, convergence, maxIterationCount);
+    }
+
+    /** Get all the event handlers that have been added to the integrator.
+     * @return an unmodifiable collection of the added events handlers
+     * @see #addEventHandler(EventHandlerWithJacobians, double, double, int)
+     * @see #clearEventHandlers()
+     */
+    public Collection<EventHandlerWithJacobians> getEventHandlers() {
+        final Collection<EventHandlerWithJacobians> handlers =
+            new ArrayList<EventHandlerWithJacobians>();
+        for (final EventHandler handler : integrator.getEventHandlers()) {
+            if (handler instanceof EventHandlerWrapper) {
+                handlers.add(((EventHandlerWrapper) handler).getHandler());
+            }
+        }
+        return handlers;
+    }
+
+    /** Remove all the event handlers that have been added to the integrator.
+     * @see #addEventHandler(EventHandlerWithJacobians, double, double, int)
+     * @see #getEventHandlers()
+     */
+    public void clearEventHandlers() {
+        integrator.clearEventHandlers();
+    }
+
+    /** Integrate the differential equations and the variational equations up to the given time.
+     * <p>This method solves an Initial Value Problem (IVP) and also computes the derivatives
+     * of the solution with respect to initial state and parameters. This can be used as
+     * a basis to solve Boundary Value Problems (BVP).</p>
+     * <p>Since this method stores some internal state variables made
+     * available in its public interface during integration ({@link
+     * #getCurrentSignedStepsize()}), it is <em>not</em> thread-safe.</p>
+     * @param t0 initial time
+     * @param y0 initial value of the state vector at t0
+     * @param dY0dP initial value of the state vector derivative with respect to the
+     * parameters at t0
+     * @param t target time for the integration
+     * (can be set to a value smaller than <code>t0</code> for backward integration)
+     * @param y placeholder where to put the state vector at each successful
+     *  step (and hence at the end of integration), can be the same object as y0
+     * @param dYdY0 placeholder where to put the state vector derivative with respect
+     * to the initial state (dy[i]/dy0[j] is in element array dYdY0[i][j]) at each successful
+     *  step (and hence at the end of integration)
+     * @param dYdP placeholder where to put the state vector derivative with respect
+     * to the parameters (dy[i]/dp[j] is in element array dYdP[i][j]) at each successful
+     *  step (and hence at the end of integration)
+     * @return stop time, will be the same as target time if integration reached its
+     * target, but may be different if some event handler stops it at some point.
+     * @throws IntegratorException if the integrator cannot perform integration
+     * @throws DerivativeException this exception is propagated to the caller if
+     * the underlying user function triggers one
+     */
+    public double integrate(final double t0, final double[] y0, final double[][] dY0dP,
+                            final double t, final double[] y,
+                            final double[][] dYdY0, final double[][] dYdP)
+        throws DerivativeException, IntegratorException {
+
+        final int n = ode.getDimension();
+        final int k = ode.getParametersDimension();
+        checkDimension(n, y0);
+        checkDimension(n, y);
+        checkDimension(n, dYdY0);
+        checkDimension(n, dYdY0[0]);
+        if (k != 0) {
+            checkDimension(n, dY0dP);
+            checkDimension(k, dY0dP[0]);
+            checkDimension(n, dYdP);
+            checkDimension(k, dYdP[0]);
+        }
+
+        // set up initial state, including partial derivatives
+        // the compound state z contains the raw state y and its derivatives
+        // with respect to initial state y0 and to parameters p
+        //    y[i]         is stored in z[i]
+        //    dy[i]/dy0[j] is stored in z[n + i * n + j]
+        //    dy[i]/dp[j]  is stored in z[n * (n + 1) + i * k + j]
+        final double[] z = new double[n * (1 + n + k)];
+        System.arraycopy(y0, 0, z, 0, n);
+        for (int i = 0; i < n; ++i) {
+
+            // set diagonal element of dy/dy0 to 1.0 at t = t0
+            z[i * (1 + n) + n] = 1.0;
+
+            // set initial derivatives with respect to parameters
+            System.arraycopy(dY0dP[i], 0, z, n * (n + 1) + i * k, k);
+
+        }
+
+        // integrate the compound state variational equations
+        evaluations = 0;
+        final double stopTime = integrator.integrate(new MappingWrapper(), t0, z, t, z);
+
+        // dispatch the final compound state into the state and partial derivatives arrays
+        dispatchCompoundState(z, y, dYdY0, dYdP);
+
+        return stopTime;
+
+    }
+
+    /** Dispatch a compound state array into state and jacobians arrays.
+     * @param z compound state
+     * @param y raw state array to fill
+     * @param dydy0 jacobian array to fill
+     * @param dydp jacobian array to fill
+     */
+    private static void dispatchCompoundState(final double[] z, final double[] y,
+                                              final double[][] dydy0, final double[][] dydp) {
+
+        final int n = y.length;
+        final int k = dydp[0].length;
+
+        // state
+        System.arraycopy(z, 0, y, 0, n);
+
+        // jacobian with respect to initial state
+        for (int i = 0; i < n; ++i) {
+            System.arraycopy(z, n * (i + 1), dydy0[i], 0, n);
+        }
+
+        // jacobian with respect to parameters
+        for (int i = 0; i < n; ++i) {
+            System.arraycopy(z, n * (n + 1) + i * k, dydp[i], 0, k);
+        }
+
+    }
+
+    /** Get the current value of the step start time t<sub>i</sub>.
+     * <p>This method can be called during integration (typically by
+     * the object implementing the {@link org.apache.commons.math.ode.FirstOrderDifferentialEquations
+     * differential equations} problem) if the value of the current step that
+     * is attempted is needed.</p>
+     * <p>The result is undefined if the method is called outside of
+     * calls to <code>integrate</code>.</p>
+     * @return current value of the step start time t<sub>i</sub>
+     */
+    public double getCurrentStepStart() {
+        return integrator.getCurrentStepStart();
+    }
+
+    /** Get the current signed value of the integration stepsize.
+     * <p>This method can be called during integration (typically by
+     * the object implementing the {@link org.apache.commons.math.ode.FirstOrderDifferentialEquations
+     * differential equations} problem) if the signed value of the current stepsize
+     * that is tried is needed.</p>
+     * <p>The result is undefined if the method is called outside of
+     * calls to <code>integrate</code>.</p>
+     * @return current signed value of the stepsize
+     */
+    public double getCurrentSignedStepsize() {
+        return integrator.getCurrentSignedStepsize();
+    }
+
+    /** Set the maximal number of differential equations function evaluations.
+     * <p>The purpose of this method is to avoid infinite loops which can occur
+     * for example when stringent error constraints are set or when lots of
+     * discrete events are triggered, thus leading to many rejected steps.</p>
+     * @param maxEvaluations maximal number of function evaluations (negative
+     * values are silently converted to maximal integer value, thus representing
+     * almost unlimited evaluations)
+     */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = (maxEvaluations < 0) ? Integer.MAX_VALUE : maxEvaluations;
+    }
+
+    /** Get the maximal number of functions evaluations.
+     * @return maximal number of functions evaluations
+     */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** Get the number of evaluations of the differential equations function.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * <code>integrate</code> method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the differential equations function
+     */
+    public int getEvaluations() {
+        return evaluations;
+    }
+
+    /** Check array dimensions.
+     * @param expected expected dimension
+     * @param array (may be null if expected is 0)
+     * @throws IllegalArgumentException if the array dimension does not match the expected one
+     */
+    private void checkDimension(final int expected, final Object array)
+        throws IllegalArgumentException {
+        int arrayDimension = (array == null) ? 0 : Array.getLength(array);
+        if (arrayDimension != expected) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, arrayDimension, expected);
+        }
+    }
+
+    /** Wrapper class used to map state and jacobians into compound state. */
+    private class MappingWrapper implements  ExtendedFirstOrderDifferentialEquations {
+
+        /** Current state. */
+        private final double[]   y;
+
+        /** Time derivative of the current state. */
+        private final double[]   yDot;
+
+        /** Derivatives of yDot with respect to state. */
+        private final double[][] dFdY;
+
+        /** Derivatives of yDot with respect to parameters. */
+        private final double[][] dFdP;
+
+        /** Simple constructor.
+         */
+        public MappingWrapper() {
+
+            final int n = ode.getDimension();
+            final int k = ode.getParametersDimension();
+            y    = new double[n];
+            yDot = new double[n];
+            dFdY = new double[n][n];
+            dFdP = new double[n][k];
+
+        }
+
+        /** {@inheritDoc} */
+        public int getDimension() {
+            final int n = y.length;
+            final int k = dFdP[0].length;
+            return n * (1 + n + k);
+        }
+
+        /** {@inheritDoc} */
+        public int getMainSetDimension() {
+            return ode.getDimension();
+        }
+
+        /** {@inheritDoc} */
+        public void computeDerivatives(final double t, final double[] z, final double[] zDot)
+            throws DerivativeException {
+
+            final int n = y.length;
+            final int k = dFdP[0].length;
+
+            // compute raw ODE and its jacobians: dy/dt, d[dy/dt]/dy0 and d[dy/dt]/dp
+            System.arraycopy(z,    0, y,    0, n);
+            if (++evaluations > maxEvaluations) {
+                throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations));
+            }
+            ode.computeDerivatives(t, y, yDot);
+            ode.computeJacobians(t, y, yDot, dFdY, dFdP);
+
+            // state part of the compound equations
+            System.arraycopy(yDot, 0, zDot, 0, n);
+
+            // variational equations: from d[dy/dt]/dy0 to d[dy/dy0]/dt
+            for (int i = 0; i < n; ++i) {
+                final double[] dFdYi = dFdY[i];
+                for (int j = 0; j < n; ++j) {
+                    double s = 0;
+                    final int startIndex = n + j;
+                    int zIndex = startIndex;
+                    for (int l = 0; l < n; ++l) {
+                        s += dFdYi[l] * z[zIndex];
+                        zIndex += n;
+                    }
+                    zDot[startIndex + i * n] = s;
+                }
+            }
+
+            // variational equations: from d[dy/dt]/dy0 and d[dy/dt]/dp to d[dy/dp]/dt
+            for (int i = 0; i < n; ++i) {
+                final double[] dFdYi = dFdY[i];
+                final double[] dFdPi = dFdP[i];
+                for (int j = 0; j < k; ++j) {
+                    double s = dFdPi[j];
+                    final int startIndex = n * (n + 1) + j;
+                    int zIndex = startIndex;
+                    for (int l = 0; l < n; ++l) {
+                        s += dFdYi[l] * z[zIndex];
+                        zIndex += k;
+                    }
+                    zDot[startIndex + i * k] = s;
+                }
+            }
+
+        }
+
+    }
+
+    /** Wrapper class to compute jacobians by finite differences for ODE which do not compute them themselves. */
+    private class FiniteDifferencesWrapper implements ODEWithJacobians {
+
+        /** Raw ODE without jacobians computation. */
+        private final ParameterizedODE ode;
+
+        /** Parameters array (may be null if parameters dimension from original problem is zero) */
+        private final double[] p;
+
+        /** Step sizes to use for computing the jacobian df/dy. */
+        private final double[] hY;
+
+        /** Step sizes to use for computing the jacobian df/dp. */
+        private final double[] hP;
+
+        /** Temporary array for state derivatives used to compute jacobians. */
+        private final double[] tmpDot;
+
+        /** Simple constructor.
+         * @param ode original ODE problem, without jacobians computations
+         * @param p parameters array (may be null if parameters dimension from original problem is zero)
+         * @param hY step sizes to use for computing the jacobian df/dy
+         * @param hP step sizes to use for computing the jacobian df/dp
+         */
+        public FiniteDifferencesWrapper(final ParameterizedODE ode,
+                                        final double[] p, final double[] hY, final double[] hP) {
+            this.ode = ode;
+            this.p  = p.clone();
+            this.hY = hY.clone();
+            this.hP = hP.clone();
+            tmpDot = new double[ode.getDimension()];
+        }
+
+        /** {@inheritDoc} */
+        public int getDimension() {
+            return ode.getDimension();
+        }
+
+        /** {@inheritDoc} */
+        public void computeDerivatives(double t, double[] y, double[] yDot) throws DerivativeException {
+            // this call to computeDerivatives has already been counted,
+            // we must not increment the counter again
+            ode.computeDerivatives(t, y, yDot);
+        }
+
+        /** {@inheritDoc} */
+        public int getParametersDimension() {
+            return ode.getParametersDimension();
+        }
+
+        /** {@inheritDoc} */
+        public void computeJacobians(double t, double[] y, double[] yDot,
+                                     double[][] dFdY, double[][] dFdP)
+            throws DerivativeException {
+
+            final int n = hY.length;
+            final int k = hP.length;
+
+            evaluations += n + k;
+            if (evaluations > maxEvaluations) {
+                throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations));
+            }
+
+            // compute df/dy where f is the ODE and y is the state array
+            for (int j = 0; j < n; ++j) {
+                final double savedYj = y[j];
+                y[j] += hY[j];
+                ode.computeDerivatives(t, y, tmpDot);
+                for (int i = 0; i < n; ++i) {
+                    dFdY[i][j] = (tmpDot[i] - yDot[i]) / hY[j];
+                }
+                y[j] = savedYj;
+            }
+
+            // compute df/dp where f is the ODE and p is the parameters array
+            for (int j = 0; j < k; ++j) {
+                ode.setParameter(j, p[j] +  hP[j]);
+                ode.computeDerivatives(t, y, tmpDot);
+                for (int i = 0; i < n; ++i) {
+                    dFdP[i][j] = (tmpDot[i] - yDot[i]) / hP[j];
+                }
+                ode.setParameter(j, p[j]);
+            }
+
+        }
+
+    }
+
+    /** Wrapper for step handlers. */
+    private static class StepHandlerWrapper implements StepHandler {
+
+        /** Underlying step handler with jacobians. */
+        private final StepHandlerWithJacobians handler;
+
+        /** Dimension of the original ODE. */
+        private final int n;
+
+        /** Number of parameters. */
+        private final int k;
+
+        /** Simple constructor.
+         * @param handler underlying step handler with jacobians
+         * @param n dimension of the original ODE
+         * @param k number of parameters
+         */
+        public StepHandlerWrapper(final StepHandlerWithJacobians handler,
+                                  final int n, final int k) {
+            this.handler = handler;
+            this.n       = n;
+            this.k       = k;
+        }
+
+        /** Get the underlying step handler with jacobians.
+         * @return underlying step handler with jacobians
+         */
+        public StepHandlerWithJacobians getHandler() {
+            return handler;
+        }
+
+        /** {@inheritDoc} */
+        public void handleStep(StepInterpolator interpolator, boolean isLast)
+            throws DerivativeException {
+            handler.handleStep(new StepInterpolatorWrapper(interpolator, n, k), isLast);
+        }
+
+        /** {@inheritDoc} */
+        public boolean requiresDenseOutput() {
+            return handler.requiresDenseOutput();
+        }
+
+        /** {@inheritDoc} */
+        public void reset() {
+            handler.reset();
+        }
+
+    }
+
+    /** Wrapper for step interpolators. */
+    private static class StepInterpolatorWrapper
+        implements StepInterpolatorWithJacobians {
+
+        /** Wrapped interpolator. */
+        private StepInterpolator interpolator;
+
+        /** State array. */
+        private double[] y;
+
+        /** Jacobian with respect to initial state dy/dy0. */
+        private double[][] dydy0;
+
+        /** Jacobian with respect to parameters dy/dp. */
+        private double[][] dydp;
+
+        /** Time derivative of the state array. */
+        private double[] yDot;
+
+        /** Time derivative of the sacobian with respect to initial state dy/dy0. */
+        private double[][] dydy0Dot;
+
+        /** Time derivative of the jacobian with respect to parameters dy/dp. */
+        private double[][] dydpDot;
+
+        /** Simple constructor.
+         * <p>This constructor is used only for externalization. It does nothing.</p>
+         */
+        @SuppressWarnings("unused")
+        public StepInterpolatorWrapper() {
+        }
+
+        /** Simple constructor.
+         * @param interpolator wrapped interpolator
+         * @param n dimension of the original ODE
+         * @param k number of parameters
+         */
+        public StepInterpolatorWrapper(final StepInterpolator interpolator,
+                                       final int n, final int k) {
+            this.interpolator = interpolator;
+            y        = new double[n];
+            dydy0    = new double[n][n];
+            dydp     = new double[n][k];
+            yDot     = new double[n];
+            dydy0Dot = new double[n][n];
+            dydpDot  = new double[n][k];
+        }
+
+        /** {@inheritDoc} */
+        public void setInterpolatedTime(double time) {
+            interpolator.setInterpolatedTime(time);
+        }
+
+        /** {@inheritDoc} */
+        public boolean isForward() {
+            return interpolator.isForward();
+        }
+
+        /** {@inheritDoc} */
+        public double getPreviousTime() {
+            return interpolator.getPreviousTime();
+        }
+
+        /** {@inheritDoc} */
+        public double getInterpolatedTime() {
+            return interpolator.getInterpolatedTime();
+        }
+
+        /** {@inheritDoc} */
+        public double[] getInterpolatedY() throws DerivativeException {
+            double[] extendedState = interpolator.getInterpolatedState();
+            System.arraycopy(extendedState, 0, y, 0, y.length);
+            return y;
+        }
+
+        /** {@inheritDoc} */
+        public double[][] getInterpolatedDyDy0() throws DerivativeException {
+            double[] extendedState = interpolator.getInterpolatedState();
+            final int n = y.length;
+            int start = n;
+            for (int i = 0; i < n; ++i) {
+                System.arraycopy(extendedState, start, dydy0[i], 0, n);
+                start += n;
+            }
+            return dydy0;
+        }
+
+        /** {@inheritDoc} */
+        public double[][] getInterpolatedDyDp() throws DerivativeException {
+            double[] extendedState = interpolator.getInterpolatedState();
+            final int n = y.length;
+            final int k = dydp[0].length;
+            int start = n * (n + 1);
+            for (int i = 0; i < n; ++i) {
+                System.arraycopy(extendedState, start, dydp[i], 0, k);
+                start += k;
+            }
+            return dydp;
+        }
+
+        /** {@inheritDoc} */
+        public double[] getInterpolatedYDot() throws DerivativeException {
+            double[] extendedDerivatives = interpolator.getInterpolatedDerivatives();
+            System.arraycopy(extendedDerivatives, 0, yDot, 0, yDot.length);
+            return yDot;
+        }
+
+        /** {@inheritDoc} */
+        public double[][] getInterpolatedDyDy0Dot() throws DerivativeException {
+            double[] extendedDerivatives = interpolator.getInterpolatedDerivatives();
+            final int n = y.length;
+            int start = n;
+            for (int i = 0; i < n; ++i) {
+                System.arraycopy(extendedDerivatives, start, dydy0Dot[i], 0, n);
+                start += n;
+            }
+            return dydy0Dot;
+        }
+
+        /** {@inheritDoc} */
+        public double[][] getInterpolatedDyDpDot() throws DerivativeException {
+            double[] extendedDerivatives = interpolator.getInterpolatedDerivatives();
+            final int n = y.length;
+            final int k = dydpDot[0].length;
+            int start = n * (n + 1);
+            for (int i = 0; i < n; ++i) {
+                System.arraycopy(extendedDerivatives, start, dydpDot[i], 0, k);
+                start += k;
+            }
+            return dydpDot;
+        }
+
+        /** {@inheritDoc} */
+        public double getCurrentTime() {
+            return interpolator.getCurrentTime();
+        }
+
+        /** {@inheritDoc} */
+        public StepInterpolatorWithJacobians copy() throws DerivativeException {
+            final int n = y.length;
+            final int k = dydp[0].length;
+            StepInterpolatorWrapper copied =
+                new StepInterpolatorWrapper(interpolator.copy(), n, k);
+            copyArray(y,        copied.y);
+            copyArray(dydy0,    copied.dydy0);
+            copyArray(dydp,     copied.dydp);
+            copyArray(yDot,     copied.yDot);
+            copyArray(dydy0Dot, copied.dydy0Dot);
+            copyArray(dydpDot,  copied.dydpDot);
+            return copied;
+        }
+
+        /** {@inheritDoc} */
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeObject(interpolator);
+            out.writeInt(y.length);
+            out.writeInt(dydp[0].length);
+            writeArray(out, y);
+            writeArray(out, dydy0);
+            writeArray(out, dydp);
+            writeArray(out, yDot);
+            writeArray(out, dydy0Dot);
+            writeArray(out, dydpDot);
+        }
+
+        /** {@inheritDoc} */
+        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            interpolator = (StepInterpolator) in.readObject();
+            final int n = in.readInt();
+            final int k = in.readInt();
+            y        = new double[n];
+            dydy0    = new double[n][n];
+            dydp     = new double[n][k];
+            yDot     = new double[n];
+            dydy0Dot = new double[n][n];
+            dydpDot  = new double[n][k];
+            readArray(in, y);
+            readArray(in, dydy0);
+            readArray(in, dydp);
+            readArray(in, yDot);
+            readArray(in, dydy0Dot);
+            readArray(in, dydpDot);
+        }
+
+        /** Copy an array.
+         * @param src source array
+         * @param dest destination array
+         */
+        private static void copyArray(final double[] src, final double[] dest) {
+            System.arraycopy(src, 0, dest, 0, src.length);
+        }
+
+        /** Copy an array.
+         * @param src source array
+         * @param dest destination array
+         */
+        private static void copyArray(final double[][] src, final double[][] dest) {
+            for (int i = 0; i < src.length; ++i) {
+                copyArray(src[i], dest[i]);
+            }
+        }
+
+        /** Write an array.
+         * @param out output stream
+         * @param array array to write
+         * @exception IOException if array cannot be read
+         */
+        private static void writeArray(final ObjectOutput out, final double[] array)
+            throws IOException {
+            for (int i = 0; i < array.length; ++i) {
+                out.writeDouble(array[i]);
+            }
+        }
+
+        /** Write an array.
+         * @param out output stream
+         * @param array array to write
+         * @exception IOException if array cannot be read
+         */
+        private static void writeArray(final ObjectOutput out, final double[][] array)
+            throws IOException {
+            for (int i = 0; i < array.length; ++i) {
+                writeArray(out, array[i]);
+            }
+        }
+
+        /** Read an array.
+         * @param in input stream
+         * @param array array to read
+         * @exception IOException if array cannot be read
+         */
+        private static void readArray(final ObjectInput in, final double[] array)
+            throws IOException {
+            for (int i = 0; i < array.length; ++i) {
+                array[i] = in.readDouble();
+            }
+        }
+
+        /** Read an array.
+         * @param in input stream
+         * @param array array to read
+         * @exception IOException if array cannot be read
+         */
+        private static void readArray(final ObjectInput in, final double[][] array)
+            throws IOException {
+            for (int i = 0; i < array.length; ++i) {
+                readArray(in, array[i]);
+            }
+        }
+
+    }
+
+    /** Wrapper for event handlers. */
+    private static class EventHandlerWrapper implements EventHandler {
+
+        /** Underlying event handler with jacobians. */
+        private final EventHandlerWithJacobians handler;
+
+        /** State array. */
+        private double[] y;
+
+        /** Jacobian with respect to initial state dy/dy0. */
+        private double[][] dydy0;
+
+        /** Jacobian with respect to parameters dy/dp. */
+        private double[][] dydp;
+
+        /** Simple constructor.
+         * @param handler underlying event handler with jacobians
+         * @param n dimension of the original ODE
+         * @param k number of parameters
+         */
+        public EventHandlerWrapper(final EventHandlerWithJacobians handler,
+                                   final int n, final int k) {
+            this.handler = handler;
+            y        = new double[n];
+            dydy0    = new double[n][n];
+            dydp     = new double[n][k];
+        }
+
+        /** Get the underlying event handler with jacobians.
+         * @return underlying event handler with jacobians
+         */
+        public EventHandlerWithJacobians getHandler() {
+            return handler;
+        }
+
+        /** {@inheritDoc} */
+        public int eventOccurred(double t, double[] z, boolean increasing)
+            throws EventException {
+            dispatchCompoundState(z, y, dydy0, dydp);
+            return handler.eventOccurred(t, y, dydy0, dydp, increasing);
+        }
+
+        /** {@inheritDoc} */
+        public double g(double t, double[] z)
+            throws EventException {
+            dispatchCompoundState(z, y, dydy0, dydp);
+            return handler.g(t, y, dydy0, dydp);
+        }
+
+        /** {@inheritDoc} */
+        public void resetState(double t, double[] z)
+            throws EventException {
+            dispatchCompoundState(z, y, dydy0, dydp);
+            handler.resetState(t, y, dydy0, dydp);
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/ODEWithJacobians.java b/src/main/java/org/apache/commons/math/ode/jacobians/ODEWithJacobians.java
new file mode 100644
index 0000000..40a7e77
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/ODEWithJacobians.java
@@ -0,0 +1,54 @@
+/*
+ * 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.ode.jacobians;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+
+
+/** This interface represents {@link ParameterizedODE
+ * first order differential equations} with parameters and partial derivatives.
+ *
+ * @see FirstOrderIntegratorWithJacobians
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.1
+ * @deprecated as of 2.2 the complete package is deprecated, it will be replaced
+ * in 3.0 by a completely rewritten implementation
+ */
+@Deprecated
+public interface ODEWithJacobians extends FirstOrderDifferentialEquations {
+
+    /** Get the number of parameters.
+     * @return number of parameters
+     */
+    int getParametersDimension();
+
+    /** Compute the partial derivatives of ODE with respect to state.
+     * @param t current value of the independent <I>time</I> variable
+     * @param y array containing the current value of the state vector
+     * @param yDot array containing the current value of the time derivative of the state vector
+     * @param dFdY placeholder array where to put the jacobian of the ODE with respect to the state vector
+     * @param dFdP placeholder array where to put the jacobian of the ODE with respect to the parameters
+     * @throws DerivativeException this exception is propagated to the caller if the
+     * underlying user function triggers one
+     */
+    void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP)
+        throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java b/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java
new file mode 100644
index 0000000..89caad7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/ParameterizedODE.java
@@ -0,0 +1,48 @@
+/*
+ * 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.ode.jacobians;
+
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+
+
+/** This interface represents {@link FirstOrderDifferentialEquations
+ * first order differential equations} with parameters.
+ *
+ * @see FirstOrderIntegratorWithJacobians
+ *
+ * @version $Revision: 1037341 $ $Date: 2010-11-20 22:58:35 +0100 (sam. 20 nov. 2010) $
+ * @since 2.1
+ * @deprecated as of 2.2 the complete package is deprecated, it will be replaced
+ * in 3.0 by a completely rewritten implementation
+ */
+@Deprecated
+public interface ParameterizedODE extends FirstOrderDifferentialEquations {
+
+    /** Get the number of parameters.
+     * @return number of parameters
+     */
+    int getParametersDimension();
+
+    /** Set a parameter.
+     * @param i index of the parameters (must be between 0
+     * and {@link #getParametersDimension() getParametersDimension() - 1})
+     * @param value value for the parameter
+     */
+    void setParameter(int i, double value);
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java b/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java
new file mode 100644
index 0000000..8cbb747
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.java
@@ -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.ode.jacobians;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/**
+ * This interface represents a handler that should be called after
+ * each successful step.
+ *
+ * <p>The ODE integrators compute the evolution of the state vector at
+ * some grid points that depend on their own internal algorithm. Once
+ * they have found a new grid point (possibly after having computed
+ * several evaluation of the derivative at intermediate points), they
+ * provide it to objects implementing this interface. These objects
+ * typically either ignore the intermediate steps and wait for the
+ * last one, store the points in an ephemeris, or forward them to
+ * specialized processing or output methods.</p>
+ *
+ * <p>Note that is is possible to register a {@link
+ * org.apache.commons.math.ode.sampling.StepHandler classical step handler}
+ * in the low level integrator used to build a {@link FirstOrderIntegratorWithJacobians}
+ * rather than implementing this class. The step handlers registered at low level
+ * will see the big compound state whether the step handlers defined by this interface
+ * see the original state, and its jacobians in separate arrays.</p>
+ *
+ * <p>The compound state is guaranteed to contain the original state in the first
+ * elements, followed by the jacobian with respect to initial state (in row order),
+ * followed by the jacobian with respect to parameters (in row order). If for example
+ * the original state dimension is 6 and there are 3 parameters, the compound state will
+ * be a 60 elements array. The first 6 elements will be the original state, the next 36
+ * elements will be the jacobian with respect to initial state, and the remaining 18 elements
+ * will be the jacobian with respect to parameters.</p>
+ *
+ * <p>Dealing with low level step handlers is cumbersome if one really needs the jacobians
+ * in these methods, but it also prevents many data being copied back and forth between
+ * state and jacobians on one side and compound state on the other side. So for performance
+ * reasons, it is recommended to use this interface <em>only</em> if jacobians are really
+ * needed and to use lower level handlers if only state is needed.</p>
+ *
+ * @see FirstOrderIntegratorWithJacobians
+ * @see StepInterpolatorWithJacobians
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.1
+ * @deprecated as of 2.2 the complete package is deprecated, it will be replaced
+ * in 3.0 by a completely rewritten implementation
+ */
+@Deprecated
+public interface StepHandlerWithJacobians {
+
+  /** Determines whether this handler needs dense output.
+   * <p>This method allows the integrator to avoid performing extra
+   * computation if the handler does not need dense output.</p>
+   * @return true if the handler needs dense output
+   */
+  boolean requiresDenseOutput();
+
+  /** Reset the step handler.
+   * Initialize the internal data as required before the first step is
+   * handled.
+   */
+  void reset();
+
+  /**
+   * Handle the last accepted step
+   * @param interpolator interpolator for the last accepted step. For
+   * efficiency purposes, the various integrators reuse the same
+   * object on each call, so if the instance wants to keep it across
+   * all calls (for example to provide at the end of the integration a
+   * continuous model valid throughout the integration range, as the
+   * {@link org.apache.commons.math.ode.ContinuousOutputModel
+   * ContinuousOutputModel} class does), it should build a local copy
+   * using the clone method of the interpolator and store this copy.
+   * Keeping only a reference to the interpolator and reusing it will
+   * result in unpredictable behavior (potentially crashing the application).
+   * @param isLast true if the step is the last one
+   * @throws DerivativeException this exception is propagated to the
+   * caller if the underlying user function triggers one
+   */
+  void handleStep(StepInterpolatorWithJacobians interpolator, boolean isLast) throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java b/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java
new file mode 100644
index 0000000..bff9d17
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.java
@@ -0,0 +1,188 @@
+/*
+ * 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.ode.jacobians;
+
+import java.io.Externalizable;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/** This interface represents an interpolator over the last step
+ * during an ODE integration.
+ *
+ * <p>The various ODE integrators provide objects implementing this
+ * interface to the step handlers. These objects are often custom
+ * objects tightly bound to the integrator internal algorithms. The
+ * handlers can use these objects to retrieve the state vector at
+ * intermediate times between the previous and the current grid points
+ * (this feature is often called dense output).</p>
+ * <p>One important thing to note is that the step handlers may be so
+ * tightly bound to the integrators that they often share some internal
+ * state arrays. This imply that one should <em>never</em> use a direct
+ * reference to a step interpolator outside of the step handler, either
+ * for future use or for use in another thread. If such a need arise, the
+ * step interpolator <em>must</em> be copied using the dedicated
+ * {@link #copy()} method.
+ * </p>
+ *
+ * @see FirstOrderIntegratorWithJacobians
+ * @see StepHandlerWithJacobians
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.1
+ * @deprecated as of 2.2 the complete package is deprecated, it will be replaced
+ * in 3.0 by a completely rewritten implementation
+ */
+@Deprecated
+public interface StepInterpolatorWithJacobians extends Externalizable {
+
+  /**
+   * Get the previous grid point time.
+   * @return previous grid point time
+   */
+  double getPreviousTime();
+
+  /**
+   * Get the current grid point time.
+   * @return current grid point time
+   */
+  double getCurrentTime();
+
+  /**
+   * Get the time of the interpolated point.
+   * If {@link #setInterpolatedTime} has not been called, it returns
+   * the current grid point time.
+   * @return interpolation point time
+   */
+  double getInterpolatedTime();
+
+  /**
+   * Set the time of the interpolated point.
+   * <p>Setting the time outside of the current step is now allowed, but
+   * should be used with care since the accuracy of the interpolator will
+   * probably be very poor far from this step. This allowance has been
+   * added to simplify implementation of search algorithms near the
+   * step endpoints.</p>
+   * <p>Setting the time changes the instance internal state. If a
+   * specific state must be preserved, a copy of the instance must be
+   * created using {@link #copy()}.</p>
+   * @param time time of the interpolated point
+   */
+  void setInterpolatedTime(double time);
+
+  /**
+   * Get the state vector of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return state vector at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedYDot()
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   */
+  double[] getInterpolatedY() throws DerivativeException;
+
+  /**
+   * Get the partial derivatives of the state vector with respect to
+   * the initial state of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return partial derivatives of the state vector with respect to
+   * the initial state at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedY()
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   */
+  double[][] getInterpolatedDyDy0() throws DerivativeException;
+
+  /**
+   * Get the partial derivatives of the state vector with respect to
+   * the ODE parameters of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return partial derivatives of the state vector with respect to
+   * the ODE parameters at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedY()
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   */
+  double[][] getInterpolatedDyDp() throws DerivativeException;
+
+  /**
+   * Get the time derivatives of the state vector of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return derivatives of the state vector at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedY()
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   */
+  double[] getInterpolatedYDot() throws DerivativeException;
+
+  /**
+   * Get the time derivatives of the jacobian of the state vector
+   * with respect to the initial state of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return time derivatives of the jacobian of the state vector
+   * with respect to the initial state at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedY()
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   */
+  double[][] getInterpolatedDyDy0Dot() throws DerivativeException;
+
+  /**
+   * Get the time derivatives of the jacobian of the state vector
+   * with respect to the ODE parameters of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return time derivatives of the jacobian of the state vector
+   * with respect to the ODE parameters at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedY()
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   */
+  double[][] getInterpolatedDyDpDot() throws DerivativeException;
+
+  /** Check if the natural integration direction is forward.
+   * <p>This method provides the integration direction as specified by
+   * the integrator itself, it avoid some nasty problems in
+   * degenerated cases like null steps due to cancellation at step
+   * initialization, step control or discrete events
+   * triggering.</p>
+   * @return true if the integration variable (time) increases during
+   * integration
+   */
+  boolean isForward();
+
+  /** Copy the instance.
+   * <p>The copied instance is guaranteed to be independent from the
+   * original one. Both can be used with different settings for
+   * interpolated time without any side effect.</p>
+   * @return a deep copy of the instance, which can be used independently.
+   * @throws DerivativeException if this call induces an automatic
+   * step finalization that throws one
+   * @see #setInterpolatedTime(double)
+   */
+   StepInterpolatorWithJacobians copy() throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/jacobians/package.html b/src/main/java/org/apache/commons/math/ode/jacobians/package.html
new file mode 100644
index 0000000..29d6f8f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/jacobians/package.html
@@ -0,0 +1,28 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 1037341 $ -->
+<body>
+<p>
+This package was intended to solve Ordinary Differential Equations problems
+and also compute derivatives of the solution. It was introduced in 2.1 but is
+difficult to use and clumsy. It is completely deprecated in 2.2 and will be removed
+in 3.0, to be replaced by a completely new implementation, much more tightly
+bound to the top level ode package.
+</p>
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.java
new file mode 100644
index 0000000..6ba7733
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.java
@@ -0,0 +1,317 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.sampling.NordsieckStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class implements explicit Adams-Bashforth integrators for Ordinary
+ * Differential Equations.
+ *
+ * <p>Adams-Bashforth methods (in fact due to Adams alone) are explicit
+ * multistep ODE solvers. This implementation is a variation of the classical
+ * one: it uses adaptive stepsize to implement error control, whereas
+ * classical implementations are fixed step size. The value of state vector
+ * at step n+1 is a simple combination of the value at step n and of the
+ * derivatives at steps n, n-1, n-2 ... Depending on the number k of previous
+ * steps one wants to use for computing the next value, different formulas
+ * are available:</p>
+ * <ul>
+ *   <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + h y'<sub>n</sub></li>
+ *   <li>k = 2: y<sub>n+1</sub> = y<sub>n</sub> + h (3y'<sub>n</sub>-y'<sub>n-1</sub>)/2</li>
+ *   <li>k = 3: y<sub>n+1</sub> = y<sub>n</sub> + h (23y'<sub>n</sub>-16y'<sub>n-1</sub>+5y'<sub>n-2</sub>)/12</li>
+ *   <li>k = 4: y<sub>n+1</sub> = y<sub>n</sub> + h (55y'<sub>n</sub>-59y'<sub>n-1</sub>+37y'<sub>n-2</sub>-9y'<sub>n-3</sub>)/24</li>
+ *   <li>...</li>
+ * </ul>
+ *
+ * <p>A k-steps Adams-Bashforth method is of order k.</p>
+ *
+ * <h3>Implementation details</h3>
+ *
+ * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as:
+ * <pre>
+ * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative
+ * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative
+ * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative
+ * ...
+ * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative
+ * </pre></p>
+ *
+ * <p>The definitions above use the classical representation with several previous first
+ * derivatives. Lets define
+ * <pre>
+ *   q<sub>n</sub> = [ s<sub>1</sub>(n-1) s<sub>1</sub>(n-2) ... s<sub>1</sub>(n-(k-1)) ]<sup>T</sup>
+ * </pre>
+ * (we omit the k index in the notation for clarity). With these definitions,
+ * Adams-Bashforth methods can be written:
+ * <ul>
+ *   <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n)</li>
+ *   <li>k = 2: y<sub>n+1</sub> = y<sub>n</sub> + 3/2 s<sub>1</sub>(n) + [ -1/2 ] q<sub>n</sub></li>
+ *   <li>k = 3: y<sub>n+1</sub> = y<sub>n</sub> + 23/12 s<sub>1</sub>(n) + [ -16/12 5/12 ] q<sub>n</sub></li>
+ *   <li>k = 4: y<sub>n+1</sub> = y<sub>n</sub> + 55/24 s<sub>1</sub>(n) + [ -59/24 37/24 -9/24 ] q<sub>n</sub></li>
+ *   <li>...</li>
+ * </ul></p>
+ *
+ * <p>Instead of using the classical representation with first derivatives only (y<sub>n</sub>,
+ * s<sub>1</sub>(n) and q<sub>n</sub>), our implementation uses the Nordsieck vector with
+ * higher degrees scaled derivatives all taken at the same step (y<sub>n</sub>, s<sub>1</sub>(n)
+ * and r<sub>n</sub>) where r<sub>n</sub> is defined as:
+ * <pre>
+ * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup>
+ * </pre>
+ * (here again we omit the k index in the notation for clarity)
+ * </p>
+ *
+ * <p>Taylor series formulas show that for any index offset i, s<sub>1</sub>(n-i) can be
+ * computed from s<sub>1</sub>(n), s<sub>2</sub>(n) ... s<sub>k</sub>(n), the formula being exact
+ * for degree k polynomials.
+ * <pre>
+ * s<sub>1</sub>(n-i) = s<sub>1</sub>(n) + &sum;<sub>j</sub> j (-i)<sup>j-1</sup> s<sub>j</sub>(n)
+ * </pre>
+ * The previous formula can be used with several values for i to compute the transform between
+ * classical representation and Nordsieck vector. The transform between r<sub>n</sub>
+ * and q<sub>n</sub> resulting from the Taylor series formulas above is:
+ * <pre>
+ * q<sub>n</sub> = s<sub>1</sub>(n) u + P r<sub>n</sub>
+ * </pre>
+ * where u is the [ 1 1 ... 1 ]<sup>T</sup> vector and P is the (k-1)&times;(k-1) matrix built
+ * with the j (-i)<sup>j-1</sup> terms:
+ * <pre>
+ *        [  -2   3   -4    5  ... ]
+ *        [  -4  12  -32   80  ... ]
+ *   P =  [  -6  27 -108  405  ... ]
+ *        [  -8  48 -256 1280  ... ]
+ *        [          ...           ]
+ * </pre></p>
+ *
+ * <p>Using the Nordsieck vector has several advantages:
+ * <ul>
+ *   <li>it greatly simplifies step interpolation as the interpolator mainly applies
+ *   Taylor series formulas,</li>
+ *   <li>it simplifies step changes that occur when discrete events that truncate
+ *   the step are triggered,</li>
+ *   <li>it allows to extend the methods in order to support adaptive stepsize.</li>
+ * </ul></p>
+ *
+ * <p>The Nordsieck vector at step n+1 is computed from the Nordsieck vector at step n as follows:
+ * <ul>
+ *   <li>y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li>
+ *   <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li>
+ *   <li>r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub></li>
+ * </ul>
+ * where A is a rows shifting matrix (the lower left part is an identity matrix):
+ * <pre>
+ *        [ 0 0   ...  0 0 | 0 ]
+ *        [ ---------------+---]
+ *        [ 1 0   ...  0 0 | 0 ]
+ *    A = [ 0 1   ...  0 0 | 0 ]
+ *        [       ...      | 0 ]
+ *        [ 0 0   ...  1 0 | 0 ]
+ *        [ 0 0   ...  0 1 | 0 ]
+ * </pre></p>
+ *
+ * <p>The P<sup>-1</sup>u vector and the P<sup>-1</sup> A P matrix do not depend on the state,
+ * they only depend on k and therefore are precomputed once for all.</p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class AdamsBashforthIntegrator extends AdamsIntegrator {
+
+    /** Integrator method name. */
+    private static final String METHOD_NAME = "Adams-Bashforth";
+
+    /**
+     * Build an Adams-Bashforth integrator with the given order and step control parameters.
+     * @param nSteps number of steps of the method excluding the one being computed
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param scalAbsoluteTolerance allowed absolute error
+     * @param scalRelativeTolerance allowed relative error
+     * @exception IllegalArgumentException if order is 1 or less
+     */
+    public AdamsBashforthIntegrator(final int nSteps,
+                                    final double minStep, final double maxStep,
+                                    final double scalAbsoluteTolerance,
+                                    final double scalRelativeTolerance)
+        throws IllegalArgumentException {
+        super(METHOD_NAME, nSteps, nSteps, minStep, maxStep,
+              scalAbsoluteTolerance, scalRelativeTolerance);
+    }
+
+    /**
+     * Build an Adams-Bashforth integrator with the given order and step control parameters.
+     * @param nSteps number of steps of the method excluding the one being computed
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param vecAbsoluteTolerance allowed absolute error
+     * @param vecRelativeTolerance allowed relative error
+     * @exception IllegalArgumentException if order is 1 or less
+     */
+    public AdamsBashforthIntegrator(final int nSteps,
+                                    final double minStep, final double maxStep,
+                                    final double[] vecAbsoluteTolerance,
+                                    final double[] vecRelativeTolerance)
+        throws IllegalArgumentException {
+        super(METHOD_NAME, nSteps, nSteps, minStep, maxStep,
+              vecAbsoluteTolerance, vecRelativeTolerance);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public double integrate(final FirstOrderDifferentialEquations equations,
+                            final double t0, final double[] y0,
+                            final double t, final double[] y)
+        throws DerivativeException, IntegratorException {
+
+        final int n = y0.length;
+        sanityChecks(equations, t0, y0, t, y);
+        setEquations(equations);
+        resetEvaluations();
+        final boolean forward = t > t0;
+
+        // initialize working arrays
+        if (y != y0) {
+            System.arraycopy(y0, 0, y, 0, n);
+        }
+        final double[] yDot = new double[n];
+
+        // set up an interpolator sharing the integrator arrays
+        final NordsieckStepInterpolator interpolator = new NordsieckStepInterpolator();
+        interpolator.reinitialize(y, forward);
+
+        // set up integration control objects
+        for (StepHandler handler : stepHandlers) {
+            handler.reset();
+        }
+        setStateInitialized(false);
+
+        // compute the initial Nordsieck vector using the configured starter integrator
+        start(t0, y, t);
+        interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck);
+        interpolator.storeTime(stepStart);
+        final int lastRow = nordsieck.getRowDimension() - 1;
+
+        // reuse the step that was chosen by the starter integrator
+        double hNew = stepSize;
+        interpolator.rescale(hNew);
+
+        // main integration loop
+        isLastStep = false;
+        do {
+
+            double error = 10;
+            while (error >= 1.0) {
+
+                stepSize = hNew;
+
+                // evaluate error using the last term of the Taylor expansion
+                error = 0;
+                for (int i = 0; i < mainSetDimension; ++i) {
+                    final double yScale = FastMath.abs(y[i]);
+                    final double tol = (vecAbsoluteTolerance == null) ?
+                                       (scalAbsoluteTolerance + scalRelativeTolerance * yScale) :
+                                       (vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yScale);
+                    final double ratio  = nordsieck.getEntry(lastRow, i) / tol;
+                    error += ratio * ratio;
+                }
+                error = FastMath.sqrt(error / mainSetDimension);
+
+                if (error >= 1.0) {
+                    // reject the step and attempt to reduce error by stepsize control
+                    final double factor = computeStepGrowShrinkFactor(error);
+                    hNew = filterStep(stepSize * factor, forward, false);
+                    interpolator.rescale(hNew);
+
+                }
+            }
+
+            // predict a first estimate of the state at step end
+            final double stepEnd = stepStart + stepSize;
+            interpolator.shift();
+            interpolator.setInterpolatedTime(stepEnd);
+            System.arraycopy(interpolator.getInterpolatedState(), 0, y, 0, y0.length);
+
+            // evaluate the derivative
+            computeDerivatives(stepEnd, y, yDot);
+
+            // update Nordsieck vector
+            final double[] predictedScaled = new double[y0.length];
+            for (int j = 0; j < y0.length; ++j) {
+                predictedScaled[j] = stepSize * yDot[j];
+            }
+            final Array2DRowRealMatrix nordsieckTmp = updateHighOrderDerivativesPhase1(nordsieck);
+            updateHighOrderDerivativesPhase2(scaled, predictedScaled, nordsieckTmp);
+            interpolator.reinitialize(stepEnd, stepSize, predictedScaled, nordsieckTmp);
+
+            // discrete events handling
+            interpolator.storeTime(stepEnd);
+            stepStart = acceptStep(interpolator, y, yDot, t);
+            scaled    = predictedScaled;
+            nordsieck = nordsieckTmp;
+            interpolator.reinitialize(stepEnd, stepSize, scaled, nordsieck);
+
+            if (!isLastStep) {
+
+                // prepare next step
+                interpolator.storeTime(stepStart);
+
+                if (resetOccurred) {
+                    // some events handler has triggered changes that
+                    // invalidate the derivatives, we need to restart from scratch
+                    start(stepStart, y, t);
+                    interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck);
+                }
+
+                // stepsize control for next step
+                final double  factor     = computeStepGrowShrinkFactor(error);
+                final double  scaledH    = stepSize * factor;
+                final double  nextT      = stepStart + scaledH;
+                final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t);
+                hNew = filterStep(scaledH, forward, nextIsLast);
+
+                final double  filteredNextT      = stepStart + hNew;
+                final boolean filteredNextIsLast = forward ? (filteredNextT >= t) : (filteredNextT <= t);
+                if (filteredNextIsLast) {
+                    hNew = t - stepStart;
+                }
+
+                interpolator.rescale(hNew);
+
+            }
+
+        } while (!isLastStep);
+
+        final double stopTime = stepStart;
+        resetInternalState();
+        return stopTime;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsIntegrator.java
new file mode 100644
index 0000000..0b114f0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsIntegrator.java
@@ -0,0 +1,131 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.MultistepIntegrator;
+
+
+/** Base class for {@link AdamsBashforthIntegrator Adams-Bashforth} and
+ * {@link AdamsMoultonIntegrator Adams-Moulton} integrators.
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AdamsIntegrator extends MultistepIntegrator {
+
+    /** Transformer. */
+    private final AdamsNordsieckTransformer transformer;
+
+    /**
+     * Build an Adams integrator with the given order and step control prameters.
+     * @param name name of the method
+     * @param nSteps number of steps of the method excluding the one being computed
+     * @param order order of the method
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param scalAbsoluteTolerance allowed absolute error
+     * @param scalRelativeTolerance allowed relative error
+     * @exception IllegalArgumentException if order is 1 or less
+     */
+    public AdamsIntegrator(final String name, final int nSteps, final int order,
+                           final double minStep, final double maxStep,
+                           final double scalAbsoluteTolerance,
+                           final double scalRelativeTolerance)
+        throws IllegalArgumentException {
+        super(name, nSteps, order, minStep, maxStep,
+              scalAbsoluteTolerance, scalRelativeTolerance);
+        transformer = AdamsNordsieckTransformer.getInstance(nSteps);
+    }
+
+    /**
+     * Build an Adams integrator with the given order and step control parameters.
+     * @param name name of the method
+     * @param nSteps number of steps of the method excluding the one being computed
+     * @param order order of the method
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param vecAbsoluteTolerance allowed absolute error
+     * @param vecRelativeTolerance allowed relative error
+     * @exception IllegalArgumentException if order is 1 or less
+     */
+    public AdamsIntegrator(final String name, final int nSteps, final int order,
+                           final double minStep, final double maxStep,
+                           final double[] vecAbsoluteTolerance,
+                           final double[] vecRelativeTolerance)
+        throws IllegalArgumentException {
+        super(name, nSteps, order, minStep, maxStep,
+              vecAbsoluteTolerance, vecRelativeTolerance);
+        transformer = AdamsNordsieckTransformer.getInstance(nSteps);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public abstract double integrate(final FirstOrderDifferentialEquations equations,
+                                     final double t0, final double[] y0,
+                                     final double t, final double[] y)
+        throws DerivativeException, IntegratorException;
+
+    /** {@inheritDoc} */
+    @Override
+    protected Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first,
+                                                        final double[][] multistep) {
+        return transformer.initializeHighOrderDerivatives(first, multistep);
+    }
+
+    /** Update the high order scaled derivatives for Adams integrators (phase 1).
+     * <p>The complete update of high order derivatives has a form similar to:
+     * <pre>
+     * r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub>
+     * </pre>
+     * this method computes the P<sup>-1</sup> A P r<sub>n</sub> part.</p>
+     * @param highOrder high order scaled derivatives
+     * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
+     * @return updated high order derivatives
+     * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix)
+     */
+    public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) {
+        return transformer.updateHighOrderDerivativesPhase1(highOrder);
+    }
+
+    /** Update the high order scaled derivatives Adams integrators (phase 2).
+     * <p>The complete update of high order derivatives has a form similar to:
+     * <pre>
+     * r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub>
+     * </pre>
+     * this method computes the (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u part.</p>
+     * <p>Phase 1 of the update must already have been performed.</p>
+     * @param start first order scaled derivatives at step start
+     * @param end first order scaled derivatives at step end
+     * @param highOrder high order scaled derivatives, will be modified
+     * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
+     * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix)
+     */
+    public void updateHighOrderDerivativesPhase2(final double[] start,
+                                                 final double[] end,
+                                                 final Array2DRowRealMatrix highOrder) {
+        transformer.updateHighOrderDerivativesPhase2(start, end, highOrder);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegrator.java
new file mode 100644
index 0000000..77a4418
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegrator.java
@@ -0,0 +1,414 @@
+/*
+ * 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.ode.nonstiff;
+
+import java.util.Arrays;
+
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.RealMatrixPreservingVisitor;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.sampling.NordsieckStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class implements implicit Adams-Moulton integrators for Ordinary
+ * Differential Equations.
+ *
+ * <p>Adams-Moulton methods (in fact due to Adams alone) are implicit
+ * multistep ODE solvers. This implementation is a variation of the classical
+ * one: it uses adaptive stepsize to implement error control, whereas
+ * classical implementations are fixed step size. The value of state vector
+ * at step n+1 is a simple combination of the value at step n and of the
+ * derivatives at steps n+1, n, n-1 ... Since y'<sub>n+1</sub> is needed to
+ * compute y<sub>n+1</sub>,another method must be used to compute a first
+ * estimate of y<sub>n+1</sub>, then compute y'<sub>n+1</sub>, then compute
+ * a final estimate of y<sub>n+1</sub> using the following formulas. Depending
+ * on the number k of previous steps one wants to use for computing the next
+ * value, different formulas are available for the final estimate:</p>
+ * <ul>
+ *   <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + h y'<sub>n+1</sub></li>
+ *   <li>k = 2: y<sub>n+1</sub> = y<sub>n</sub> + h (y'<sub>n+1</sub>+y'<sub>n</sub>)/2</li>
+ *   <li>k = 3: y<sub>n+1</sub> = y<sub>n</sub> + h (5y'<sub>n+1</sub>+8y'<sub>n</sub>-y'<sub>n-1</sub>)/12</li>
+ *   <li>k = 4: y<sub>n+1</sub> = y<sub>n</sub> + h (9y'<sub>n+1</sub>+19y'<sub>n</sub>-5y'<sub>n-1</sub>+y'<sub>n-2</sub>)/24</li>
+ *   <li>...</li>
+ * </ul>
+ *
+ * <p>A k-steps Adams-Moulton method is of order k+1.</p>
+ *
+ * <h3>Implementation details</h3>
+ *
+ * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as:
+ * <pre>
+ * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative
+ * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative
+ * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative
+ * ...
+ * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative
+ * </pre></p>
+ *
+ * <p>The definitions above use the classical representation with several previous first
+ * derivatives. Lets define
+ * <pre>
+ *   q<sub>n</sub> = [ s<sub>1</sub>(n-1) s<sub>1</sub>(n-2) ... s<sub>1</sub>(n-(k-1)) ]<sup>T</sup>
+ * </pre>
+ * (we omit the k index in the notation for clarity). With these definitions,
+ * Adams-Moulton methods can be written:
+ * <ul>
+ *   <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n+1)</li>
+ *   <li>k = 2: y<sub>n+1</sub> = y<sub>n</sub> + 1/2 s<sub>1</sub>(n+1) + [ 1/2 ] q<sub>n+1</sub></li>
+ *   <li>k = 3: y<sub>n+1</sub> = y<sub>n</sub> + 5/12 s<sub>1</sub>(n+1) + [ 8/12 -1/12 ] q<sub>n+1</sub></li>
+ *   <li>k = 4: y<sub>n+1</sub> = y<sub>n</sub> + 9/24 s<sub>1</sub>(n+1) + [ 19/24 -5/24 1/24 ] q<sub>n+1</sub></li>
+ *   <li>...</li>
+ * </ul></p>
+ *
+ * <p>Instead of using the classical representation with first derivatives only (y<sub>n</sub>,
+ * s<sub>1</sub>(n+1) and q<sub>n+1</sub>), our implementation uses the Nordsieck vector with
+ * higher degrees scaled derivatives all taken at the same step (y<sub>n</sub>, s<sub>1</sub>(n)
+ * and r<sub>n</sub>) where r<sub>n</sub> is defined as:
+ * <pre>
+ * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup>
+ * </pre>
+ * (here again we omit the k index in the notation for clarity)
+ * </p>
+ *
+ * <p>Taylor series formulas show that for any index offset i, s<sub>1</sub>(n-i) can be
+ * computed from s<sub>1</sub>(n), s<sub>2</sub>(n) ... s<sub>k</sub>(n), the formula being exact
+ * for degree k polynomials.
+ * <pre>
+ * s<sub>1</sub>(n-i) = s<sub>1</sub>(n) + &sum;<sub>j</sub> j (-i)<sup>j-1</sup> s<sub>j</sub>(n)
+ * </pre>
+ * The previous formula can be used with several values for i to compute the transform between
+ * classical representation and Nordsieck vector. The transform between r<sub>n</sub>
+ * and q<sub>n</sub> resulting from the Taylor series formulas above is:
+ * <pre>
+ * q<sub>n</sub> = s<sub>1</sub>(n) u + P r<sub>n</sub>
+ * </pre>
+ * where u is the [ 1 1 ... 1 ]<sup>T</sup> vector and P is the (k-1)&times;(k-1) matrix built
+ * with the j (-i)<sup>j-1</sup> terms:
+ * <pre>
+ *        [  -2   3   -4    5  ... ]
+ *        [  -4  12  -32   80  ... ]
+ *   P =  [  -6  27 -108  405  ... ]
+ *        [  -8  48 -256 1280  ... ]
+ *        [          ...           ]
+ * </pre></p>
+ *
+ * <p>Using the Nordsieck vector has several advantages:
+ * <ul>
+ *   <li>it greatly simplifies step interpolation as the interpolator mainly applies
+ *   Taylor series formulas,</li>
+ *   <li>it simplifies step changes that occur when discrete events that truncate
+ *   the step are triggered,</li>
+ *   <li>it allows to extend the methods in order to support adaptive stepsize.</li>
+ * </ul></p>
+ *
+ * <p>The predicted Nordsieck vector at step n+1 is computed from the Nordsieck vector at step
+ * n as follows:
+ * <ul>
+ *   <li>Y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li>
+ *   <li>S<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, Y<sub>n+1</sub>)</li>
+ *   <li>R<sub>n+1</sub> = (s<sub>1</sub>(n) - S<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub></li>
+ * </ul>
+ * where A is a rows shifting matrix (the lower left part is an identity matrix):
+ * <pre>
+ *        [ 0 0   ...  0 0 | 0 ]
+ *        [ ---------------+---]
+ *        [ 1 0   ...  0 0 | 0 ]
+ *    A = [ 0 1   ...  0 0 | 0 ]
+ *        [       ...      | 0 ]
+ *        [ 0 0   ...  1 0 | 0 ]
+ *        [ 0 0   ...  0 1 | 0 ]
+ * </pre>
+ * From this predicted vector, the corrected vector is computed as follows:
+ * <ul>
+ *   <li>y<sub>n+1</sub> = y<sub>n</sub> + S<sub>1</sub>(n+1) + [ -1 +1 -1 +1 ... &plusmn;1 ] r<sub>n+1</sub></li>
+ *   <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li>
+ *   <li>r<sub>n+1</sub> = R<sub>n+1</sub> + (s<sub>1</sub>(n+1) - S<sub>1</sub>(n+1)) P<sup>-1</sup> u</li>
+ * </ul>
+ * where the upper case Y<sub>n+1</sub>, S<sub>1</sub>(n+1) and R<sub>n+1</sub> represent the
+ * predicted states whereas the lower case y<sub>n+1</sub>, s<sub>n+1</sub> and r<sub>n+1</sub>
+ * represent the corrected states.</p>
+ *
+ * <p>The P<sup>-1</sup>u vector and the P<sup>-1</sup> A P matrix do not depend on the state,
+ * they only depend on k and therefore are precomputed once for all.</p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class AdamsMoultonIntegrator extends AdamsIntegrator {
+
+    /** Integrator method name. */
+    private static final String METHOD_NAME = "Adams-Moulton";
+
+    /**
+     * Build an Adams-Moulton integrator with the given order and error control parameters.
+     * @param nSteps number of steps of the method excluding the one being computed
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param scalAbsoluteTolerance allowed absolute error
+     * @param scalRelativeTolerance allowed relative error
+     * @exception IllegalArgumentException if order is 1 or less
+     */
+    public AdamsMoultonIntegrator(final int nSteps,
+                                  final double minStep, final double maxStep,
+                                  final double scalAbsoluteTolerance,
+                                  final double scalRelativeTolerance)
+        throws IllegalArgumentException {
+        super(METHOD_NAME, nSteps, nSteps + 1, minStep, maxStep,
+              scalAbsoluteTolerance, scalRelativeTolerance);
+    }
+
+    /**
+     * Build an Adams-Moulton integrator with the given order and error control parameters.
+     * @param nSteps number of steps of the method excluding the one being computed
+     * @param minStep minimal step (must be positive even for backward
+     * integration), the last step can be smaller than this
+     * @param maxStep maximal step (must be positive even for backward
+     * integration)
+     * @param vecAbsoluteTolerance allowed absolute error
+     * @param vecRelativeTolerance allowed relative error
+     * @exception IllegalArgumentException if order is 1 or less
+     */
+    public AdamsMoultonIntegrator(final int nSteps,
+                                  final double minStep, final double maxStep,
+                                  final double[] vecAbsoluteTolerance,
+                                  final double[] vecRelativeTolerance)
+        throws IllegalArgumentException {
+        super(METHOD_NAME, nSteps, nSteps + 1, minStep, maxStep,
+              vecAbsoluteTolerance, vecRelativeTolerance);
+    }
+
+
+    /** {@inheritDoc} */
+    @Override
+    public double integrate(final FirstOrderDifferentialEquations equations,
+                            final double t0, final double[] y0,
+                            final double t, final double[] y)
+        throws DerivativeException, IntegratorException {
+
+        final int n = y0.length;
+        sanityChecks(equations, t0, y0, t, y);
+        setEquations(equations);
+        resetEvaluations();
+        final boolean forward = t > t0;
+
+        // initialize working arrays
+        if (y != y0) {
+            System.arraycopy(y0, 0, y, 0, n);
+        }
+        final double[] yDot = new double[y0.length];
+        final double[] yTmp = new double[y0.length];
+        final double[] predictedScaled = new double[y0.length];
+        Array2DRowRealMatrix nordsieckTmp = null;
+
+        // set up two interpolators sharing the integrator arrays
+        final NordsieckStepInterpolator interpolator = new NordsieckStepInterpolator();
+        interpolator.reinitialize(y, forward);
+
+        // set up integration control objects
+        for (StepHandler handler : stepHandlers) {
+            handler.reset();
+        }
+        setStateInitialized(false);
+
+        // compute the initial Nordsieck vector using the configured starter integrator
+        start(t0, y, t);
+        interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck);
+        interpolator.storeTime(stepStart);
+
+        double hNew = stepSize;
+        interpolator.rescale(hNew);
+
+        isLastStep = false;
+        do {
+
+            double error = 10;
+            while (error >= 1.0) {
+
+                stepSize = hNew;
+
+                // predict a first estimate of the state at step end (P in the PECE sequence)
+                final double stepEnd = stepStart + stepSize;
+                interpolator.setInterpolatedTime(stepEnd);
+                System.arraycopy(interpolator.getInterpolatedState(), 0, yTmp, 0, y0.length);
+
+                // evaluate a first estimate of the derivative (first E in the PECE sequence)
+                computeDerivatives(stepEnd, yTmp, yDot);
+
+                // update Nordsieck vector
+                for (int j = 0; j < y0.length; ++j) {
+                    predictedScaled[j] = stepSize * yDot[j];
+                }
+                nordsieckTmp = updateHighOrderDerivativesPhase1(nordsieck);
+                updateHighOrderDerivativesPhase2(scaled, predictedScaled, nordsieckTmp);
+
+                // apply correction (C in the PECE sequence)
+                error = nordsieckTmp.walkInOptimizedOrder(new Corrector(y, predictedScaled, yTmp));
+
+                if (error >= 1.0) {
+                    // reject the step and attempt to reduce error by stepsize control
+                    final double factor = computeStepGrowShrinkFactor(error);
+                    hNew = filterStep(stepSize * factor, forward, false);
+                    interpolator.rescale(hNew);
+                }
+            }
+
+            // evaluate a final estimate of the derivative (second E in the PECE sequence)
+            final double stepEnd = stepStart + stepSize;
+            computeDerivatives(stepEnd, yTmp, yDot);
+
+            // update Nordsieck vector
+            final double[] correctedScaled = new double[y0.length];
+            for (int j = 0; j < y0.length; ++j) {
+                correctedScaled[j] = stepSize * yDot[j];
+            }
+            updateHighOrderDerivativesPhase2(predictedScaled, correctedScaled, nordsieckTmp);
+
+            // discrete events handling
+            System.arraycopy(yTmp, 0, y, 0, n);
+            interpolator.reinitialize(stepEnd, stepSize, correctedScaled, nordsieckTmp);
+            interpolator.storeTime(stepStart);
+            interpolator.shift();
+            interpolator.storeTime(stepEnd);
+            stepStart = acceptStep(interpolator, y, yDot, t);
+            scaled    = correctedScaled;
+            nordsieck = nordsieckTmp;
+
+            if (!isLastStep) {
+
+                // prepare next step
+                interpolator.storeTime(stepStart);
+
+                if (resetOccurred) {
+                    // some events handler has triggered changes that
+                    // invalidate the derivatives, we need to restart from scratch
+                    start(stepStart, y, t);
+                    interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck);
+
+                }
+
+                // stepsize control for next step
+                final double  factor     = computeStepGrowShrinkFactor(error);
+                final double  scaledH    = stepSize * factor;
+                final double  nextT      = stepStart + scaledH;
+                final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t);
+                hNew = filterStep(scaledH, forward, nextIsLast);
+
+                final double  filteredNextT      = stepStart + hNew;
+                final boolean filteredNextIsLast = forward ? (filteredNextT >= t) : (filteredNextT <= t);
+                if (filteredNextIsLast) {
+                    hNew = t - stepStart;
+                }
+
+                interpolator.rescale(hNew);
+            }
+
+        } while (!isLastStep);
+
+        final double stopTime  = stepStart;
+        stepStart = Double.NaN;
+        stepSize  = Double.NaN;
+        return stopTime;
+
+    }
+
+    /** Corrector for current state in Adams-Moulton method.
+     * <p>
+     * This visitor implements the Taylor series formula:
+     * <pre>
+     * Y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n+1) + [ -1 +1 -1 +1 ... &plusmn;1 ] r<sub>n+1</sub>
+     * </pre>
+     * </p>
+     */
+    private class Corrector implements RealMatrixPreservingVisitor {
+
+        /** Previous state. */
+        private final double[] previous;
+
+        /** Current scaled first derivative. */
+        private final double[] scaled;
+
+        /** Current state before correction. */
+        private final double[] before;
+
+        /** Current state after correction. */
+        private final double[] after;
+
+        /** Simple constructor.
+         * @param previous previous state
+         * @param scaled current scaled first derivative
+         * @param state state to correct (will be overwritten after visit)
+         */
+        public Corrector(final double[] previous, final double[] scaled, final double[] state) {
+            this.previous = previous;
+            this.scaled   = scaled;
+            this.after    = state;
+            this.before   = state.clone();
+        }
+
+        /** {@inheritDoc} */
+        public void start(int rows, int columns,
+                          int startRow, int endRow, int startColumn, int endColumn) {
+            Arrays.fill(after, 0.0);
+        }
+
+        /** {@inheritDoc} */
+        public void visit(int row, int column, double value) {
+            if ((row & 0x1) == 0) {
+                after[column] -= value;
+            } else {
+                after[column] += value;
+            }
+        }
+
+        /**
+         * End visiting the Nordsieck vector.
+         * <p>The correction is used to control stepsize. So its amplitude is
+         * considered to be an error, which must be normalized according to
+         * error control settings. If the normalized value is greater than 1,
+         * the correction was too large and the step must be rejected.</p>
+         * @return the normalized correction, if greater than 1, the step
+         * must be rejected
+         */
+        public double end() {
+
+            double error = 0;
+            for (int i = 0; i < after.length; ++i) {
+                after[i] += previous[i] + scaled[i];
+                if (i < mainSetDimension) {
+                    final double yScale = FastMath.max(FastMath.abs(previous[i]), FastMath.abs(after[i]));
+                    final double tol = (vecAbsoluteTolerance == null) ?
+                                       (scalAbsoluteTolerance + scalRelativeTolerance * yScale) :
+                                       (vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yScale);
+                    final double ratio  = (after[i] - before[i]) / tol;
+                    error += ratio * ratio;
+                }
+            }
+
+            return FastMath.sqrt(error / mainSetDimension);
+
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.java b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.java
new file mode 100644
index 0000000..1f16a76
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.java
@@ -0,0 +1,312 @@
+/*
+ * 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.ode.nonstiff;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.math.fraction.BigFraction;
+import org.apache.commons.math.linear.Array2DRowFieldMatrix;
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.DefaultFieldMatrixChangingVisitor;
+import org.apache.commons.math.linear.FieldDecompositionSolver;
+import org.apache.commons.math.linear.FieldLUDecompositionImpl;
+import org.apache.commons.math.linear.FieldMatrix;
+import org.apache.commons.math.linear.MatrixUtils;
+
+/** Transformer to Nordsieck vectors for Adams integrators.
+ * <p>This class i used by {@link AdamsBashforthIntegrator Adams-Bashforth} and
+ * {@link AdamsMoultonIntegrator Adams-Moulton} integrators to convert between
+ * classical representation with several previous first derivatives and Nordsieck
+ * representation with higher order scaled derivatives.</p>
+ *
+ * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as:
+ * <pre>
+ * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative
+ * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative
+ * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative
+ * ...
+ * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative
+ * </pre></p>
+ *
+ * <p>With the previous definition, the classical representation of multistep methods
+ * uses first derivatives only, i.e. it handles y<sub>n</sub>, s<sub>1</sub>(n) and
+ * q<sub>n</sub> where q<sub>n</sub> is defined as:
+ * <pre>
+ *   q<sub>n</sub> = [ s<sub>1</sub>(n-1) s<sub>1</sub>(n-2) ... s<sub>1</sub>(n-(k-1)) ]<sup>T</sup>
+ * </pre>
+ * (we omit the k index in the notation for clarity).</p>
+ *
+ * <p>Another possible representation uses the Nordsieck vector with
+ * higher degrees scaled derivatives all taken at the same step, i.e it handles y<sub>n</sub>,
+ * s<sub>1</sub>(n) and r<sub>n</sub>) where r<sub>n</sub> is defined as:
+ * <pre>
+ * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup>
+ * </pre>
+ * (here again we omit the k index in the notation for clarity)
+ * </p>
+ *
+ * <p>Taylor series formulas show that for any index offset i, s<sub>1</sub>(n-i) can be
+ * computed from s<sub>1</sub>(n), s<sub>2</sub>(n) ... s<sub>k</sub>(n), the formula being exact
+ * for degree k polynomials.
+ * <pre>
+ * s<sub>1</sub>(n-i) = s<sub>1</sub>(n) + &sum;<sub>j</sub> j (-i)<sup>j-1</sup> s<sub>j</sub>(n)
+ * </pre>
+ * The previous formula can be used with several values for i to compute the transform between
+ * classical representation and Nordsieck vector at step end. The transform between r<sub>n</sub>
+ * and q<sub>n</sub> resulting from the Taylor series formulas above is:
+ * <pre>
+ * q<sub>n</sub> = s<sub>1</sub>(n) u + P r<sub>n</sub>
+ * </pre>
+ * where u is the [ 1 1 ... 1 ]<sup>T</sup> vector and P is the (k-1)&times;(k-1) matrix built
+ * with the j (-i)<sup>j-1</sup> terms:
+ * <pre>
+ *        [  -2   3   -4    5  ... ]
+ *        [  -4  12  -32   80  ... ]
+ *   P =  [  -6  27 -108  405  ... ]
+ *        [  -8  48 -256 1280  ... ]
+ *        [          ...           ]
+ * </pre></p>
+ *
+ * <p>Changing -i into +i in the formula above can be used to compute a similar transform between
+ * classical representation and Nordsieck vector at step start. The resulting matrix is simply
+ * the absolute value of matrix P.</p>
+ *
+ * <p>For {@link AdamsBashforthIntegrator Adams-Bashforth} method, the Nordsieck vector
+ * at step n+1 is computed from the Nordsieck vector at step n as follows:
+ * <ul>
+ *   <li>y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li>
+ *   <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li>
+ *   <li>r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub></li>
+ * </ul>
+ * where A is a rows shifting matrix (the lower left part is an identity matrix):
+ * <pre>
+ *        [ 0 0   ...  0 0 | 0 ]
+ *        [ ---------------+---]
+ *        [ 1 0   ...  0 0 | 0 ]
+ *    A = [ 0 1   ...  0 0 | 0 ]
+ *        [       ...      | 0 ]
+ *        [ 0 0   ...  1 0 | 0 ]
+ *        [ 0 0   ...  0 1 | 0 ]
+ * </pre></p>
+ *
+ * <p>For {@link AdamsMoultonIntegrator Adams-Moulton} method, the predicted Nordsieck vector
+ * at step n+1 is computed from the Nordsieck vector at step n as follows:
+ * <ul>
+ *   <li>Y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li>
+ *   <li>S<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, Y<sub>n+1</sub>)</li>
+ *   <li>R<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub></li>
+ * </ul>
+ * From this predicted vector, the corrected vector is computed as follows:
+ * <ul>
+ *   <li>y<sub>n+1</sub> = y<sub>n</sub> + S<sub>1</sub>(n+1) + [ -1 +1 -1 +1 ... &plusmn;1 ] r<sub>n+1</sub></li>
+ *   <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li>
+ *   <li>r<sub>n+1</sub> = R<sub>n+1</sub> + (s<sub>1</sub>(n+1) - S<sub>1</sub>(n+1)) P<sup>-1</sup> u</li>
+ * </ul>
+ * where the upper case Y<sub>n+1</sub>, S<sub>1</sub>(n+1) and R<sub>n+1</sub> represent the
+ * predicted states whereas the lower case y<sub>n+1</sub>, s<sub>n+1</sub> and r<sub>n+1</sub>
+ * represent the corrected states.</p>
+ *
+ * <p>We observe that both methods use similar update formulas. In both cases a P<sup>-1</sup>u
+ * vector and a P<sup>-1</sup> A P matrix are used that do not depend on the state,
+ * they only depend on k. This class handles these transformations.</p>
+ *
+ * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $
+ * @since 2.0
+ */
+public class AdamsNordsieckTransformer {
+
+    /** Cache for already computed coefficients. */
+    private static final Map<Integer, AdamsNordsieckTransformer> CACHE =
+        new HashMap<Integer, AdamsNordsieckTransformer>();
+
+    /** Initialization matrix for the higher order derivatives wrt y'', y''' ... */
+    private final Array2DRowRealMatrix initialization;
+
+    /** Update matrix for the higher order derivatives h<sup>2</sup>/2y'', h<sup>3</sup>/6 y''' ... */
+    private final Array2DRowRealMatrix update;
+
+    /** Update coefficients of the higher order derivatives wrt y'. */
+    private final double[] c1;
+
+    /** Simple constructor.
+     * @param nSteps number of steps of the multistep method
+     * (excluding the one being computed)
+     */
+    private AdamsNordsieckTransformer(final int nSteps) {
+
+        // compute exact coefficients
+        FieldMatrix<BigFraction> bigP = buildP(nSteps);
+        FieldDecompositionSolver<BigFraction> pSolver =
+            new FieldLUDecompositionImpl<BigFraction>(bigP).getSolver();
+
+        BigFraction[] u = new BigFraction[nSteps];
+        Arrays.fill(u, BigFraction.ONE);
+        BigFraction[] bigC1 = pSolver.solve(u);
+
+        // update coefficients are computed by combining transform from
+        // Nordsieck to multistep, then shifting rows to represent step advance
+        // then applying inverse transform
+        BigFraction[][] shiftedP = bigP.getData();
+        for (int i = shiftedP.length - 1; i > 0; --i) {
+            // shift rows
+            shiftedP[i] = shiftedP[i - 1];
+        }
+        shiftedP[0] = new BigFraction[nSteps];
+        Arrays.fill(shiftedP[0], BigFraction.ZERO);
+        FieldMatrix<BigFraction> bigMSupdate =
+            pSolver.solve(new Array2DRowFieldMatrix<BigFraction>(shiftedP, false));
+
+        // initialization coefficients, computed from a R matrix = abs(P)
+        bigP.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<BigFraction>(BigFraction.ZERO) {
+            /** {@inheritDoc} */
+            @Override
+            public BigFraction visit(int row, int column, BigFraction value) {
+                return ((column & 0x1) == 0x1) ? value : value.negate();
+            }
+        });
+        FieldMatrix<BigFraction> bigRInverse =
+            new FieldLUDecompositionImpl<BigFraction>(bigP).getSolver().getInverse();
+
+        // convert coefficients to double
+        initialization = MatrixUtils.bigFractionMatrixToRealMatrix(bigRInverse);
+        update         = MatrixUtils.bigFractionMatrixToRealMatrix(bigMSupdate);
+        c1             = new double[nSteps];
+        for (int i = 0; i < nSteps; ++i) {
+            c1[i] = bigC1[i].doubleValue();
+        }
+
+    }
+
+    /** Get the Nordsieck transformer for a given number of steps.
+     * @param nSteps number of steps of the multistep method
+     * (excluding the one being computed)
+     * @return Nordsieck transformer for the specified number of steps
+     */
+    public static AdamsNordsieckTransformer getInstance(final int nSteps) {
+        synchronized(CACHE) {
+            AdamsNordsieckTransformer t = CACHE.get(nSteps);
+            if (t == null) {
+                t = new AdamsNordsieckTransformer(nSteps);
+                CACHE.put(nSteps, t);
+            }
+            return t;
+        }
+    }
+
+    /** Get the number of steps of the method
+     * (excluding the one being computed).
+     * @return number of steps of the method
+     * (excluding the one being computed)
+     */
+    public int getNSteps() {
+        return c1.length;
+    }
+
+    /** Build the P matrix.
+     * <p>The P matrix general terms are shifted j (-i)<sup>j-1</sup> terms:
+     * <pre>
+     *        [  -2   3   -4    5  ... ]
+     *        [  -4  12  -32   80  ... ]
+     *   P =  [  -6  27 -108  405  ... ]
+     *        [  -8  48 -256 1280  ... ]
+     *        [          ...           ]
+     * </pre></p>
+     * @param nSteps number of steps of the multistep method
+     * (excluding the one being computed)
+     * @return P matrix
+     */
+    private FieldMatrix<BigFraction> buildP(final int nSteps) {
+
+        final BigFraction[][] pData = new BigFraction[nSteps][nSteps];
+
+        for (int i = 0; i < pData.length; ++i) {
+            // build the P matrix elements from Taylor series formulas
+            final BigFraction[] pI = pData[i];
+            final int factor = -(i + 1);
+            int aj = factor;
+            for (int j = 0; j < pI.length; ++j) {
+                pI[j] = new BigFraction(aj * (j + 2));
+                aj *= factor;
+            }
+        }
+
+        return new Array2DRowFieldMatrix<BigFraction>(pData, false);
+
+    }
+
+    /** Initialize the high order scaled derivatives at step start.
+     * @param first first scaled derivative at step start
+     * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1)
+     * will be modified
+     * @return high order derivatives at step start
+     */
+    public Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first,
+                                                     final double[][] multistep) {
+        for (int i = 0; i < multistep.length; ++i) {
+            final double[] msI = multistep[i];
+            for (int j = 0; j < first.length; ++j) {
+                msI[j] -= first[j];
+            }
+        }
+        return initialization.multiply(new Array2DRowRealMatrix(multistep, false));
+    }
+
+    /** Update the high order scaled derivatives for Adams integrators (phase 1).
+     * <p>The complete update of high order derivatives has a form similar to:
+     * <pre>
+     * r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub>
+     * </pre>
+     * this method computes the P<sup>-1</sup> A P r<sub>n</sub> part.</p>
+     * @param highOrder high order scaled derivatives
+     * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
+     * @return updated high order derivatives
+     * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix)
+     */
+    public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) {
+        return update.multiply(highOrder);
+    }
+
+    /** Update the high order scaled derivatives Adams integrators (phase 2).
+     * <p>The complete update of high order derivatives has a form similar to:
+     * <pre>
+     * r<sub>n+1</sub> = (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u + P<sup>-1</sup> A P r<sub>n</sub>
+     * </pre>
+     * this method computes the (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u part.</p>
+     * <p>Phase 1 of the update must already have been performed.</p>
+     * @param start first order scaled derivatives at step start
+     * @param end first order scaled derivatives at step end
+     * @param highOrder high order scaled derivatives, will be modified
+     * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k))
+     * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix)
+     */
+    public void updateHighOrderDerivativesPhase2(final double[] start,
+                                                 final double[] end,
+                                                 final Array2DRowRealMatrix highOrder) {
+        final double[][] data = highOrder.getDataRef();
+        for (int i = 0; i < data.length; ++i) {
+            final double[] dataI = data[i];
+            final double c1I = c1[i];
+            for (int j = 0; j < dataI.length; ++j) {
+                dataI[j] += c1I * (start[j] - end[j]);
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.java
new file mode 100644
index 0000000..bfae8f4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.java
@@ -0,0 +1,349 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.ode.AbstractIntegrator;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.ExtendedFirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This abstract class holds the common part of all adaptive
+ * stepsize integrators for Ordinary Differential Equations.
+ *
+ * <p>These algorithms perform integration with stepsize control, which
+ * means the user does not specify the integration step but rather a
+ * tolerance on error. The error threshold is computed as
+ * <pre>
+ * threshold_i = absTol_i + relTol_i * max (abs (ym), abs (ym+1))
+ * </pre>
+ * where absTol_i is the absolute tolerance for component i of the
+ * state vector and relTol_i is the relative tolerance for the same
+ * component. The user can also use only two scalar values absTol and
+ * relTol which will be used for all components.
+ * </p>
+ *
+ * <p>If the Ordinary Differential Equations is an {@link ExtendedFirstOrderDifferentialEquations
+ * extended ODE} rather than a {@link FirstOrderDifferentialEquations basic ODE},
+ * then <em>only</em> the {@link ExtendedFirstOrderDifferentialEquations#getMainSetDimension()
+ * main set} part of the state vector is used for stepsize control, not the complete
+ * state vector.
+ * </p>
+ *
+ * <p>If the estimated error for ym+1 is such that
+ * <pre>
+ * sqrt((sum (errEst_i / threshold_i)^2 ) / n) < 1
+ * </pre>
+ *
+ * (where n is the main set dimension) then the step is accepted,
+ * otherwise the step is rejected and a new attempt is made with a new
+ * stepsize.</p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ *
+ */
+
+public abstract class AdaptiveStepsizeIntegrator
+  extends AbstractIntegrator {
+
+    /** Allowed absolute scalar error. */
+    protected final double scalAbsoluteTolerance;
+
+    /** Allowed relative scalar error. */
+    protected final double scalRelativeTolerance;
+
+    /** Allowed absolute vectorial error. */
+    protected final double[] vecAbsoluteTolerance;
+
+    /** Allowed relative vectorial error. */
+    protected final double[] vecRelativeTolerance;
+
+    /** Main set dimension. */
+    protected int mainSetDimension;
+
+    /** User supplied initial step. */
+    private double initialStep;
+
+    /** Minimal step. */
+    private final double minStep;
+
+    /** Maximal step. */
+    private final double maxStep;
+
+  /** Build an integrator with the given stepsize bounds.
+   * The default step handler does nothing.
+   * @param name name of the method
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param scalAbsoluteTolerance allowed absolute error
+   * @param scalRelativeTolerance allowed relative error
+   */
+  public AdaptiveStepsizeIntegrator(final String name,
+                                    final double minStep, final double maxStep,
+                                    final double scalAbsoluteTolerance,
+                                    final double scalRelativeTolerance) {
+
+    super(name);
+
+    this.minStep     = FastMath.abs(minStep);
+    this.maxStep     = FastMath.abs(maxStep);
+    this.initialStep = -1.0;
+
+    this.scalAbsoluteTolerance = scalAbsoluteTolerance;
+    this.scalRelativeTolerance = scalRelativeTolerance;
+    this.vecAbsoluteTolerance  = null;
+    this.vecRelativeTolerance  = null;
+
+    resetInternalState();
+
+  }
+
+  /** Build an integrator with the given stepsize bounds.
+   * The default step handler does nothing.
+   * @param name name of the method
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param vecAbsoluteTolerance allowed absolute error
+   * @param vecRelativeTolerance allowed relative error
+   */
+  public AdaptiveStepsizeIntegrator(final String name,
+                                    final double minStep, final double maxStep,
+                                    final double[] vecAbsoluteTolerance,
+                                    final double[] vecRelativeTolerance) {
+
+    super(name);
+
+    this.minStep     = minStep;
+    this.maxStep     = maxStep;
+    this.initialStep = -1.0;
+
+    this.scalAbsoluteTolerance = 0;
+    this.scalRelativeTolerance = 0;
+    this.vecAbsoluteTolerance  = vecAbsoluteTolerance.clone();
+    this.vecRelativeTolerance  = vecRelativeTolerance.clone();
+
+    resetInternalState();
+
+  }
+
+  /** Set the initial step size.
+   * <p>This method allows the user to specify an initial positive
+   * step size instead of letting the integrator guess it by
+   * itself. If this method is not called before integration is
+   * started, the initial step size will be estimated by the
+   * integrator.</p>
+   * @param initialStepSize initial step size to use (must be positive even
+   * for backward integration ; providing a negative value or a value
+   * outside of the min/max step interval will lead the integrator to
+   * ignore the value and compute the initial step size by itself)
+   */
+  public void setInitialStepSize(final double initialStepSize) {
+    if ((initialStepSize < minStep) || (initialStepSize > maxStep)) {
+      initialStep = -1.0;
+    } else {
+      initialStep = initialStepSize;
+    }
+  }
+
+  /** Perform some sanity checks on the integration parameters.
+   * @param equations differential equations set
+   * @param t0 start time
+   * @param y0 state vector at t0
+   * @param t target time for the integration
+   * @param y placeholder where to put the state vector
+   * @exception IntegratorException if some inconsistency is detected
+   */
+  @Override
+  protected void sanityChecks(final FirstOrderDifferentialEquations equations,
+                              final double t0, final double[] y0,
+                              final double t, final double[] y)
+      throws IntegratorException {
+
+      super.sanityChecks(equations, t0, y0, t, y);
+
+      if (equations instanceof ExtendedFirstOrderDifferentialEquations) {
+          mainSetDimension = ((ExtendedFirstOrderDifferentialEquations) equations).getMainSetDimension();
+      } else {
+          mainSetDimension = equations.getDimension();
+      }
+
+      if ((vecAbsoluteTolerance != null) && (vecAbsoluteTolerance.length != mainSetDimension)) {
+          throw new IntegratorException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, mainSetDimension, vecAbsoluteTolerance.length);
+      }
+
+      if ((vecRelativeTolerance != null) && (vecRelativeTolerance.length != mainSetDimension)) {
+          throw new IntegratorException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, mainSetDimension, vecRelativeTolerance.length);
+      }
+
+  }
+
+  /** Initialize the integration step.
+   * @param equations differential equations set
+   * @param forward forward integration indicator
+   * @param order order of the method
+   * @param scale scaling vector for the state vector (can be shorter than state vector)
+   * @param t0 start time
+   * @param y0 state vector at t0
+   * @param yDot0 first time derivative of y0
+   * @param y1 work array for a state vector
+   * @param yDot1 work array for the first time derivative of y1
+   * @return first integration step
+   * @exception DerivativeException this exception is propagated to
+   * the caller if the underlying user function triggers one
+   */
+  public double initializeStep(final FirstOrderDifferentialEquations equations,
+                               final boolean forward, final int order, final double[] scale,
+                               final double t0, final double[] y0, final double[] yDot0,
+                               final double[] y1, final double[] yDot1)
+      throws DerivativeException {
+
+    if (initialStep > 0) {
+      // use the user provided value
+      return forward ? initialStep : -initialStep;
+    }
+
+    // very rough first guess : h = 0.01 * ||y/scale|| / ||y'/scale||
+    // this guess will be used to perform an Euler step
+    double ratio;
+    double yOnScale2 = 0;
+    double yDotOnScale2 = 0;
+    for (int j = 0; j < scale.length; ++j) {
+      ratio         = y0[j] / scale[j];
+      yOnScale2    += ratio * ratio;
+      ratio         = yDot0[j] / scale[j];
+      yDotOnScale2 += ratio * ratio;
+    }
+
+    double h = ((yOnScale2 < 1.0e-10) || (yDotOnScale2 < 1.0e-10)) ?
+               1.0e-6 : (0.01 * FastMath.sqrt(yOnScale2 / yDotOnScale2));
+    if (! forward) {
+      h = -h;
+    }
+
+    // perform an Euler step using the preceding rough guess
+    for (int j = 0; j < y0.length; ++j) {
+      y1[j] = y0[j] + h * yDot0[j];
+    }
+    computeDerivatives(t0 + h, y1, yDot1);
+
+    // estimate the second derivative of the solution
+    double yDDotOnScale = 0;
+    for (int j = 0; j < scale.length; ++j) {
+      ratio         = (yDot1[j] - yDot0[j]) / scale[j];
+      yDDotOnScale += ratio * ratio;
+    }
+    yDDotOnScale = FastMath.sqrt(yDDotOnScale) / h;
+
+    // step size is computed such that
+    // h^order * max (||y'/tol||, ||y''/tol||) = 0.01
+    final double maxInv2 = FastMath.max(FastMath.sqrt(yDotOnScale2), yDDotOnScale);
+    final double h1 = (maxInv2 < 1.0e-15) ?
+                      FastMath.max(1.0e-6, 0.001 * FastMath.abs(h)) :
+                      FastMath.pow(0.01 / maxInv2, 1.0 / order);
+    h = FastMath.min(100.0 * FastMath.abs(h), h1);
+    h = FastMath.max(h, 1.0e-12 * FastMath.abs(t0));  // avoids cancellation when computing t1 - t0
+    if (h < getMinStep()) {
+      h = getMinStep();
+    }
+    if (h > getMaxStep()) {
+      h = getMaxStep();
+    }
+    if (! forward) {
+      h = -h;
+    }
+
+    return h;
+
+  }
+
+  /** Filter the integration step.
+   * @param h signed step
+   * @param forward forward integration indicator
+   * @param acceptSmall if true, steps smaller than the minimal value
+   * are silently increased up to this value, if false such small
+   * steps generate an exception
+   * @return a bounded integration step (h if no bound is reach, or a bounded value)
+   * @exception IntegratorException if the step is too small and acceptSmall is false
+   */
+  protected double filterStep(final double h, final boolean forward, final boolean acceptSmall)
+    throws IntegratorException {
+
+      double filteredH = h;
+      if (FastMath.abs(h) < minStep) {
+          if (acceptSmall) {
+              filteredH = forward ? minStep : -minStep;
+          } else {
+              throw new IntegratorException(
+                      LocalizedFormats.MINIMAL_STEPSIZE_REACHED_DURING_INTEGRATION,
+                      minStep, FastMath.abs(h));
+          }
+      }
+
+      if (filteredH > maxStep) {
+          filteredH = maxStep;
+      } else if (filteredH < -maxStep) {
+          filteredH = -maxStep;
+      }
+
+      return filteredH;
+
+  }
+
+  /** {@inheritDoc} */
+  public abstract double integrate (FirstOrderDifferentialEquations equations,
+                                    double t0, double[] y0,
+                                    double t, double[] y)
+    throws DerivativeException, IntegratorException;
+
+  /** {@inheritDoc} */
+  @Override
+  public double getCurrentStepStart() {
+    return stepStart;
+  }
+
+  /** Reset internal state to dummy values. */
+  protected void resetInternalState() {
+    stepStart = Double.NaN;
+    stepSize  = FastMath.sqrt(minStep * maxStep);
+  }
+
+  /** Get the minimal step.
+   * @return minimal step
+   */
+  public double getMinStep() {
+    return minStep;
+  }
+
+  /** Get the maximal step.
+   * @return maximal step
+   */
+  public double getMaxStep() {
+    return maxStep;
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.java
new file mode 100644
index 0000000..a993d40
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.java
@@ -0,0 +1,75 @@
+/*
+ * 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.ode.nonstiff;
+
+
+/**
+ * This class implements the classical fourth order Runge-Kutta
+ * integrator for Ordinary Differential Equations (it is the most
+ * often used Runge-Kutta method).
+ *
+ * <p>This method is an explicit Runge-Kutta method, its Butcher-array
+ * is the following one :
+ * <pre>
+ *    0  |  0    0    0    0
+ *   1/2 | 1/2   0    0    0
+ *   1/2 |  0   1/2   0    0
+ *    1  |  0    0    1    0
+ *       |--------------------
+ *       | 1/6  1/3  1/3  1/6
+ * </pre>
+ * </p>
+ *
+ * @see EulerIntegrator
+ * @see GillIntegrator
+ * @see MidpointIntegrator
+ * @see ThreeEighthesIntegrator
+ * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $
+ * @since 1.2
+ */
+
+public class ClassicalRungeKuttaIntegrator extends RungeKuttaIntegrator {
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    1.0 / 2.0, 1.0 / 2.0, 1.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+    { 1.0 / 2.0 },
+    { 0.0, 1.0 / 2.0 },
+    { 0.0, 0.0, 1.0 }
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    1.0 / 6.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 6.0
+  };
+
+  /** Simple constructor.
+   * Build a fourth-order Runge-Kutta integrator with the given
+   * step.
+   * @param step integration step
+   */
+  public ClassicalRungeKuttaIntegrator(final double step) {
+    super("classical Runge-Kutta", STATIC_C, STATIC_A, STATIC_B,
+          new ClassicalRungeKuttaStepInterpolator(), step);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInterpolator.java
new file mode 100644
index 0000000..90596b1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaStepInterpolator.java
@@ -0,0 +1,110 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class implements a step interpolator for the classical fourth
+ * order Runge-Kutta integrator.
+ *
+ * <p>This interpolator allows to compute dense output inside the last
+ * step computed. The interpolation equation is consistent with the
+ * integration scheme :
+
+ * <pre>
+ *   y(t_n + theta h) = y (t_n + h)
+ *                    + (1 - theta) (h/6) [ (-4 theta^2 + 5 theta - 1) y'_1
+ *                                          +(4 theta^2 - 2 theta - 2) (y'_2 + y'_3)
+ *                                          -(4 theta^2 +   theta + 1) y'_4
+ *                                        ]
+ * </pre>
+ *
+ * where theta belongs to [0 ; 1] and where y'_1 to y'_4 are the four
+ * evaluations of the derivatives already computed during the
+ * step.</p>
+ *
+ * @see ClassicalRungeKuttaIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class ClassicalRungeKuttaStepInterpolator
+    extends RungeKuttaStepInterpolator {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -6576285612589783992L;
+
+    /** Simple constructor.
+     * This constructor builds an instance that is not usable yet, the
+     * {@link RungeKuttaStepInterpolator#reinitialize} method should be
+     * called before using the instance in order to initialize the
+     * internal arrays. This constructor is used only in order to delay
+     * the initialization in some cases. The {@link RungeKuttaIntegrator}
+     * class uses the prototyping design pattern to create the step
+     * interpolators by cloning an uninitialized model and latter initializing
+     * the copy.
+     */
+    public ClassicalRungeKuttaStepInterpolator() {
+    }
+
+    /** Copy constructor.
+     * @param interpolator interpolator to copy from. The copy is a deep
+     * copy: its arrays are separated from the original arrays of the
+     * instance
+     */
+    public ClassicalRungeKuttaStepInterpolator(final ClassicalRungeKuttaStepInterpolator interpolator) {
+        super(interpolator);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected StepInterpolator doCopy() {
+        return new ClassicalRungeKuttaStepInterpolator(this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                            final double oneMinusThetaH)
+        throws DerivativeException {
+
+        final double fourTheta      = 4 * theta;
+        final double oneMinusTheta  = 1 - theta;
+        final double oneMinus2Theta = 1 - 2 * theta;
+        final double s             = oneMinusThetaH / 6.0;
+        final double coeff1        = s * ((-fourTheta + 5) * theta - 1);
+        final double coeff23       = s * (( fourTheta - 2) * theta - 2);
+        final double coeff4        = s * ((-fourTheta - 1) * theta - 1);
+        final double coeffDot1     = oneMinusTheta * oneMinus2Theta;
+        final double coeffDot23    = 2 * theta * oneMinusTheta;
+        final double coeffDot4     = -theta * oneMinus2Theta;
+        for (int i = 0; i < interpolatedState.length; ++i) {
+            final double yDot1  = yDotK[0][i];
+            final double yDot23 = yDotK[1][i] + yDotK[2][i];
+            final double yDot4  = yDotK[3][i];
+            interpolatedState[i] =
+                currentState[i] + coeff1  * yDot1 + coeff23 * yDot23 + coeff4  * yDot4;
+            interpolatedDerivatives[i] =
+                coeffDot1 * yDot1 + coeffDot23 * yDot23 + coeffDot4 * yDot4;
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.java
new file mode 100644
index 0000000..e31991f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.java
@@ -0,0 +1,158 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class implements the 5(4) Dormand-Prince integrator for Ordinary
+ * Differential Equations.
+
+ * <p>This integrator is an embedded Runge-Kutta integrator
+ * of order 5(4) used in local extrapolation mode (i.e. the solution
+ * is computed using the high order formula) with stepsize control
+ * (and automatic step initialization) and continuous output. This
+ * method uses 7 functions evaluations per step. However, since this
+ * is an <i>fsal</i>, the last evaluation of one step is the same as
+ * the first evaluation of the next step and hence can be avoided. So
+ * the cost is really 6 functions evaluations per step.</p>
+ *
+ * <p>This method has been published (whithout the continuous output
+ * that was added by Shampine in 1986) in the following article :
+ * <pre>
+ *  A family of embedded Runge-Kutta formulae
+ *  J. R. Dormand and P. J. Prince
+ *  Journal of Computational and Applied Mathematics
+ *  volume 6, no 1, 1980, pp. 19-26
+ * </pre></p>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ */
+
+public class DormandPrince54Integrator extends EmbeddedRungeKuttaIntegrator {
+
+  /** Integrator method name. */
+  private static final String METHOD_NAME = "Dormand-Prince 5(4)";
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    1.0/5.0, 3.0/10.0, 4.0/5.0, 8.0/9.0, 1.0, 1.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+    {1.0/5.0},
+    {3.0/40.0, 9.0/40.0},
+    {44.0/45.0, -56.0/15.0, 32.0/9.0},
+    {19372.0/6561.0, -25360.0/2187.0, 64448.0/6561.0,  -212.0/729.0},
+    {9017.0/3168.0, -355.0/33.0, 46732.0/5247.0, 49.0/176.0, -5103.0/18656.0},
+    {35.0/384.0, 0.0, 500.0/1113.0, 125.0/192.0, -2187.0/6784.0, 11.0/84.0}
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    35.0/384.0, 0.0, 500.0/1113.0, 125.0/192.0, -2187.0/6784.0, 11.0/84.0, 0.0
+  };
+
+  /** Error array, element 1. */
+  private static final double E1 =     71.0 / 57600.0;
+
+  // element 2 is zero, so it is neither stored nor used
+
+  /** Error array, element 3. */
+  private static final double E3 =    -71.0 / 16695.0;
+
+  /** Error array, element 4. */
+  private static final double E4 =     71.0 / 1920.0;
+
+  /** Error array, element 5. */
+  private static final double E5 = -17253.0 / 339200.0;
+
+  /** Error array, element 6. */
+  private static final double E6 =     22.0 / 525.0;
+
+  /** Error array, element 7. */
+  private static final double E7 =     -1.0 / 40.0;
+
+  /** Simple constructor.
+   * Build a fifth order Dormand-Prince integrator with the given step bounds
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param scalAbsoluteTolerance allowed absolute error
+   * @param scalRelativeTolerance allowed relative error
+   */
+  public DormandPrince54Integrator(final double minStep, final double maxStep,
+                                   final double scalAbsoluteTolerance,
+                                   final double scalRelativeTolerance) {
+    super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince54StepInterpolator(),
+          minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+  }
+
+  /** Simple constructor.
+   * Build a fifth order Dormand-Prince integrator with the given step bounds
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param vecAbsoluteTolerance allowed absolute error
+   * @param vecRelativeTolerance allowed relative error
+   */
+  public DormandPrince54Integrator(final double minStep, final double maxStep,
+                                   final double[] vecAbsoluteTolerance,
+                                   final double[] vecRelativeTolerance) {
+    super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince54StepInterpolator(),
+          minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public int getOrder() {
+    return 5;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected double estimateError(final double[][] yDotK,
+                                 final double[] y0, final double[] y1,
+                                 final double h) {
+
+    double error = 0;
+
+    for (int j = 0; j < mainSetDimension; ++j) {
+        final double errSum = E1 * yDotK[0][j] +  E3 * yDotK[2][j] +
+                              E4 * yDotK[3][j] +  E5 * yDotK[4][j] +
+                              E6 * yDotK[5][j] +  E7 * yDotK[6][j];
+
+        final double yScale = FastMath.max(FastMath.abs(y0[j]), FastMath.abs(y1[j]));
+        final double tol = (vecAbsoluteTolerance == null) ?
+                           (scalAbsoluteTolerance + scalRelativeTolerance * yScale) :
+                               (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale);
+        final double ratio  = h * errSum / tol;
+        error += ratio * ratio;
+
+    }
+
+    return FastMath.sqrt(error / mainSetDimension);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpolator.java
new file mode 100644
index 0000000..34cd924
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince54StepInterpolator.java
@@ -0,0 +1,214 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.AbstractIntegrator;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class represents an interpolator over the last step during an
+ * ODE integration for the 5(4) Dormand-Prince integrator.
+ *
+ * @see DormandPrince54Integrator
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class DormandPrince54StepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+    /** Last row of the Butcher-array internal weights, element 0. */
+    private static final double A70 =    35.0 /  384.0;
+
+    // element 1 is zero, so it is neither stored nor used
+
+    /** Last row of the Butcher-array internal weights, element 2. */
+    private static final double A72 =   500.0 / 1113.0;
+
+    /** Last row of the Butcher-array internal weights, element 3. */
+    private static final double A73 =   125.0 /  192.0;
+
+    /** Last row of the Butcher-array internal weights, element 4. */
+    private static final double A74 = -2187.0 / 6784.0;
+
+    /** Last row of the Butcher-array internal weights, element 5. */
+    private static final double A75 =    11.0 /   84.0;
+
+    /** Shampine (1986) Dense output, element 0. */
+    private static final double D0 =  -12715105075.0 /  11282082432.0;
+
+    // element 1 is zero, so it is neither stored nor used
+
+    /** Shampine (1986) Dense output, element 2. */
+    private static final double D2 =   87487479700.0 /  32700410799.0;
+
+    /** Shampine (1986) Dense output, element 3. */
+    private static final double D3 =  -10690763975.0 /   1880347072.0;
+
+    /** Shampine (1986) Dense output, element 4. */
+    private static final double D4 =  701980252875.0 / 199316789632.0;
+
+    /** Shampine (1986) Dense output, element 5. */
+    private static final double D5 =   -1453857185.0 /    822651844.0;
+
+    /** Shampine (1986) Dense output, element 6. */
+    private static final double D6 =      69997945.0 /     29380423.0;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4104157279605906956L;
+
+    /** First vector for interpolation. */
+    private double[] v1;
+
+    /** Second vector for interpolation. */
+    private double[] v2;
+
+    /** Third vector for interpolation. */
+    private double[] v3;
+
+    /** Fourth vector for interpolation. */
+    private double[] v4;
+
+    /** Initialization indicator for the interpolation vectors. */
+    private boolean vectorsInitialized;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link #reinitialize} method should be called before using the
+   * instance in order to initialize the internal arrays. This
+   * constructor is used only in order to delay the initialization in
+   * some cases. The {@link EmbeddedRungeKuttaIntegrator} uses the
+   * prototyping design pattern to create the step interpolators by
+   * cloning an uninitialized model and latter initializing the copy.
+   */
+  public DormandPrince54StepInterpolator() {
+    super();
+    v1 = null;
+    v2 = null;
+    v3 = null;
+    v4 = null;
+    vectorsInitialized = false;
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public DormandPrince54StepInterpolator(final DormandPrince54StepInterpolator interpolator) {
+
+    super(interpolator);
+
+    if (interpolator.v1 == null) {
+
+      v1 = null;
+      v2 = null;
+      v3 = null;
+      v4 = null;
+      vectorsInitialized = false;
+
+    } else {
+
+      v1 = interpolator.v1.clone();
+      v2 = interpolator.v2.clone();
+      v3 = interpolator.v3.clone();
+      v4 = interpolator.v4.clone();
+      vectorsInitialized = interpolator.vectorsInitialized;
+
+    }
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new DormandPrince54StepInterpolator(this);
+  }
+
+
+  /** {@inheritDoc} */
+  @Override
+  public void reinitialize(final AbstractIntegrator integrator,
+                           final double[] y, final double[][] yDotK, final boolean forward) {
+    super.reinitialize(integrator, y, yDotK, forward);
+    v1 = null;
+    v2 = null;
+    v3 = null;
+    v4 = null;
+    vectorsInitialized = false;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void storeTime(final double t) {
+    super.storeTime(t);
+    vectorsInitialized = false;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+    throws DerivativeException {
+
+    if (! vectorsInitialized) {
+
+      if (v1 == null) {
+        v1 = new double[interpolatedState.length];
+        v2 = new double[interpolatedState.length];
+        v3 = new double[interpolatedState.length];
+        v4 = new double[interpolatedState.length];
+      }
+
+      // no step finalization is needed for this interpolator
+
+      // we need to compute the interpolation vectors for this time step
+      for (int i = 0; i < interpolatedState.length; ++i) {
+          final double yDot0 = yDotK[0][i];
+          final double yDot2 = yDotK[2][i];
+          final double yDot3 = yDotK[3][i];
+          final double yDot4 = yDotK[4][i];
+          final double yDot5 = yDotK[5][i];
+          final double yDot6 = yDotK[6][i];
+          v1[i] = A70 * yDot0 + A72 * yDot2 + A73 * yDot3 + A74 * yDot4 + A75 * yDot5;
+          v2[i] = yDot0 - v1[i];
+          v3[i] = v1[i] - v2[i] - yDot6;
+          v4[i] = D0 * yDot0 + D2 * yDot2 + D3 * yDot3 + D4 * yDot4 + D5 * yDot5 + D6 * yDot6;
+      }
+
+      vectorsInitialized = true;
+
+    }
+
+    // interpolate
+    final double eta = 1 - theta;
+    final double twoTheta = 2 * theta;
+    final double dot2 = 1 - twoTheta;
+    final double dot3 = theta * (2 - 3 * theta);
+    final double dot4 = twoTheta * (1 + theta * (twoTheta - 3));
+    for (int i = 0; i < interpolatedState.length; ++i) {
+      interpolatedState[i] =
+          currentState[i] - oneMinusThetaH * (v1[i] - theta * (v2[i] + theta * (v3[i] + eta * v4[i])));
+      interpolatedDerivatives[i] = v1[i] + dot2 * v2[i] + dot3 * v3[i] + dot4 * v4[i];
+    }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.java
new file mode 100644
index 0000000..68c1141
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.java
@@ -0,0 +1,283 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class implements the 8(5,3) Dormand-Prince integrator for Ordinary
+ * Differential Equations.
+ *
+ * <p>This integrator is an embedded Runge-Kutta integrator
+ * of order 8(5,3) used in local extrapolation mode (i.e. the solution
+ * is computed using the high order formula) with stepsize control
+ * (and automatic step initialization) and continuous output. This
+ * method uses 12 functions evaluations per step for integration and 4
+ * evaluations for interpolation. However, since the first
+ * interpolation evaluation is the same as the first integration
+ * evaluation of the next step, we have included it in the integrator
+ * rather than in the interpolator and specified the method was an
+ * <i>fsal</i>. Hence, despite we have 13 stages here, the cost is
+ * really 12 evaluations per step even if no interpolation is done,
+ * and the overcost of interpolation is only 3 evaluations.</p>
+ *
+ * <p>This method is based on an 8(6) method by Dormand and Prince
+ * (i.e. order 8 for the integration and order 6 for error estimation)
+ * modified by Hairer and Wanner to use a 5th order error estimator
+ * with 3rd order correction. This modification was introduced because
+ * the original method failed in some cases (wrong steps can be
+ * accepted when step size is too large, for example in the
+ * Brusselator problem) and also had <i>severe difficulties when
+ * applied to problems with discontinuities</i>. This modification is
+ * explained in the second edition of the first volume (Nonstiff
+ * Problems) of the reference book by Hairer, Norsett and Wanner:
+ * <i>Solving Ordinary Differential Equations</i> (Springer-Verlag,
+ * ISBN 3-540-56670-8).</p>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ */
+
+public class DormandPrince853Integrator extends EmbeddedRungeKuttaIntegrator {
+
+  /** Integrator method name. */
+  private static final String METHOD_NAME = "Dormand-Prince 8 (5, 3)";
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    (12.0 - 2.0 * FastMath.sqrt(6.0)) / 135.0, (6.0 - FastMath.sqrt(6.0)) / 45.0, (6.0 - FastMath.sqrt(6.0)) / 30.0,
+    (6.0 + FastMath.sqrt(6.0)) / 30.0, 1.0/3.0, 1.0/4.0, 4.0/13.0, 127.0/195.0, 3.0/5.0,
+    6.0/7.0, 1.0, 1.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+
+    // k2
+    {(12.0 - 2.0 * FastMath.sqrt(6.0)) / 135.0},
+
+    // k3
+    {(6.0 - FastMath.sqrt(6.0)) / 180.0, (6.0 - FastMath.sqrt(6.0)) / 60.0},
+
+    // k4
+    {(6.0 - FastMath.sqrt(6.0)) / 120.0, 0.0, (6.0 - FastMath.sqrt(6.0)) / 40.0},
+
+    // k5
+    {(462.0 + 107.0 * FastMath.sqrt(6.0)) / 3000.0, 0.0,
+     (-402.0 - 197.0 * FastMath.sqrt(6.0)) / 1000.0, (168.0 + 73.0 * FastMath.sqrt(6.0)) / 375.0},
+
+    // k6
+    {1.0 / 27.0, 0.0, 0.0, (16.0 + FastMath.sqrt(6.0)) / 108.0, (16.0 - FastMath.sqrt(6.0)) / 108.0},
+
+    // k7
+    {19.0 / 512.0, 0.0, 0.0, (118.0 + 23.0 * FastMath.sqrt(6.0)) / 1024.0,
+     (118.0 - 23.0 * FastMath.sqrt(6.0)) / 1024.0, -9.0 / 512.0},
+
+    // k8
+    {13772.0 / 371293.0, 0.0, 0.0, (51544.0 + 4784.0 * FastMath.sqrt(6.0)) / 371293.0,
+     (51544.0 - 4784.0 * FastMath.sqrt(6.0)) / 371293.0, -5688.0 / 371293.0, 3072.0 / 371293.0},
+
+    // k9
+    {58656157643.0 / 93983540625.0, 0.0, 0.0,
+     (-1324889724104.0 - 318801444819.0 * FastMath.sqrt(6.0)) / 626556937500.0,
+     (-1324889724104.0 + 318801444819.0 * FastMath.sqrt(6.0)) / 626556937500.0,
+     96044563816.0 / 3480871875.0, 5682451879168.0 / 281950621875.0,
+     -165125654.0 / 3796875.0},
+
+    // k10
+    {8909899.0 / 18653125.0, 0.0, 0.0,
+     (-4521408.0 - 1137963.0 * FastMath.sqrt(6.0)) / 2937500.0,
+     (-4521408.0 + 1137963.0 * FastMath.sqrt(6.0)) / 2937500.0,
+     96663078.0 / 4553125.0, 2107245056.0 / 137915625.0,
+     -4913652016.0 / 147609375.0, -78894270.0 / 3880452869.0},
+
+    // k11
+    {-20401265806.0 / 21769653311.0, 0.0, 0.0,
+     (354216.0 + 94326.0 * FastMath.sqrt(6.0)) / 112847.0,
+     (354216.0 - 94326.0 * FastMath.sqrt(6.0)) / 112847.0,
+     -43306765128.0 / 5313852383.0, -20866708358144.0 / 1126708119789.0,
+     14886003438020.0 / 654632330667.0, 35290686222309375.0 / 14152473387134411.0,
+     -1477884375.0 / 485066827.0},
+
+    // k12
+    {39815761.0 / 17514443.0, 0.0, 0.0,
+     (-3457480.0 - 960905.0 * FastMath.sqrt(6.0)) / 551636.0,
+     (-3457480.0 + 960905.0 * FastMath.sqrt(6.0)) / 551636.0,
+     -844554132.0 / 47026969.0, 8444996352.0 / 302158619.0,
+     -2509602342.0 / 877790785.0, -28388795297996250.0 / 3199510091356783.0,
+     226716250.0 / 18341897.0, 1371316744.0 / 2131383595.0},
+
+    // k13 should be for interpolation only, but since it is the same
+    // stage as the first evaluation of the next step, we perform it
+    // here at no cost by specifying this is an fsal method
+    {104257.0/1920240.0, 0.0, 0.0, 0.0, 0.0, 3399327.0/763840.0,
+     66578432.0/35198415.0, -1674902723.0/288716400.0,
+     54980371265625.0/176692375811392.0, -734375.0/4826304.0,
+     171414593.0/851261400.0, 137909.0/3084480.0}
+
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+      104257.0/1920240.0,
+      0.0,
+      0.0,
+      0.0,
+      0.0,
+      3399327.0/763840.0,
+      66578432.0/35198415.0,
+      -1674902723.0/288716400.0,
+      54980371265625.0/176692375811392.0,
+      -734375.0/4826304.0,
+      171414593.0/851261400.0,
+      137909.0/3084480.0,
+      0.0
+  };
+
+  /** First error weights array, element 1. */
+  private static final double E1_01 =         116092271.0 / 8848465920.0;
+
+  // elements 2 to 5 are zero, so they are neither stored nor used
+
+  /** First error weights array, element 6. */
+  private static final double E1_06 =          -1871647.0 / 1527680.0;
+
+  /** First error weights array, element 7. */
+  private static final double E1_07 =         -69799717.0 / 140793660.0;
+
+  /** First error weights array, element 8. */
+  private static final double E1_08 =     1230164450203.0 / 739113984000.0;
+
+  /** First error weights array, element 9. */
+  private static final double E1_09 = -1980813971228885.0 / 5654156025964544.0;
+
+  /** First error weights array, element 10. */
+  private static final double E1_10 =         464500805.0 / 1389975552.0;
+
+  /** First error weights array, element 11. */
+  private static final double E1_11 =     1606764981773.0 / 19613062656000.0;
+
+  /** First error weights array, element 12. */
+  private static final double E1_12 =           -137909.0 / 6168960.0;
+
+
+  /** Second error weights array, element 1. */
+  private static final double E2_01 =           -364463.0 / 1920240.0;
+
+  // elements 2 to 5 are zero, so they are neither stored nor used
+
+  /** Second error weights array, element 6. */
+  private static final double E2_06 =           3399327.0 / 763840.0;
+
+  /** Second error weights array, element 7. */
+  private static final double E2_07 =          66578432.0 / 35198415.0;
+
+  /** Second error weights array, element 8. */
+  private static final double E2_08 =       -1674902723.0 / 288716400.0;
+
+  /** Second error weights array, element 9. */
+  private static final double E2_09 =   -74684743568175.0 / 176692375811392.0;
+
+  /** Second error weights array, element 10. */
+  private static final double E2_10 =           -734375.0 / 4826304.0;
+
+  /** Second error weights array, element 11. */
+  private static final double E2_11 =         171414593.0 / 851261400.0;
+
+  /** Second error weights array, element 12. */
+  private static final double E2_12 =             69869.0 / 3084480.0;
+
+  /** Simple constructor.
+   * Build an eighth order Dormand-Prince integrator with the given step bounds
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param scalAbsoluteTolerance allowed absolute error
+   * @param scalRelativeTolerance allowed relative error
+   */
+  public DormandPrince853Integrator(final double minStep, final double maxStep,
+                                    final double scalAbsoluteTolerance,
+                                    final double scalRelativeTolerance) {
+    super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B,
+          new DormandPrince853StepInterpolator(),
+          minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+  }
+
+  /** Simple constructor.
+   * Build an eighth order Dormand-Prince integrator with the given step bounds
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param vecAbsoluteTolerance allowed absolute error
+   * @param vecRelativeTolerance allowed relative error
+   */
+  public DormandPrince853Integrator(final double minStep, final double maxStep,
+                                    final double[] vecAbsoluteTolerance,
+                                    final double[] vecRelativeTolerance) {
+    super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B,
+          new DormandPrince853StepInterpolator(),
+          minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public int getOrder() {
+    return 8;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected double estimateError(final double[][] yDotK,
+                                 final double[] y0, final double[] y1,
+                                 final double h) {
+    double error1 = 0;
+    double error2 = 0;
+
+    for (int j = 0; j < mainSetDimension; ++j) {
+      final double errSum1 = E1_01 * yDotK[0][j]  + E1_06 * yDotK[5][j] +
+                             E1_07 * yDotK[6][j]  + E1_08 * yDotK[7][j] +
+                             E1_09 * yDotK[8][j]  + E1_10 * yDotK[9][j] +
+                             E1_11 * yDotK[10][j] + E1_12 * yDotK[11][j];
+      final double errSum2 = E2_01 * yDotK[0][j]  + E2_06 * yDotK[5][j] +
+                             E2_07 * yDotK[6][j]  + E2_08 * yDotK[7][j] +
+                             E2_09 * yDotK[8][j]  + E2_10 * yDotK[9][j] +
+                             E2_11 * yDotK[10][j] + E2_12 * yDotK[11][j];
+
+      final double yScale = FastMath.max(FastMath.abs(y0[j]), FastMath.abs(y1[j]));
+      final double tol = (vecAbsoluteTolerance == null) ?
+                         (scalAbsoluteTolerance + scalRelativeTolerance * yScale) :
+                         (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale);
+      final double ratio1  = errSum1 / tol;
+      error1        += ratio1 * ratio1;
+      final double ratio2  = errSum2 / tol;
+      error2        += ratio2 * ratio2;
+    }
+
+    double den = error1 + 0.01 * error2;
+    if (den <= 0.0) {
+      den = 1.0;
+    }
+
+    return FastMath.abs(h) * error1 / FastMath.sqrt(mainSetDimension * den);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpolator.java
new file mode 100644
index 0000000..946f8a2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/DormandPrince853StepInterpolator.java
@@ -0,0 +1,480 @@
+/*
+ * 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.ode.nonstiff;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.apache.commons.math.ode.AbstractIntegrator;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class represents an interpolator over the last step during an
+ * ODE integration for the 8(5,3) Dormand-Prince integrator.
+ *
+ * @see DormandPrince853Integrator
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class DormandPrince853StepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 7152276390558450974L;
+
+    /** Propagation weights, element 1. */
+    private static final double B_01 =         104257.0 / 1920240.0;
+
+    // elements 2 to 5 are zero, so they are neither stored nor used
+
+    /** Propagation weights, element 6. */
+    private static final double B_06 =        3399327.0 / 763840.0;
+
+    /** Propagation weights, element 7. */
+    private static final double B_07 =       66578432.0 / 35198415.0;
+
+    /** Propagation weights, element 8. */
+    private static final double B_08 =    -1674902723.0 / 288716400.0;
+
+    /** Propagation weights, element 9. */
+    private static final double B_09 = 54980371265625.0 / 176692375811392.0;
+
+    /** Propagation weights, element 10. */
+    private static final double B_10 =        -734375.0 / 4826304.0;
+
+    /** Propagation weights, element 11. */
+    private static final double B_11 =      171414593.0 / 851261400.0;
+
+    /** Propagation weights, element 12. */
+    private static final double B_12 =         137909.0 / 3084480.0;
+
+    /** Time step for stage 14 (interpolation only). */
+    private static final double C14    = 1.0 / 10.0;
+
+    /** Internal weights for stage 14, element 1. */
+    private static final double K14_01 =       13481885573.0 / 240030000000.0      - B_01;
+
+    // elements 2 to 5 are zero, so they are neither stored nor used
+
+    /** Internal weights for stage 14, element 6. */
+    private static final double K14_06 =                 0.0                       - B_06;
+
+    /** Internal weights for stage 14, element 7. */
+    private static final double K14_07 =      139418837528.0 / 549975234375.0      - B_07;
+
+    /** Internal weights for stage 14, element 8. */
+    private static final double K14_08 =   -11108320068443.0 / 45111937500000.0    - B_08;
+
+    /** Internal weights for stage 14, element 9. */
+    private static final double K14_09 = -1769651421925959.0 / 14249385146080000.0 - B_09;
+
+    /** Internal weights for stage 14, element 10. */
+    private static final double K14_10 =          57799439.0 / 377055000.0         - B_10;
+
+    /** Internal weights for stage 14, element 11. */
+    private static final double K14_11 =      793322643029.0 / 96734250000000.0    - B_11;
+
+    /** Internal weights for stage 14, element 12. */
+    private static final double K14_12 =        1458939311.0 / 192780000000.0      - B_12;
+
+    /** Internal weights for stage 14, element 13. */
+    private static final double K14_13 =             -4149.0 / 500000.0;
+
+    /** Time step for stage 15 (interpolation only). */
+    private static final double C15    = 1.0 / 5.0;
+
+
+    /** Internal weights for stage 15, element 1. */
+    private static final double K15_01 =     1595561272731.0 / 50120273500000.0    - B_01;
+
+    // elements 2 to 5 are zero, so they are neither stored nor used
+
+    /** Internal weights for stage 15, element 6. */
+    private static final double K15_06 =      975183916491.0 / 34457688031250.0    - B_06;
+
+    /** Internal weights for stage 15, element 7. */
+    private static final double K15_07 =    38492013932672.0 / 718912673015625.0   - B_07;
+
+    /** Internal weights for stage 15, element 8. */
+    private static final double K15_08 = -1114881286517557.0 / 20298710767500000.0 - B_08;
+
+    /** Internal weights for stage 15, element 9. */
+    private static final double K15_09 =                 0.0                       - B_09;
+
+    /** Internal weights for stage 15, element 10. */
+    private static final double K15_10 =                 0.0                       - B_10;
+
+    /** Internal weights for stage 15, element 11. */
+    private static final double K15_11 =    -2538710946863.0 / 23431227861250000.0 - B_11;
+
+    /** Internal weights for stage 15, element 12. */
+    private static final double K15_12 =        8824659001.0 / 23066716781250.0    - B_12;
+
+    /** Internal weights for stage 15, element 13. */
+    private static final double K15_13 =      -11518334563.0 / 33831184612500.0;
+
+    /** Internal weights for stage 15, element 14. */
+    private static final double K15_14 =        1912306948.0 / 13532473845.0;
+
+    /** Time step for stage 16 (interpolation only). */
+    private static final double C16    = 7.0 / 9.0;
+
+
+    /** Internal weights for stage 16, element 1. */
+    private static final double K16_01 =      -13613986967.0 / 31741908048.0       - B_01;
+
+    // elements 2 to 5 are zero, so they are neither stored nor used
+
+    /** Internal weights for stage 16, element 6. */
+    private static final double K16_06 =       -4755612631.0 / 1012344804.0        - B_06;
+
+    /** Internal weights for stage 16, element 7. */
+    private static final double K16_07 =    42939257944576.0 / 5588559685701.0     - B_07;
+
+    /** Internal weights for stage 16, element 8. */
+    private static final double K16_08 =    77881972900277.0 / 19140370552944.0    - B_08;
+
+    /** Internal weights for stage 16, element 9. */
+    private static final double K16_09 =    22719829234375.0 / 63689648654052.0    - B_09;
+
+    /** Internal weights for stage 16, element 10. */
+    private static final double K16_10 =                 0.0                       - B_10;
+
+    /** Internal weights for stage 16, element 11. */
+    private static final double K16_11 =                 0.0                       - B_11;
+
+    /** Internal weights for stage 16, element 12. */
+    private static final double K16_12 =                 0.0                       - B_12;
+
+    /** Internal weights for stage 16, element 13. */
+    private static final double K16_13 =       -1199007803.0 / 857031517296.0;
+
+    /** Internal weights for stage 16, element 14. */
+    private static final double K16_14 =      157882067000.0 / 53564469831.0;
+
+    /** Internal weights for stage 16, element 15. */
+    private static final double K16_15 =     -290468882375.0 / 31741908048.0;
+
+    /** Interpolation weights.
+     * (beware that only the non-null values are in the table)
+     */
+    private static final double[][] D = {
+
+      {        -17751989329.0 / 2106076560.0,               4272954039.0 / 7539864640.0,
+              -118476319744.0 / 38604839385.0,            755123450731.0 / 316657731600.0,
+        3692384461234828125.0 / 1744130441634250432.0,     -4612609375.0 / 5293382976.0,
+              2091772278379.0 / 933644586600.0,             2136624137.0 / 3382989120.0,
+                    -126493.0 / 1421424.0,                    98350000.0 / 5419179.0,
+                  -18878125.0 / 2053168.0,                 -1944542619.0 / 438351368.0},
+
+      {         32941697297.0 / 3159114840.0,             456696183123.0 / 1884966160.0,
+             19132610714624.0 / 115814518155.0,       -177904688592943.0 / 474986597400.0,
+       -4821139941836765625.0 / 218016305204281304.0,      30702015625.0 / 3970037232.0,
+            -85916079474274.0 / 2800933759800.0,           -5919468007.0 / 634310460.0,
+                    2479159.0 / 157936.0,                    -18750000.0 / 602131.0,
+                  -19203125.0 / 2053168.0,                 15700361463.0 / 438351368.0},
+
+      {         12627015655.0 / 631822968.0,              -72955222965.0 / 188496616.0,
+            -13145744952320.0 / 69488710893.0,          30084216194513.0 / 56998391688.0,
+        -296858761006640625.0 / 25648977082856624.0,         569140625.0 / 82709109.0,
+               -18684190637.0 / 18672891732.0,                69644045.0 / 89549712.0,
+                  -11847025.0 / 4264272.0,                  -978650000.0 / 16257537.0,
+                  519371875.0 / 6159504.0,                  5256837225.0 / 438351368.0},
+
+      {          -450944925.0 / 17550638.0,               -14532122925.0 / 94248308.0,
+              -595876966400.0 / 2573655959.0,             188748653015.0 / 527762886.0,
+        2545485458115234375.0 / 27252038150535163.0,       -1376953125.0 / 36759604.0,
+                53995596795.0 / 518691437.0,                 210311225.0 / 7047894.0,
+                   -1718875.0 / 39484.0,                      58000000.0 / 602131.0,
+                   -1546875.0 / 39484.0,                   -1262172375.0 / 8429834.0}
+
+    };
+
+    /** Last evaluations. */
+    private double[][] yDotKLast;
+
+    /** Vectors for interpolation. */
+    private double[][] v;
+
+    /** Initialization indicator for the interpolation vectors. */
+    private boolean vectorsInitialized;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link #reinitialize} method should be called before using the
+   * instance in order to initialize the internal arrays. This
+   * constructor is used only in order to delay the initialization in
+   * some cases. The {@link EmbeddedRungeKuttaIntegrator} uses the
+   * prototyping design pattern to create the step interpolators by
+   * cloning an uninitialized model and latter initializing the copy.
+   */
+  public DormandPrince853StepInterpolator() {
+    super();
+    yDotKLast = null;
+    v         = null;
+    vectorsInitialized = false;
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public DormandPrince853StepInterpolator(final DormandPrince853StepInterpolator interpolator) {
+
+    super(interpolator);
+
+    if (interpolator.currentState == null) {
+
+      yDotKLast = null;
+      v         = null;
+      vectorsInitialized = false;
+
+    } else {
+
+      final int dimension = interpolator.currentState.length;
+
+      yDotKLast    = new double[3][];
+      for (int k = 0; k < yDotKLast.length; ++k) {
+        yDotKLast[k] = new double[dimension];
+        System.arraycopy(interpolator.yDotKLast[k], 0, yDotKLast[k], 0,
+                         dimension);
+      }
+
+      v = new double[7][];
+      for (int k = 0; k < v.length; ++k) {
+        v[k] = new double[dimension];
+        System.arraycopy(interpolator.v[k], 0, v[k], 0, dimension);
+      }
+
+      vectorsInitialized = interpolator.vectorsInitialized;
+
+    }
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new DormandPrince853StepInterpolator(this);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void reinitialize(final AbstractIntegrator integrator,
+                           final double[] y, final double[][] yDotK, final boolean forward) {
+
+    super.reinitialize(integrator, y, yDotK, forward);
+
+    final int dimension = currentState.length;
+
+    yDotKLast = new double[3][];
+    for (int k = 0; k < yDotKLast.length; ++k) {
+      yDotKLast[k] = new double[dimension];
+    }
+
+    v = new double[7][];
+    for (int k = 0; k < v.length; ++k) {
+      v[k]  = new double[dimension];
+    }
+
+    vectorsInitialized = false;
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void storeTime(final double t) {
+    super.storeTime(t);
+    vectorsInitialized = false;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+    throws DerivativeException {
+
+    if (! vectorsInitialized) {
+
+      if (v == null) {
+        v = new double[7][];
+        for (int k = 0; k < 7; ++k) {
+          v[k] = new double[interpolatedState.length];
+        }
+      }
+
+      // perform the last evaluations if they have not been done yet
+      finalizeStep();
+
+      // compute the interpolation vectors for this time step
+      for (int i = 0; i < interpolatedState.length; ++i) {
+          final double yDot1  = yDotK[0][i];
+          final double yDot6  = yDotK[5][i];
+          final double yDot7  = yDotK[6][i];
+          final double yDot8  = yDotK[7][i];
+          final double yDot9  = yDotK[8][i];
+          final double yDot10 = yDotK[9][i];
+          final double yDot11 = yDotK[10][i];
+          final double yDot12 = yDotK[11][i];
+          final double yDot13 = yDotK[12][i];
+          final double yDot14 = yDotKLast[0][i];
+          final double yDot15 = yDotKLast[1][i];
+          final double yDot16 = yDotKLast[2][i];
+          v[0][i] = B_01 * yDot1  + B_06 * yDot6 + B_07 * yDot7 +
+                    B_08 * yDot8  + B_09 * yDot9 + B_10 * yDot10 +
+                    B_11 * yDot11 + B_12 * yDot12;
+          v[1][i] = yDot1 - v[0][i];
+          v[2][i] = v[0][i] - v[1][i] - yDotK[12][i];
+          for (int k = 0; k < D.length; ++k) {
+              v[k+3][i] = D[k][0] * yDot1  + D[k][1]  * yDot6  + D[k][2]  * yDot7  +
+                          D[k][3] * yDot8  + D[k][4]  * yDot9  + D[k][5]  * yDot10 +
+                          D[k][6] * yDot11 + D[k][7]  * yDot12 + D[k][8]  * yDot13 +
+                          D[k][9] * yDot14 + D[k][10] * yDot15 + D[k][11] * yDot16;
+          }
+      }
+
+      vectorsInitialized = true;
+
+    }
+
+    final double eta      = 1 - theta;
+    final double twoTheta = 2 * theta;
+    final double theta2   = theta * theta;
+    final double dot1 = 1 - twoTheta;
+    final double dot2 = theta * (2 - 3 * theta);
+    final double dot3 = twoTheta * (1 + theta * (twoTheta -3));
+    final double dot4 = theta2 * (3 + theta * (5 * theta - 8));
+    final double dot5 = theta2 * (3 + theta * (-12 + theta * (15 - 6 * theta)));
+    final double dot6 = theta2 * theta * (4 + theta * (-15 + theta * (18 - 7 * theta)));
+
+    for (int i = 0; i < interpolatedState.length; ++i) {
+      interpolatedState[i] = currentState[i] -
+                             oneMinusThetaH * (v[0][i] -
+                                               theta * (v[1][i] +
+                                                        theta * (v[2][i] +
+                                                                 eta * (v[3][i] +
+                                                                        theta * (v[4][i] +
+                                                                                 eta * (v[5][i] +
+                                                                                        theta * (v[6][i])))))));
+      interpolatedDerivatives[i] =  v[0][i] + dot1 * v[1][i] + dot2 * v[2][i] +
+                                    dot3 * v[3][i] + dot4 * v[4][i] +
+                                    dot5 * v[5][i] + dot6 * v[6][i];
+    }
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected void doFinalize()
+    throws DerivativeException {
+
+    if (currentState == null) {
+      // we are finalizing an uninitialized instance
+      return;
+    }
+
+    double s;
+    final double[] yTmp = new double[currentState.length];
+    final double pT = getGlobalPreviousTime();
+
+    // k14
+    for (int j = 0; j < currentState.length; ++j) {
+      s = K14_01 * yDotK[0][j]  + K14_06 * yDotK[5][j]  + K14_07 * yDotK[6][j] +
+          K14_08 * yDotK[7][j]  + K14_09 * yDotK[8][j]  + K14_10 * yDotK[9][j] +
+          K14_11 * yDotK[10][j] + K14_12 * yDotK[11][j] + K14_13 * yDotK[12][j];
+      yTmp[j] = currentState[j] + h * s;
+    }
+    integrator.computeDerivatives(pT + C14 * h, yTmp, yDotKLast[0]);
+
+    // k15
+    for (int j = 0; j < currentState.length; ++j) {
+     s = K15_01 * yDotK[0][j]  + K15_06 * yDotK[5][j]  + K15_07 * yDotK[6][j] +
+         K15_08 * yDotK[7][j]  + K15_09 * yDotK[8][j]  + K15_10 * yDotK[9][j] +
+         K15_11 * yDotK[10][j] + K15_12 * yDotK[11][j] + K15_13 * yDotK[12][j] +
+         K15_14 * yDotKLast[0][j];
+     yTmp[j] = currentState[j] + h * s;
+    }
+    integrator.computeDerivatives(pT + C15 * h, yTmp, yDotKLast[1]);
+
+    // k16
+    for (int j = 0; j < currentState.length; ++j) {
+      s = K16_01 * yDotK[0][j]  + K16_06 * yDotK[5][j]  + K16_07 * yDotK[6][j] +
+          K16_08 * yDotK[7][j]  + K16_09 * yDotK[8][j]  + K16_10 * yDotK[9][j] +
+          K16_11 * yDotK[10][j] + K16_12 * yDotK[11][j] + K16_13 * yDotK[12][j] +
+          K16_14 * yDotKLast[0][j] +  K16_15 * yDotKLast[1][j];
+      yTmp[j] = currentState[j] + h * s;
+    }
+    integrator.computeDerivatives(pT + C16 * h, yTmp, yDotKLast[2]);
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void writeExternal(final ObjectOutput out)
+    throws IOException {
+
+    try {
+      // save the local attributes
+      finalizeStep();
+    } catch (DerivativeException e) {
+        IOException ioe = new IOException(e.getLocalizedMessage());
+        ioe.initCause(e);
+        throw ioe;
+    }
+    final int dimension = (currentState == null) ? -1 : currentState.length;
+    out.writeInt(dimension);
+    for (int i = 0; i < dimension; ++i) {
+      out.writeDouble(yDotKLast[0][i]);
+      out.writeDouble(yDotKLast[1][i]);
+      out.writeDouble(yDotKLast[2][i]);
+    }
+
+    // save the state of the base class
+    super.writeExternal(out);
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void readExternal(final ObjectInput in)
+    throws IOException {
+
+    // read the local attributes
+    yDotKLast = new double[3][];
+    final int dimension = in.readInt();
+    yDotKLast[0] = (dimension < 0) ? null : new double[dimension];
+    yDotKLast[1] = (dimension < 0) ? null : new double[dimension];
+    yDotKLast[2] = (dimension < 0) ? null : new double[dimension];
+
+    for (int i = 0; i < dimension; ++i) {
+      yDotKLast[0][i] = in.readDouble();
+      yDotKLast[1][i] = in.readDouble();
+      yDotKLast[2][i] = in.readDouble();
+    }
+
+    // read the base state
+    super.readExternal(in);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java
new file mode 100644
index 0000000..97e772e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java
@@ -0,0 +1,379 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
+import org.apache.commons.math.ode.sampling.DummyStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements the common part of all embedded Runge-Kutta
+ * integrators for Ordinary Differential Equations.
+ *
+ * <p>These methods are embedded explicit Runge-Kutta methods with two
+ * sets of coefficients allowing to estimate the error, their Butcher
+ * arrays are as follows :
+ * <pre>
+ *    0  |
+ *   c2  | a21
+ *   c3  | a31  a32
+ *   ... |        ...
+ *   cs  | as1  as2  ...  ass-1
+ *       |--------------------------
+ *       |  b1   b2  ...   bs-1  bs
+ *       |  b'1  b'2 ...   b's-1 b's
+ * </pre>
+ * </p>
+ *
+ * <p>In fact, we rather use the array defined by ej = bj - b'j to
+ * compute directly the error rather than computing two estimates and
+ * then comparing them.</p>
+ *
+ * <p>Some methods are qualified as <i>fsal</i> (first same as last)
+ * methods. This means the last evaluation of the derivatives in one
+ * step is the same as the first in the next step. Then, this
+ * evaluation can be reused from one step to the next one and the cost
+ * of such a method is really s-1 evaluations despite the method still
+ * has s stages. This behaviour is true only for successful steps, if
+ * the step is rejected after the error estimation phase, no
+ * evaluation is saved. For an <i>fsal</i> method, we have cs = 1 and
+ * asi = bi for all i.</p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public abstract class EmbeddedRungeKuttaIntegrator
+  extends AdaptiveStepsizeIntegrator {
+
+    /** Indicator for <i>fsal</i> methods. */
+    private final boolean fsal;
+
+    /** Time steps from Butcher array (without the first zero). */
+    private final double[] c;
+
+    /** Internal weights from Butcher array (without the first empty row). */
+    private final double[][] a;
+
+    /** External weights for the high order method from Butcher array. */
+    private final double[] b;
+
+    /** Prototype of the step interpolator. */
+    private final RungeKuttaStepInterpolator prototype;
+
+    /** Stepsize control exponent. */
+    private final double exp;
+
+    /** Safety factor for stepsize control. */
+    private double safety;
+
+    /** Minimal reduction factor for stepsize control. */
+    private double minReduction;
+
+    /** Maximal growth factor for stepsize control. */
+    private double maxGrowth;
+
+  /** Build a Runge-Kutta integrator with the given Butcher array.
+   * @param name name of the method
+   * @param fsal indicate that the method is an <i>fsal</i>
+   * @param c time steps from Butcher array (without the first zero)
+   * @param a internal weights from Butcher array (without the first empty row)
+   * @param b propagation weights for the high order method from Butcher array
+   * @param prototype prototype of the step interpolator to use
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param scalAbsoluteTolerance allowed absolute error
+   * @param scalRelativeTolerance allowed relative error
+   */
+  protected EmbeddedRungeKuttaIntegrator(final String name, final boolean fsal,
+                                         final double[] c, final double[][] a, final double[] b,
+                                         final RungeKuttaStepInterpolator prototype,
+                                         final double minStep, final double maxStep,
+                                         final double scalAbsoluteTolerance,
+                                         final double scalRelativeTolerance) {
+
+    super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+
+    this.fsal      = fsal;
+    this.c         = c;
+    this.a         = a;
+    this.b         = b;
+    this.prototype = prototype;
+
+    exp = -1.0 / getOrder();
+
+    // set the default values of the algorithm control parameters
+    setSafety(0.9);
+    setMinReduction(0.2);
+    setMaxGrowth(10.0);
+
+  }
+
+  /** Build a Runge-Kutta integrator with the given Butcher array.
+   * @param name name of the method
+   * @param fsal indicate that the method is an <i>fsal</i>
+   * @param c time steps from Butcher array (without the first zero)
+   * @param a internal weights from Butcher array (without the first empty row)
+   * @param b propagation weights for the high order method from Butcher array
+   * @param prototype prototype of the step interpolator to use
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param vecAbsoluteTolerance allowed absolute error
+   * @param vecRelativeTolerance allowed relative error
+   */
+  protected EmbeddedRungeKuttaIntegrator(final String name, final boolean fsal,
+                                         final double[] c, final double[][] a, final double[] b,
+                                         final RungeKuttaStepInterpolator prototype,
+                                         final double   minStep, final double maxStep,
+                                         final double[] vecAbsoluteTolerance,
+                                         final double[] vecRelativeTolerance) {
+
+    super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+
+    this.fsal      = fsal;
+    this.c         = c;
+    this.a         = a;
+    this.b         = b;
+    this.prototype = prototype;
+
+    exp = -1.0 / getOrder();
+
+    // set the default values of the algorithm control parameters
+    setSafety(0.9);
+    setMinReduction(0.2);
+    setMaxGrowth(10.0);
+
+  }
+
+  /** Get the order of the method.
+   * @return order of the method
+   */
+  public abstract int getOrder();
+
+  /** Get the safety factor for stepsize control.
+   * @return safety factor
+   */
+  public double getSafety() {
+    return safety;
+  }
+
+  /** Set the safety factor for stepsize control.
+   * @param safety safety factor
+   */
+  public void setSafety(final double safety) {
+    this.safety = safety;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public double integrate(final FirstOrderDifferentialEquations equations,
+                          final double t0, final double[] y0,
+                          final double t, final double[] y)
+  throws DerivativeException, IntegratorException {
+
+    sanityChecks(equations, t0, y0, t, y);
+    setEquations(equations);
+    resetEvaluations();
+    final boolean forward = t > t0;
+
+    // create some internal working arrays
+    final int stages = c.length + 1;
+    if (y != y0) {
+      System.arraycopy(y0, 0, y, 0, y0.length);
+    }
+    final double[][] yDotK = new double[stages][y0.length];
+    final double[] yTmp    = new double[y0.length];
+    final double[] yDotTmp = new double[y0.length];
+
+    // set up an interpolator sharing the integrator arrays
+    AbstractStepInterpolator interpolator;
+    if (requiresDenseOutput()) {
+      final RungeKuttaStepInterpolator rki = (RungeKuttaStepInterpolator) prototype.copy();
+      rki.reinitialize(this, yTmp, yDotK, forward);
+      interpolator = rki;
+    } else {
+      interpolator = new DummyStepInterpolator(yTmp, yDotK[stages - 1], forward);
+    }
+    interpolator.storeTime(t0);
+
+    // set up integration control objects
+    stepStart         = t0;
+    double  hNew      = 0;
+    boolean firstTime = true;
+    for (StepHandler handler : stepHandlers) {
+        handler.reset();
+    }
+    setStateInitialized(false);
+
+    // main integration loop
+    isLastStep = false;
+    do {
+
+      interpolator.shift();
+
+      // iterate over step size, ensuring local normalized error is smaller than 1
+      double error = 10;
+      while (error >= 1.0) {
+
+        if (firstTime || !fsal) {
+          // first stage
+          computeDerivatives(stepStart, y, yDotK[0]);
+        }
+
+        if (firstTime) {
+          final double[] scale = new double[mainSetDimension];
+          if (vecAbsoluteTolerance == null) {
+              for (int i = 0; i < scale.length; ++i) {
+                scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * FastMath.abs(y[i]);
+              }
+          } else {
+              for (int i = 0; i < scale.length; ++i) {
+                scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * FastMath.abs(y[i]);
+              }
+          }
+          hNew = initializeStep(equations, forward, getOrder(), scale,
+                                stepStart, y, yDotK[0], yTmp, yDotK[1]);
+          firstTime = false;
+        }
+
+        stepSize = hNew;
+
+        // next stages
+        for (int k = 1; k < stages; ++k) {
+
+          for (int j = 0; j < y0.length; ++j) {
+            double sum = a[k-1][0] * yDotK[0][j];
+            for (int l = 1; l < k; ++l) {
+              sum += a[k-1][l] * yDotK[l][j];
+            }
+            yTmp[j] = y[j] + stepSize * sum;
+          }
+
+          computeDerivatives(stepStart + c[k-1] * stepSize, yTmp, yDotK[k]);
+
+        }
+
+        // estimate the state at the end of the step
+        for (int j = 0; j < y0.length; ++j) {
+          double sum    = b[0] * yDotK[0][j];
+          for (int l = 1; l < stages; ++l) {
+            sum    += b[l] * yDotK[l][j];
+          }
+          yTmp[j] = y[j] + stepSize * sum;
+        }
+
+        // estimate the error at the end of the step
+        error = estimateError(yDotK, y, yTmp, stepSize);
+        if (error >= 1.0) {
+          // reject the step and attempt to reduce error by stepsize control
+          final double factor =
+              FastMath.min(maxGrowth,
+                           FastMath.max(minReduction, safety * FastMath.pow(error, exp)));
+          hNew = filterStep(stepSize * factor, forward, false);
+        }
+
+      }
+
+      // local error is small enough: accept the step, trigger events and step handlers
+      interpolator.storeTime(stepStart + stepSize);
+      System.arraycopy(yTmp, 0, y, 0, y0.length);
+      System.arraycopy(yDotK[stages - 1], 0, yDotTmp, 0, y0.length);
+      stepStart = acceptStep(interpolator, y, yDotTmp, t);
+
+      if (!isLastStep) {
+
+          // prepare next step
+          interpolator.storeTime(stepStart);
+
+          if (fsal) {
+              // save the last evaluation for the next step
+              System.arraycopy(yDotTmp, 0, yDotK[0], 0, y0.length);
+          }
+
+          // stepsize control for next step
+          final double factor =
+              FastMath.min(maxGrowth, FastMath.max(minReduction, safety * FastMath.pow(error, exp)));
+          final double  scaledH    = stepSize * factor;
+          final double  nextT      = stepStart + scaledH;
+          final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t);
+          hNew = filterStep(scaledH, forward, nextIsLast);
+
+          final double  filteredNextT      = stepStart + hNew;
+          final boolean filteredNextIsLast = forward ? (filteredNextT >= t) : (filteredNextT <= t);
+          if (filteredNextIsLast) {
+              hNew = t - stepStart;
+          }
+
+      }
+
+    } while (!isLastStep);
+
+    final double stopTime = stepStart;
+    resetInternalState();
+    return stopTime;
+
+  }
+
+  /** Get the minimal reduction factor for stepsize control.
+   * @return minimal reduction factor
+   */
+  public double getMinReduction() {
+    return minReduction;
+  }
+
+  /** Set the minimal reduction factor for stepsize control.
+   * @param minReduction minimal reduction factor
+   */
+  public void setMinReduction(final double minReduction) {
+    this.minReduction = minReduction;
+  }
+
+  /** Get the maximal growth factor for stepsize control.
+   * @return maximal growth factor
+   */
+  public double getMaxGrowth() {
+    return maxGrowth;
+  }
+
+  /** Set the maximal growth factor for stepsize control.
+   * @param maxGrowth maximal growth factor
+   */
+  public void setMaxGrowth(final double maxGrowth) {
+    this.maxGrowth = maxGrowth;
+  }
+
+  /** Compute the error ratio.
+   * @param yDotK derivatives computed during the first stages
+   * @param y0 estimate of the step at the start of the step
+   * @param y1 estimate of the step at the end of the step
+   * @param h  current step
+   * @return error ratio, greater than 1 if step should be rejected
+   */
+  protected abstract double estimateError(double[][] yDotK,
+                                          double[] y0, double[] y1,
+                                          double h);
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/EulerIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/EulerIntegrator.java
new file mode 100644
index 0000000..21b0f74
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/EulerIntegrator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ode.nonstiff;
+
+
+/**
+ * This class implements a simple Euler integrator for Ordinary
+ * Differential Equations.
+ *
+ * <p>The Euler algorithm is the simplest one that can be used to
+ * integrate ordinary differential equations. It is a simple inversion
+ * of the forward difference expression :
+ * <code>f'=(f(t+h)-f(t))/h</code> which leads to
+ * <code>f(t+h)=f(t)+hf'</code>. The interpolation scheme used for
+ * dense output is the linear scheme already used for integration.</p>
+ *
+ * <p>This algorithm looks cheap because it needs only one function
+ * evaluation per step. However, as it uses linear estimates, it needs
+ * very small steps to achieve high accuracy, and small steps lead to
+ * numerical errors and instabilities.</p>
+ *
+ * <p>This algorithm is almost never used and has been included in
+ * this package only as a comparison reference for more useful
+ * integrators.</p>
+ *
+ * @see MidpointIntegrator
+ * @see ClassicalRungeKuttaIntegrator
+ * @see GillIntegrator
+ * @see ThreeEighthesIntegrator
+ * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $
+ * @since 1.2
+ */
+
+public class EulerIntegrator extends RungeKuttaIntegrator {
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    1.0
+  };
+
+  /** Simple constructor.
+   * Build an Euler integrator with the given step.
+   * @param step integration step
+   */
+  public EulerIntegrator(final double step) {
+    super("Euler", STATIC_C, STATIC_A, STATIC_B, new EulerStepInterpolator(), step);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/EulerStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/EulerStepInterpolator.java
new file mode 100644
index 0000000..96f0c13
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/EulerStepInterpolator.java
@@ -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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class implements a linear interpolator for step.
+ *
+ * <p>This interpolator computes dense output inside the last
+ * step computed. The interpolation equation is consistent with the
+ * integration scheme :
+ *
+ * <pre>
+ *   y(t_n + theta h) = y (t_n + h) - (1-theta) h y'
+ * </pre>
+ *
+ * where theta belongs to [0 ; 1] and where y' is the evaluation of
+ * the derivatives already computed during the step.</p>
+ *
+ * @see EulerIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class EulerStepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+  /** Serializable version identifier */
+  private static final long serialVersionUID = -7179861704951334960L;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link
+   * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize}
+   * method should be called before using the instance in order to
+   * initialize the internal arrays. This constructor is used only
+   * in order to delay the initialization in some cases. The {@link
+   * RungeKuttaIntegrator} class uses the prototyping design pattern
+   * to create the step interpolators by cloning an uninitialized model
+   * and later initializing the copy.
+   */
+  public EulerStepInterpolator() {
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public EulerStepInterpolator(final EulerStepInterpolator interpolator) {
+    super(interpolator);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new EulerStepInterpolator(this);
+  }
+
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+    throws DerivativeException {
+
+    for (int i = 0; i < interpolatedState.length; ++i) {
+      interpolatedState[i] = currentState[i] - oneMinusThetaH * yDotK[0][i];
+    }
+    System.arraycopy(yDotK[0], 0, interpolatedDerivatives, 0, interpolatedDerivatives.length);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/GillIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/GillIntegrator.java
new file mode 100644
index 0000000..3b31f9f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/GillIntegrator.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class implements the Gill fourth order Runge-Kutta
+ * integrator for Ordinary Differential Equations .
+
+ * <p>This method is an explicit Runge-Kutta method, its Butcher-array
+ * is the following one :
+ * <pre>
+ *    0  |    0        0       0      0
+ *   1/2 |   1/2       0       0      0
+ *   1/2 | (q-1)/2  (2-q)/2    0      0
+ *    1  |    0       -q/2  (2+q)/2   0
+ *       |-------------------------------
+ *       |   1/6    (2-q)/6 (2+q)/6  1/6
+ * </pre>
+ * where q = sqrt(2)</p>
+ *
+ * @see EulerIntegrator
+ * @see ClassicalRungeKuttaIntegrator
+ * @see MidpointIntegrator
+ * @see ThreeEighthesIntegrator
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ */
+
+public class GillIntegrator extends RungeKuttaIntegrator {
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    1.0 / 2.0, 1.0 / 2.0, 1.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+    { 1.0 / 2.0 },
+    { (FastMath.sqrt(2.0) - 1.0) / 2.0, (2.0 - FastMath.sqrt(2.0)) / 2.0 },
+    { 0.0, -FastMath.sqrt(2.0) / 2.0, (2.0 + FastMath.sqrt(2.0)) / 2.0 }
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    1.0 / 6.0, (2.0 - FastMath.sqrt(2.0)) / 6.0, (2.0 + FastMath.sqrt(2.0)) / 6.0, 1.0 / 6.0
+  };
+
+  /** Simple constructor.
+   * Build a fourth-order Gill integrator with the given step.
+   * @param step integration step
+   */
+  public GillIntegrator(final double step) {
+    super("Gill", STATIC_C, STATIC_A, STATIC_B, new GillStepInterpolator(), step);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/GillStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/GillStepInterpolator.java
new file mode 100644
index 0000000..3d17d27
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/GillStepInterpolator.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements a step interpolator for the Gill fourth
+ * order Runge-Kutta integrator.
+ *
+ * <p>This interpolator allows to compute dense output inside the last
+ * step computed. The interpolation equation is consistent with the
+ * integration scheme :
+ *
+ * <pre>
+ *   y(t_n + theta h) = y (t_n + h)
+ *                    - (1 - theta) (h/6) [ (1 - theta) (1 - 4 theta) y'_1
+ *                                        + (1 - theta) (1 + 2 theta) ((2-q) y'_2 + (2+q) y'_3)
+ *                                        + (1 + theta + 4 theta^2) y'_4
+ *                                        ]
+ * </pre>
+ * where theta belongs to [0 ; 1], q = sqrt(2) and where y'_1 to y'_4
+ * are the four evaluations of the derivatives already computed during
+ * the step.</p>
+ *
+ * @see GillIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class GillStepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+    /** First Gill coefficient. */
+    private static final double TWO_MINUS_SQRT_2 = 2 - FastMath.sqrt(2.0);
+
+    /** Second Gill coefficient. */
+    private static final double TWO_PLUS_SQRT_2 = 2 + FastMath.sqrt(2.0);
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -107804074496313322L;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link
+   * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize}
+   * method should be called before using the instance in order to
+   * initialize the internal arrays. This constructor is used only
+   * in order to delay the initialization in some cases. The {@link
+   * RungeKuttaIntegrator} class uses the prototyping design pattern
+   * to create the step interpolators by cloning an uninitialized model
+   * and later initializing the copy.
+   */
+  public GillStepInterpolator() {
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public GillStepInterpolator(final GillStepInterpolator interpolator) {
+    super(interpolator);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new GillStepInterpolator(this);
+  }
+
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+    throws DerivativeException {
+
+    final double twoTheta  = 2 * theta;
+    final double fourTheta = 4 * theta;
+    final double s         = oneMinusThetaH / 6.0;
+    final double oMt       = 1 - theta;
+    final double soMt      = s * oMt;
+    final double c23       = soMt * (1 + twoTheta);
+    final double coeff1    = soMt * (1 - fourTheta);
+    final double coeff2    = c23  * TWO_MINUS_SQRT_2;
+    final double coeff3    = c23  * TWO_PLUS_SQRT_2;
+    final double coeff4    = s * (1 + theta * (1 + fourTheta));
+    final double coeffDot1 = theta * (twoTheta - 3) + 1;
+    final double cDot23    = theta * oMt;
+    final double coeffDot2 = cDot23  * TWO_MINUS_SQRT_2;
+    final double coeffDot3 = cDot23  * TWO_PLUS_SQRT_2;
+    final double coeffDot4 = theta * (twoTheta - 1);
+
+    for (int i = 0; i < interpolatedState.length; ++i) {
+        final double yDot1 = yDotK[0][i];
+        final double yDot2 = yDotK[1][i];
+        final double yDot3 = yDotK[2][i];
+        final double yDot4 = yDotK[3][i];
+        interpolatedState[i] =
+            currentState[i] - coeff1 * yDot1 - coeff2 * yDot2 - coeff3 * yDot3 - coeff4 * yDot4;
+        interpolatedDerivatives[i] =
+            coeffDot1 * yDot1 + coeffDot2 * yDot2 + coeffDot3 * yDot3 + coeffDot4 * yDot4;
+     }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java
new file mode 100644
index 0000000..09267d0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java
@@ -0,0 +1,963 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.events.EventHandler;
+import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
+import org.apache.commons.math.ode.sampling.DummyStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements a Gragg-Bulirsch-Stoer integrator for
+ * Ordinary Differential Equations.
+ *
+ * <p>The Gragg-Bulirsch-Stoer algorithm is one of the most efficient
+ * ones currently available for smooth problems. It uses Richardson
+ * extrapolation to estimate what would be the solution if the step
+ * size could be decreased down to zero.</p>
+ *
+ * <p>
+ * This method changes both the step size and the order during
+ * integration, in order to minimize computation cost. It is
+ * particularly well suited when a very high precision is needed. The
+ * limit where this method becomes more efficient than high-order
+ * embedded Runge-Kutta methods like {@link DormandPrince853Integrator
+ * Dormand-Prince 8(5,3)} depends on the problem. Results given in the
+ * Hairer, Norsett and Wanner book show for example that this limit
+ * occurs for accuracy around 1e-6 when integrating Saltzam-Lorenz
+ * equations (the authors note this problem is <i>extremely sensitive
+ * to the errors in the first integration steps</i>), and around 1e-11
+ * for a two dimensional celestial mechanics problems with seven
+ * bodies (pleiades problem, involving quasi-collisions for which
+ * <i>automatic step size control is essential</i>).
+ * </p>
+ *
+ * <p>
+ * This implementation is basically a reimplementation in Java of the
+ * <a
+ * href="http://www.unige.ch/math/folks/hairer/prog/nonstiff/odex.f">odex</a>
+ * fortran code by E. Hairer and G. Wanner. The redistribution policy
+ * for this code is available <a
+ * href="http://www.unige.ch/~hairer/prog/licence.txt">here</a>, for
+ * convenience, it is reproduced below.</p>
+ * </p>
+ *
+ * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+ * <tr><td>Copyright (c) 2004, Ernst Hairer</td></tr>
+ *
+ * <tr><td>Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * <ul>
+ *  <li>Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.</li>
+ *  <li>Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.</li>
+ * </ul></td></tr>
+ *
+ * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</strong></td></tr>
+ * </table>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public class GraggBulirschStoerIntegrator extends AdaptiveStepsizeIntegrator {
+
+    /** Integrator method name. */
+    private static final String METHOD_NAME = "Gragg-Bulirsch-Stoer";
+
+    /** maximal order. */
+    private int maxOrder;
+
+    /** step size sequence. */
+    private int[] sequence;
+
+    /** overall cost of applying step reduction up to iteration k+1, in number of calls. */
+    private int[] costPerStep;
+
+    /** cost per unit step. */
+    private double[] costPerTimeUnit;
+
+    /** optimal steps for each order. */
+    private double[] optimalStep;
+
+    /** extrapolation coefficients. */
+    private double[][] coeff;
+
+    /** stability check enabling parameter. */
+    private boolean performTest;
+
+    /** maximal number of checks for each iteration. */
+    private int maxChecks;
+
+    /** maximal number of iterations for which checks are performed. */
+    private int maxIter;
+
+    /** stepsize reduction factor in case of stability check failure. */
+    private double stabilityReduction;
+
+    /** first stepsize control factor. */
+    private double stepControl1;
+
+    /** second stepsize control factor. */
+    private double stepControl2;
+
+    /** third stepsize control factor. */
+    private double stepControl3;
+
+    /** fourth stepsize control factor. */
+    private double stepControl4;
+
+    /** first order control factor. */
+    private double orderControl1;
+
+    /** second order control factor. */
+    private double orderControl2;
+
+    /** use interpolation error in stepsize control. */
+    private boolean useInterpolationError;
+
+    /** interpolation order control parameter. */
+    private int mudif;
+
+  /** Simple constructor.
+   * Build a Gragg-Bulirsch-Stoer integrator with the given step
+   * bounds. All tuning parameters are set to their default
+   * values. The default step handler does nothing.
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param scalAbsoluteTolerance allowed absolute error
+   * @param scalRelativeTolerance allowed relative error
+   */
+  public GraggBulirschStoerIntegrator(final double minStep, final double maxStep,
+                                      final double scalAbsoluteTolerance,
+                                      final double scalRelativeTolerance) {
+    super(METHOD_NAME, minStep, maxStep,
+          scalAbsoluteTolerance, scalRelativeTolerance);
+    setStabilityCheck(true, -1, -1, -1);
+    setStepsizeControl(-1, -1, -1, -1);
+    setOrderControl(-1, -1, -1);
+    setInterpolationControl(true, -1);
+  }
+
+  /** Simple constructor.
+   * Build a Gragg-Bulirsch-Stoer integrator with the given step
+   * bounds. All tuning parameters are set to their default
+   * values. The default step handler does nothing.
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param vecAbsoluteTolerance allowed absolute error
+   * @param vecRelativeTolerance allowed relative error
+   */
+  public GraggBulirschStoerIntegrator(final double minStep, final double maxStep,
+                                      final double[] vecAbsoluteTolerance,
+                                      final double[] vecRelativeTolerance) {
+    super(METHOD_NAME, minStep, maxStep,
+          vecAbsoluteTolerance, vecRelativeTolerance);
+    setStabilityCheck(true, -1, -1, -1);
+    setStepsizeControl(-1, -1, -1, -1);
+    setOrderControl(-1, -1, -1);
+    setInterpolationControl(true, -1);
+  }
+
+  /** Set the stability check controls.
+   * <p>The stability check is performed on the first few iterations of
+   * the extrapolation scheme. If this test fails, the step is rejected
+   * and the stepsize is reduced.</p>
+   * <p>By default, the test is performed, at most during two
+   * iterations at each step, and at most once for each of these
+   * iterations. The default stepsize reduction factor is 0.5.</p>
+   * @param performStabilityCheck if true, stability check will be performed,
+     if false, the check will be skipped
+   * @param maxNumIter maximal number of iterations for which checks are
+   * performed (the number of iterations is reset to default if negative
+   * or null)
+   * @param maxNumChecks maximal number of checks for each iteration
+   * (the number of checks is reset to default if negative or null)
+   * @param stepsizeReductionFactor stepsize reduction factor in case of
+   * failure (the factor is reset to default if lower than 0.0001 or
+   * greater than 0.9999)
+   */
+  public void setStabilityCheck(final boolean performStabilityCheck,
+                                final int maxNumIter, final int maxNumChecks,
+                                final double stepsizeReductionFactor) {
+
+    this.performTest = performStabilityCheck;
+    this.maxIter     = (maxNumIter   <= 0) ? 2 : maxNumIter;
+    this.maxChecks   = (maxNumChecks <= 0) ? 1 : maxNumChecks;
+
+    if ((stepsizeReductionFactor < 0.0001) || (stepsizeReductionFactor > 0.9999)) {
+      this.stabilityReduction = 0.5;
+    } else {
+      this.stabilityReduction = stepsizeReductionFactor;
+    }
+
+  }
+
+  /** Set the step size control factors.
+
+   * <p>The new step size hNew is computed from the old one h by:
+   * <pre>
+   * hNew = h * stepControl2 / (err/stepControl1)^(1/(2k+1))
+   * </pre>
+   * where err is the scaled error and k the iteration number of the
+   * extrapolation scheme (counting from 0). The default values are
+   * 0.65 for stepControl1 and 0.94 for stepControl2.</p>
+   * <p>The step size is subject to the restriction:
+   * <pre>
+   * stepControl3^(1/(2k+1))/stepControl4 <= hNew/h <= 1/stepControl3^(1/(2k+1))
+   * </pre>
+   * The default values are 0.02 for stepControl3 and 4.0 for
+   * stepControl4.</p>
+   * @param control1 first stepsize control factor (the factor is
+   * reset to default if lower than 0.0001 or greater than 0.9999)
+   * @param control2 second stepsize control factor (the factor
+   * is reset to default if lower than 0.0001 or greater than 0.9999)
+   * @param control3 third stepsize control factor (the factor is
+   * reset to default if lower than 0.0001 or greater than 0.9999)
+   * @param control4 fourth stepsize control factor (the factor
+   * is reset to default if lower than 1.0001 or greater than 999.9)
+   */
+  public void setStepsizeControl(final double control1, final double control2,
+                                 final double control3, final double control4) {
+
+    if ((control1 < 0.0001) || (control1 > 0.9999)) {
+      this.stepControl1 = 0.65;
+    } else {
+      this.stepControl1 = control1;
+    }
+
+    if ((control2 < 0.0001) || (control2 > 0.9999)) {
+      this.stepControl2 = 0.94;
+    } else {
+      this.stepControl2 = control2;
+    }
+
+    if ((control3 < 0.0001) || (control3 > 0.9999)) {
+      this.stepControl3 = 0.02;
+    } else {
+      this.stepControl3 = control3;
+    }
+
+    if ((control4 < 1.0001) || (control4 > 999.9)) {
+      this.stepControl4 = 4.0;
+    } else {
+      this.stepControl4 = control4;
+    }
+
+  }
+
+  /** Set the order control parameters.
+   * <p>The Gragg-Bulirsch-Stoer method changes both the step size and
+   * the order during integration, in order to minimize computation
+   * cost. Each extrapolation step increases the order by 2, so the
+   * maximal order that will be used is always even, it is twice the
+   * maximal number of columns in the extrapolation table.</p>
+   * <pre>
+   * order is decreased if w(k-1) <= w(k)   * orderControl1
+   * order is increased if w(k)   <= w(k-1) * orderControl2
+   * </pre>
+   * <p>where w is the table of work per unit step for each order
+   * (number of function calls divided by the step length), and k is
+   * the current order.</p>
+   * <p>The default maximal order after construction is 18 (i.e. the
+   * maximal number of columns is 9). The default values are 0.8 for
+   * orderControl1 and 0.9 for orderControl2.</p>
+   * @param maximalOrder maximal order in the extrapolation table (the
+   * maximal order is reset to default if order <= 6 or odd)
+   * @param control1 first order control factor (the factor is
+   * reset to default if lower than 0.0001 or greater than 0.9999)
+   * @param control2 second order control factor (the factor
+   * is reset to default if lower than 0.0001 or greater than 0.9999)
+   */
+  public void setOrderControl(final int maximalOrder,
+                              final double control1, final double control2) {
+
+    if ((maximalOrder <= 6) || (maximalOrder % 2 != 0)) {
+      this.maxOrder = 18;
+    }
+
+    if ((control1 < 0.0001) || (control1 > 0.9999)) {
+      this.orderControl1 = 0.8;
+    } else {
+      this.orderControl1 = control1;
+    }
+
+    if ((control2 < 0.0001) || (control2 > 0.9999)) {
+      this.orderControl2 = 0.9;
+    } else {
+      this.orderControl2 = control2;
+    }
+
+    // reinitialize the arrays
+    initializeArrays();
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void addStepHandler (final StepHandler handler) {
+
+    super.addStepHandler(handler);
+
+    // reinitialize the arrays
+    initializeArrays();
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void addEventHandler(final EventHandler function,
+                              final double maxCheckInterval,
+                              final double convergence,
+                              final int maxIterationCount) {
+    super.addEventHandler(function, maxCheckInterval, convergence, maxIterationCount);
+
+    // reinitialize the arrays
+    initializeArrays();
+
+  }
+
+  /** Initialize the integrator internal arrays. */
+  private void initializeArrays() {
+
+    final int size = maxOrder / 2;
+
+    if ((sequence == null) || (sequence.length != size)) {
+      // all arrays should be reallocated with the right size
+      sequence        = new int[size];
+      costPerStep     = new int[size];
+      coeff           = new double[size][];
+      costPerTimeUnit = new double[size];
+      optimalStep     = new double[size];
+    }
+
+    if (requiresDenseOutput()) {
+      // step size sequence: 2, 6, 10, 14, ...
+      for (int k = 0; k < size; ++k) {
+        sequence[k] = 4 * k + 2;
+      }
+    } else {
+      // step size sequence: 2, 4, 6, 8, ...
+      for (int k = 0; k < size; ++k) {
+        sequence[k] = 2 * (k + 1);
+      }
+    }
+
+    // initialize the order selection cost array
+    // (number of function calls for each column of the extrapolation table)
+    costPerStep[0] = sequence[0] + 1;
+    for (int k = 1; k < size; ++k) {
+      costPerStep[k] = costPerStep[k-1] + sequence[k];
+    }
+
+    // initialize the extrapolation tables
+    for (int k = 0; k < size; ++k) {
+      coeff[k] = (k > 0) ? new double[k] : null;
+      for (int l = 0; l < k; ++l) {
+        final double ratio = ((double) sequence[k]) / sequence[k-l-1];
+        coeff[k][l] = 1.0 / (ratio * ratio - 1.0);
+      }
+    }
+
+  }
+
+  /** Set the interpolation order control parameter.
+   * The interpolation order for dense output is 2k - mudif + 1. The
+   * default value for mudif is 4 and the interpolation error is used
+   * in stepsize control by default.
+   *
+   * @param useInterpolationErrorForControl if true, interpolation error is used
+   * for stepsize control
+   * @param mudifControlParameter interpolation order control parameter (the parameter
+   * is reset to default if <= 0 or >= 7)
+   */
+  public void setInterpolationControl(final boolean useInterpolationErrorForControl,
+                                      final int mudifControlParameter) {
+
+    this.useInterpolationError = useInterpolationErrorForControl;
+
+    if ((mudifControlParameter <= 0) || (mudifControlParameter >= 7)) {
+      this.mudif = 4;
+    } else {
+      this.mudif = mudifControlParameter;
+    }
+
+  }
+
+  /** Update scaling array.
+   * @param y1 first state vector to use for scaling
+   * @param y2 second state vector to use for scaling
+   * @param scale scaling array to update (can be shorter than state)
+   */
+  private void rescale(final double[] y1, final double[] y2, final double[] scale) {
+    if (vecAbsoluteTolerance == null) {
+      for (int i = 0; i < scale.length; ++i) {
+        final double yi = FastMath.max(FastMath.abs(y1[i]), FastMath.abs(y2[i]));
+        scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * yi;
+      }
+    } else {
+      for (int i = 0; i < scale.length; ++i) {
+        final double yi = FastMath.max(FastMath.abs(y1[i]), FastMath.abs(y2[i]));
+        scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yi;
+      }
+    }
+  }
+
+  /** Perform integration over one step using substeps of a modified
+   * midpoint method.
+   * @param t0 initial time
+   * @param y0 initial value of the state vector at t0
+   * @param step global step
+   * @param k iteration number (from 0 to sequence.length - 1)
+   * @param scale scaling array (can be shorter than state)
+   * @param f placeholder where to put the state vector derivatives at each substep
+   *          (element 0 already contains initial derivative)
+   * @param yMiddle placeholder where to put the state vector at the middle of the step
+   * @param yEnd placeholder where to put the state vector at the end
+   * @param yTmp placeholder for one state vector
+   * @return true if computation was done properly,
+   *         false if stability check failed before end of computation
+   * @throws DerivativeException this exception is propagated to the caller if the
+   * underlying user function triggers one
+   */
+  private boolean tryStep(final double t0, final double[] y0, final double step, final int k,
+                          final double[] scale, final double[][] f,
+                          final double[] yMiddle, final double[] yEnd,
+                          final double[] yTmp)
+    throws DerivativeException {
+
+    final int    n        = sequence[k];
+    final double subStep  = step / n;
+    final double subStep2 = 2 * subStep;
+
+    // first substep
+    double t = t0 + subStep;
+    for (int i = 0; i < y0.length; ++i) {
+      yTmp[i] = y0[i];
+      yEnd[i] = y0[i] + subStep * f[0][i];
+    }
+    computeDerivatives(t, yEnd, f[1]);
+
+    // other substeps
+    for (int j = 1; j < n; ++j) {
+
+      if (2 * j == n) {
+        // save the point at the middle of the step
+        System.arraycopy(yEnd, 0, yMiddle, 0, y0.length);
+      }
+
+      t += subStep;
+      for (int i = 0; i < y0.length; ++i) {
+        final double middle = yEnd[i];
+        yEnd[i]       = yTmp[i] + subStep2 * f[j][i];
+        yTmp[i]       = middle;
+      }
+
+      computeDerivatives(t, yEnd, f[j+1]);
+
+      // stability check
+      if (performTest && (j <= maxChecks) && (k < maxIter)) {
+        double initialNorm = 0.0;
+        for (int l = 0; l < scale.length; ++l) {
+          final double ratio = f[0][l] / scale[l];
+          initialNorm += ratio * ratio;
+        }
+        double deltaNorm = 0.0;
+        for (int l = 0; l < scale.length; ++l) {
+          final double ratio = (f[j+1][l] - f[0][l]) / scale[l];
+          deltaNorm += ratio * ratio;
+        }
+        if (deltaNorm > 4 * FastMath.max(1.0e-15, initialNorm)) {
+          return false;
+        }
+      }
+
+    }
+
+    // correction of the last substep (at t0 + step)
+    for (int i = 0; i < y0.length; ++i) {
+      yEnd[i] = 0.5 * (yTmp[i] + yEnd[i] + subStep * f[n][i]);
+    }
+
+    return true;
+
+  }
+
+  /** Extrapolate a vector.
+   * @param offset offset to use in the coefficients table
+   * @param k index of the last updated point
+   * @param diag working diagonal of the Aitken-Neville's
+   * triangle, without the last element
+   * @param last last element
+   */
+  private void extrapolate(final int offset, final int k,
+                           final double[][] diag, final double[] last) {
+
+    // update the diagonal
+    for (int j = 1; j < k; ++j) {
+      for (int i = 0; i < last.length; ++i) {
+        // Aitken-Neville's recursive formula
+        diag[k-j-1][i] = diag[k-j][i] +
+                         coeff[k+offset][j-1] * (diag[k-j][i] - diag[k-j-1][i]);
+      }
+    }
+
+    // update the last element
+    for (int i = 0; i < last.length; ++i) {
+      // Aitken-Neville's recursive formula
+      last[i] = diag[0][i] + coeff[k+offset][k-1] * (diag[0][i] - last[i]);
+    }
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public double integrate(final FirstOrderDifferentialEquations equations,
+                          final double t0, final double[] y0, final double t, final double[] y)
+      throws DerivativeException, IntegratorException {
+
+    sanityChecks(equations, t0, y0, t, y);
+    setEquations(equations);
+    resetEvaluations();
+    final boolean forward = t > t0;
+
+    // create some internal working arrays
+    final double[] yDot0   = new double[y0.length];
+    final double[] y1      = new double[y0.length];
+    final double[] yTmp    = new double[y0.length];
+    final double[] yTmpDot = new double[y0.length];
+
+    final double[][] diagonal = new double[sequence.length-1][];
+    final double[][] y1Diag = new double[sequence.length-1][];
+    for (int k = 0; k < sequence.length-1; ++k) {
+      diagonal[k] = new double[y0.length];
+      y1Diag[k] = new double[y0.length];
+    }
+
+    final double[][][] fk  = new double[sequence.length][][];
+    for (int k = 0; k < sequence.length; ++k) {
+
+      fk[k]    = new double[sequence[k] + 1][];
+
+      // all substeps start at the same point, so share the first array
+      fk[k][0] = yDot0;
+
+      for (int l = 0; l < sequence[k]; ++l) {
+        fk[k][l+1] = new double[y0.length];
+      }
+
+    }
+
+    if (y != y0) {
+      System.arraycopy(y0, 0, y, 0, y0.length);
+    }
+
+    double[] yDot1      = new double[y0.length];
+    double[][] yMidDots = null;
+    final boolean denseOutput = requiresDenseOutput();
+    if (denseOutput) {
+      yMidDots = new double[1 + 2 * sequence.length][];
+      for (int j = 0; j < yMidDots.length; ++j) {
+        yMidDots[j] = new double[y0.length];
+      }
+    } else {
+      yMidDots    = new double[1][];
+      yMidDots[0] = new double[y0.length];
+    }
+
+    // initial scaling
+    final double[] scale = new double[mainSetDimension];
+    rescale(y, y, scale);
+
+    // initial order selection
+    final double tol =
+        (vecRelativeTolerance == null) ? scalRelativeTolerance : vecRelativeTolerance[0];
+    final double log10R = FastMath.log10(FastMath.max(1.0e-10, tol));
+    int targetIter = FastMath.max(1,
+                              FastMath.min(sequence.length - 2,
+                                       (int) FastMath.floor(0.5 - 0.6 * log10R)));
+    // set up an interpolator sharing the integrator arrays
+    AbstractStepInterpolator interpolator = null;
+    if (denseOutput) {
+      interpolator = new GraggBulirschStoerStepInterpolator(y, yDot0,
+                                                            y1, yDot1,
+                                                            yMidDots, forward);
+    } else {
+      interpolator = new DummyStepInterpolator(y, yDot1, forward);
+    }
+    interpolator.storeTime(t0);
+
+    stepStart = t0;
+    double  hNew             = 0;
+    double  maxError         = Double.MAX_VALUE;
+    boolean previousRejected = false;
+    boolean firstTime        = true;
+    boolean newStep          = true;
+    boolean firstStepAlreadyComputed = false;
+    for (StepHandler handler : stepHandlers) {
+        handler.reset();
+    }
+    setStateInitialized(false);
+    costPerTimeUnit[0] = 0;
+    isLastStep = false;
+    do {
+
+      double error;
+      boolean reject = false;
+
+      if (newStep) {
+
+        interpolator.shift();
+
+        // first evaluation, at the beginning of the step
+        if (! firstStepAlreadyComputed) {
+          computeDerivatives(stepStart, y, yDot0);
+        }
+
+        if (firstTime) {
+          hNew = initializeStep(equations, forward,
+                                2 * targetIter + 1, scale,
+                                stepStart, y, yDot0, yTmp, yTmpDot);
+        }
+
+        newStep = false;
+
+      }
+
+      stepSize = hNew;
+
+      // step adjustment near bounds
+      if ((forward && (stepStart + stepSize > t)) ||
+          ((! forward) && (stepStart + stepSize < t))) {
+        stepSize = t - stepStart;
+      }
+      final double nextT = stepStart + stepSize;
+      isLastStep = forward ? (nextT >= t) : (nextT <= t);
+
+      // iterate over several substep sizes
+      int k = -1;
+      for (boolean loop = true; loop; ) {
+
+        ++k;
+
+        // modified midpoint integration with the current substep
+        if ( ! tryStep(stepStart, y, stepSize, k, scale, fk[k],
+                       (k == 0) ? yMidDots[0] : diagonal[k-1],
+                       (k == 0) ? y1 : y1Diag[k-1],
+                       yTmp)) {
+
+          // the stability check failed, we reduce the global step
+          hNew   = FastMath.abs(filterStep(stepSize * stabilityReduction, forward, false));
+          reject = true;
+          loop   = false;
+
+        } else {
+
+          // the substep was computed successfully
+          if (k > 0) {
+
+            // extrapolate the state at the end of the step
+            // using last iteration data
+            extrapolate(0, k, y1Diag, y1);
+            rescale(y, y1, scale);
+
+            // estimate the error at the end of the step.
+            error = 0;
+            for (int j = 0; j < mainSetDimension; ++j) {
+              final double e = FastMath.abs(y1[j] - y1Diag[0][j]) / scale[j];
+              error += e * e;
+            }
+            error = FastMath.sqrt(error / mainSetDimension);
+
+            if ((error > 1.0e15) || ((k > 1) && (error > maxError))) {
+              // error is too big, we reduce the global step
+              hNew   = FastMath.abs(filterStep(stepSize * stabilityReduction, forward, false));
+              reject = true;
+              loop   = false;
+            } else {
+
+              maxError = FastMath.max(4 * error, 1.0);
+
+              // compute optimal stepsize for this order
+              final double exp = 1.0 / (2 * k + 1);
+              double fac = stepControl2 / FastMath.pow(error / stepControl1, exp);
+              final double pow = FastMath.pow(stepControl3, exp);
+              fac = FastMath.max(pow / stepControl4, FastMath.min(1 / pow, fac));
+              optimalStep[k]     = FastMath.abs(filterStep(stepSize * fac, forward, true));
+              costPerTimeUnit[k] = costPerStep[k] / optimalStep[k];
+
+              // check convergence
+              switch (k - targetIter) {
+
+              case -1 :
+                if ((targetIter > 1) && ! previousRejected) {
+
+                  // check if we can stop iterations now
+                  if (error <= 1.0) {
+                    // convergence have been reached just before targetIter
+                    loop = false;
+                  } else {
+                    // estimate if there is a chance convergence will
+                    // be reached on next iteration, using the
+                    // asymptotic evolution of error
+                    final double ratio = ((double) sequence [targetIter] * sequence[targetIter + 1]) /
+                                         (sequence[0] * sequence[0]);
+                    if (error > ratio * ratio) {
+                      // we don't expect to converge on next iteration
+                      // we reject the step immediately and reduce order
+                      reject = true;
+                      loop   = false;
+                      targetIter = k;
+                      if ((targetIter > 1) &&
+                          (costPerTimeUnit[targetIter-1] <
+                           orderControl1 * costPerTimeUnit[targetIter])) {
+                        --targetIter;
+                      }
+                      hNew = optimalStep[targetIter];
+                    }
+                  }
+                }
+                break;
+
+              case 0:
+                if (error <= 1.0) {
+                  // convergence has been reached exactly at targetIter
+                  loop = false;
+                } else {
+                  // estimate if there is a chance convergence will
+                  // be reached on next iteration, using the
+                  // asymptotic evolution of error
+                  final double ratio = ((double) sequence[k+1]) / sequence[0];
+                  if (error > ratio * ratio) {
+                    // we don't expect to converge on next iteration
+                    // we reject the step immediately
+                    reject = true;
+                    loop = false;
+                    if ((targetIter > 1) &&
+                        (costPerTimeUnit[targetIter-1] <
+                         orderControl1 * costPerTimeUnit[targetIter])) {
+                      --targetIter;
+                    }
+                    hNew = optimalStep[targetIter];
+                  }
+                }
+                break;
+
+              case 1 :
+                if (error > 1.0) {
+                  reject = true;
+                  if ((targetIter > 1) &&
+                      (costPerTimeUnit[targetIter-1] <
+                       orderControl1 * costPerTimeUnit[targetIter])) {
+                    --targetIter;
+                  }
+                  hNew = optimalStep[targetIter];
+                }
+                loop = false;
+                break;
+
+              default :
+                if ((firstTime || isLastStep) && (error <= 1.0)) {
+                  loop = false;
+                }
+                break;
+
+              }
+
+            }
+          }
+        }
+      }
+
+      if (! reject) {
+          // derivatives at end of step
+          computeDerivatives(stepStart + stepSize, y1, yDot1);
+      }
+
+      // dense output handling
+      double hInt = getMaxStep();
+      if (denseOutput && ! reject) {
+
+        // extrapolate state at middle point of the step
+        for (int j = 1; j <= k; ++j) {
+          extrapolate(0, j, diagonal, yMidDots[0]);
+        }
+
+        final int mu = 2 * k - mudif + 3;
+
+        for (int l = 0; l < mu; ++l) {
+
+          // derivative at middle point of the step
+          final int l2 = l / 2;
+          double factor = FastMath.pow(0.5 * sequence[l2], l);
+          int middleIndex = fk[l2].length / 2;
+          for (int i = 0; i < y0.length; ++i) {
+            yMidDots[l+1][i] = factor * fk[l2][middleIndex + l][i];
+          }
+          for (int j = 1; j <= k - l2; ++j) {
+            factor = FastMath.pow(0.5 * sequence[j + l2], l);
+            middleIndex = fk[l2+j].length / 2;
+            for (int i = 0; i < y0.length; ++i) {
+              diagonal[j-1][i] = factor * fk[l2+j][middleIndex+l][i];
+            }
+            extrapolate(l2, j, diagonal, yMidDots[l+1]);
+          }
+          for (int i = 0; i < y0.length; ++i) {
+            yMidDots[l+1][i] *= stepSize;
+          }
+
+          // compute centered differences to evaluate next derivatives
+          for (int j = (l + 1) / 2; j <= k; ++j) {
+            for (int m = fk[j].length - 1; m >= 2 * (l + 1); --m) {
+              for (int i = 0; i < y0.length; ++i) {
+                fk[j][m][i] -= fk[j][m-2][i];
+              }
+            }
+          }
+
+        }
+
+        if (mu >= 0) {
+
+          // estimate the dense output coefficients
+          final GraggBulirschStoerStepInterpolator gbsInterpolator
+            = (GraggBulirschStoerStepInterpolator) interpolator;
+          gbsInterpolator.computeCoefficients(mu, stepSize);
+
+          if (useInterpolationError) {
+            // use the interpolation error to limit stepsize
+            final double interpError = gbsInterpolator.estimateError(scale);
+            hInt = FastMath.abs(stepSize / FastMath.max(FastMath.pow(interpError, 1.0 / (mu+4)),
+                                                0.01));
+            if (interpError > 10.0) {
+              hNew = hInt;
+              reject = true;
+            }
+          }
+
+        }
+
+      }
+
+      if (! reject) {
+
+        // Discrete events handling
+        interpolator.storeTime(stepStart + stepSize);
+        stepStart = acceptStep(interpolator, y1, yDot1, t);
+
+        // prepare next step
+        interpolator.storeTime(stepStart);
+        System.arraycopy(y1, 0, y, 0, y0.length);
+        System.arraycopy(yDot1, 0, yDot0, 0, y0.length);
+        firstStepAlreadyComputed = true;
+
+        int optimalIter;
+        if (k == 1) {
+          optimalIter = 2;
+          if (previousRejected) {
+            optimalIter = 1;
+          }
+        } else if (k <= targetIter) {
+          optimalIter = k;
+          if (costPerTimeUnit[k-1] < orderControl1 * costPerTimeUnit[k]) {
+            optimalIter = k-1;
+          } else if (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[k-1]) {
+            optimalIter = FastMath.min(k+1, sequence.length - 2);
+          }
+        } else {
+          optimalIter = k - 1;
+          if ((k > 2) &&
+              (costPerTimeUnit[k-2] < orderControl1 * costPerTimeUnit[k-1])) {
+            optimalIter = k - 2;
+          }
+          if (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[optimalIter]) {
+            optimalIter = FastMath.min(k, sequence.length - 2);
+          }
+        }
+
+        if (previousRejected) {
+          // after a rejected step neither order nor stepsize
+          // should increase
+          targetIter = FastMath.min(optimalIter, k);
+          hNew = FastMath.min(FastMath.abs(stepSize), optimalStep[targetIter]);
+        } else {
+          // stepsize control
+          if (optimalIter <= k) {
+            hNew = optimalStep[optimalIter];
+          } else {
+            if ((k < targetIter) &&
+                (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[k-1])) {
+              hNew = filterStep(optimalStep[k] * costPerStep[optimalIter+1] / costPerStep[k],
+                               forward, false);
+            } else {
+              hNew = filterStep(optimalStep[k] * costPerStep[optimalIter] / costPerStep[k],
+                                forward, false);
+            }
+          }
+
+          targetIter = optimalIter;
+
+        }
+
+        newStep = true;
+
+      }
+
+      hNew = FastMath.min(hNew, hInt);
+      if (! forward) {
+        hNew = -hNew;
+      }
+
+      firstTime = false;
+
+      if (reject) {
+        isLastStep = false;
+        previousRejected = true;
+      } else {
+        previousRejected = false;
+      }
+
+    } while (!isLastStep);
+
+    final double stopTime = stepStart;
+    resetInternalState();
+    return stopTime;
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterpolator.java
new file mode 100644
index 0000000..48fdf2c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerStepInterpolator.java
@@ -0,0 +1,401 @@
+/*
+ * 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.ode.nonstiff;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements an interpolator for the Gragg-Bulirsch-Stoer
+ * integrator.
+ *
+ * <p>This interpolator compute dense output inside the last step
+ * produced by a Gragg-Bulirsch-Stoer integrator.</p>
+ *
+ * <p>
+ * This implementation is basically a reimplementation in Java of the
+ * <a
+ * href="http://www.unige.ch/math/folks/hairer/prog/nonstiff/odex.f">odex</a>
+ * fortran code by E. Hairer and G. Wanner. The redistribution policy
+ * for this code is available <a
+ * href="http://www.unige.ch/~hairer/prog/licence.txt">here</a>, for
+ * convenience, it is reproduced below.</p>
+ * </p>
+ *
+ * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+ * <tr><td>Copyright (c) 2004, Ernst Hairer</td></tr>
+ *
+ * <tr><td>Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ * <ul>
+ *  <li>Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.</li>
+ *  <li>Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.</li>
+ * </ul></td></tr>
+ *
+ * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</strong></td></tr>
+ * </table>
+ *
+ * @see GraggBulirschStoerIntegrator
+ * @version $Revision: 1061507 $ $Date: 2011-01-20 21:55:00 +0100 (jeu. 20 janv. 2011) $
+ * @since 1.2
+ */
+
+class GraggBulirschStoerStepInterpolator
+  extends AbstractStepInterpolator {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 7320613236731409847L;
+
+    /** Slope at the beginning of the step. */
+    private double[] y0Dot;
+
+    /** State at the end of the step. */
+    private double[] y1;
+
+    /** Slope at the end of the step. */
+    private double[] y1Dot;
+
+    /** Derivatives at the middle of the step.
+     * element 0 is state at midpoint, element 1 is first derivative ...
+     */
+    private double[][] yMidDots;
+
+    /** Interpolation polynoms. */
+    private double[][] polynoms;
+
+    /** Error coefficients for the interpolation. */
+    private double[] errfac;
+
+    /** Degree of the interpolation polynoms. */
+    private int currentDegree;
+
+  /** Simple constructor.
+   * This constructor should not be used directly, it is only intended
+   * for the serialization process.
+   */
+  public GraggBulirschStoerStepInterpolator() {
+    y0Dot    = null;
+    y1       = null;
+    y1Dot    = null;
+    yMidDots = null;
+    resetTables(-1);
+  }
+
+  /** Simple constructor.
+   * @param y reference to the integrator array holding the current state
+   * @param y0Dot reference to the integrator array holding the slope
+   * at the beginning of the step
+   * @param y1 reference to the integrator array holding the state at
+   * the end of the step
+   * @param y1Dot reference to the integrator array holding the slope
+   * at the end of the step
+   * @param yMidDots reference to the integrator array holding the
+   * derivatives at the middle point of the step
+   * @param forward integration direction indicator
+   */
+  public GraggBulirschStoerStepInterpolator(final double[] y, final double[] y0Dot,
+                                            final double[] y1, final double[] y1Dot,
+                                            final double[][] yMidDots,
+                                            final boolean forward) {
+
+    super(y, forward);
+    this.y0Dot    = y0Dot;
+    this.y1       = y1;
+    this.y1Dot    = y1Dot;
+    this.yMidDots = yMidDots;
+
+    resetTables(yMidDots.length + 4);
+
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public GraggBulirschStoerStepInterpolator
+    (final GraggBulirschStoerStepInterpolator interpolator) {
+
+    super(interpolator);
+
+    final int dimension = currentState.length;
+
+    // the interpolator has been finalized,
+    // the following arrays are not needed anymore
+    y0Dot    = null;
+    y1       = null;
+    y1Dot    = null;
+    yMidDots = null;
+
+    // copy the interpolation polynoms (up to the current degree only)
+    if (interpolator.polynoms == null) {
+      polynoms = null;
+      currentDegree = -1;
+    } else {
+      resetTables(interpolator.currentDegree);
+      for (int i = 0; i < polynoms.length; ++i) {
+        polynoms[i] = new double[dimension];
+        System.arraycopy(interpolator.polynoms[i], 0,
+                         polynoms[i], 0, dimension);
+      }
+      currentDegree = interpolator.currentDegree;
+    }
+
+  }
+
+  /** Reallocate the internal tables.
+   * Reallocate the internal tables in order to be able to handle
+   * interpolation polynoms up to the given degree
+   * @param maxDegree maximal degree to handle
+   */
+  private void resetTables(final int maxDegree) {
+
+    if (maxDegree < 0) {
+      polynoms      = null;
+      errfac        = null;
+      currentDegree = -1;
+    } else {
+
+      final double[][] newPols = new double[maxDegree + 1][];
+      if (polynoms != null) {
+        System.arraycopy(polynoms, 0, newPols, 0, polynoms.length);
+        for (int i = polynoms.length; i < newPols.length; ++i) {
+          newPols[i] = new double[currentState.length];
+        }
+      } else {
+        for (int i = 0; i < newPols.length; ++i) {
+          newPols[i] = new double[currentState.length];
+        }
+      }
+      polynoms = newPols;
+
+      // initialize the error factors array for interpolation
+      if (maxDegree <= 4) {
+        errfac = null;
+      } else {
+        errfac = new double[maxDegree - 4];
+        for (int i = 0; i < errfac.length; ++i) {
+          final int ip5 = i + 5;
+          errfac[i] = 1.0 / (ip5 * ip5);
+          final double e = 0.5 * FastMath.sqrt (((double) (i + 1)) / ip5);
+          for (int j = 0; j <= i; ++j) {
+            errfac[i] *= e / (j + 1);
+          }
+        }
+      }
+
+      currentDegree = 0;
+
+    }
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new GraggBulirschStoerStepInterpolator(this);
+  }
+
+
+  /** Compute the interpolation coefficients for dense output.
+   * @param mu degree of the interpolation polynomial
+   * @param h current step
+   */
+  public void computeCoefficients(final int mu, final double h) {
+
+    if ((polynoms == null) || (polynoms.length <= (mu + 4))) {
+      resetTables(mu + 4);
+    }
+
+    currentDegree = mu + 4;
+
+    for (int i = 0; i < currentState.length; ++i) {
+
+      final double yp0   = h * y0Dot[i];
+      final double yp1   = h * y1Dot[i];
+      final double ydiff = y1[i] - currentState[i];
+      final double aspl  = ydiff - yp1;
+      final double bspl  = yp0 - ydiff;
+
+      polynoms[0][i] = currentState[i];
+      polynoms[1][i] = ydiff;
+      polynoms[2][i] = aspl;
+      polynoms[3][i] = bspl;
+
+      if (mu < 0) {
+        return;
+      }
+
+      // compute the remaining coefficients
+      final double ph0 = 0.5 * (currentState[i] + y1[i]) + 0.125 * (aspl + bspl);
+      polynoms[4][i] = 16 * (yMidDots[0][i] - ph0);
+
+      if (mu > 0) {
+        final double ph1 = ydiff + 0.25 * (aspl - bspl);
+        polynoms[5][i] = 16 * (yMidDots[1][i] - ph1);
+
+        if (mu > 1) {
+          final double ph2 = yp1 - yp0;
+          polynoms[6][i] = 16 * (yMidDots[2][i] - ph2 + polynoms[4][i]);
+
+          if (mu > 2) {
+            final double ph3 = 6 * (bspl - aspl);
+            polynoms[7][i] = 16 * (yMidDots[3][i] - ph3 + 3 * polynoms[5][i]);
+
+            for (int j = 4; j <= mu; ++j) {
+              final double fac1 = 0.5 * j * (j - 1);
+              final double fac2 = 2 * fac1 * (j - 2) * (j - 3);
+              polynoms[j+4][i] =
+                  16 * (yMidDots[j][i] + fac1 * polynoms[j+2][i] - fac2 * polynoms[j][i]);
+            }
+
+          }
+        }
+      }
+    }
+
+  }
+
+  /** Estimate interpolation error.
+   * @param scale scaling array
+   * @return estimate of the interpolation error
+   */
+  public double estimateError(final double[] scale) {
+    double error = 0;
+    if (currentDegree >= 5) {
+      for (int i = 0; i < scale.length; ++i) {
+        final double e = polynoms[currentDegree][i] / scale[i];
+        error += e * e;
+      }
+      error = FastMath.sqrt(error / scale.length) * errfac[currentDegree - 5];
+    }
+    return error;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH) {
+
+    final int dimension = currentState.length;
+
+    final double oneMinusTheta = 1.0 - theta;
+    final double theta05       = theta - 0.5;
+    final double tOmT          = theta * oneMinusTheta;
+    final double t4            = tOmT * tOmT;
+    final double t4Dot         = 2 * tOmT * (1 - 2 * theta);
+    final double dot1          = 1.0 / h;
+    final double dot2          = theta * (2 - 3 * theta) / h;
+    final double dot3          = ((3 * theta - 4) * theta + 1) / h;
+
+    for (int i = 0; i < dimension; ++i) {
+
+        final double p0 = polynoms[0][i];
+        final double p1 = polynoms[1][i];
+        final double p2 = polynoms[2][i];
+        final double p3 = polynoms[3][i];
+        interpolatedState[i] = p0 + theta * (p1 + oneMinusTheta * (p2 * theta + p3 * oneMinusTheta));
+        interpolatedDerivatives[i] = dot1 * p1 + dot2 * p2 + dot3 * p3;
+
+        if (currentDegree > 3) {
+            double cDot = 0;
+            double c = polynoms[currentDegree][i];
+            for (int j = currentDegree - 1; j > 3; --j) {
+                final double d = 1.0 / (j - 3);
+                cDot = d * (theta05 * cDot + c);
+                c = polynoms[j][i] + c * d * theta05;
+            }
+            interpolatedState[i]       += t4 * c;
+            interpolatedDerivatives[i] += (t4 * cDot + t4Dot * c) / h;
+        }
+
+    }
+
+    if (h == 0) {
+        // in this degenerated case, the previous computation leads to NaN for derivatives
+        // we fix this by using the derivatives at midpoint
+        System.arraycopy(yMidDots[1], 0, interpolatedDerivatives, 0, dimension);
+    }
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void writeExternal(final ObjectOutput out)
+    throws IOException {
+
+    final int dimension = (currentState == null) ? -1 : currentState.length;
+
+    // save the state of the base class
+    writeBaseExternal(out);
+
+    // save the local attributes (but not the temporary vectors)
+    out.writeInt(currentDegree);
+    for (int k = 0; k <= currentDegree; ++k) {
+      for (int l = 0; l < dimension; ++l) {
+        out.writeDouble(polynoms[k][l]);
+      }
+    }
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void readExternal(final ObjectInput in)
+    throws IOException {
+
+    // read the base class
+    final double t = readBaseExternal(in);
+    final int dimension = (currentState == null) ? -1 : currentState.length;
+
+    // read the local attributes
+    final int degree = in.readInt();
+    resetTables(degree);
+    currentDegree = degree;
+
+    for (int k = 0; k <= currentDegree; ++k) {
+      for (int l = 0; l < dimension; ++l) {
+        polynoms[k][l] = in.readDouble();
+      }
+    }
+
+    // we can now set the interpolated time and state
+    setInterpolatedTime(t);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54Integrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54Integrator.java
new file mode 100644
index 0000000..6ea8564
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54Integrator.java
@@ -0,0 +1,132 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * This class implements the 5(4) Higham and Hall integrator for
+ * Ordinary Differential Equations.
+ *
+ * <p>This integrator is an embedded Runge-Kutta integrator
+ * of order 5(4) used in local extrapolation mode (i.e. the solution
+ * is computed using the high order formula) with stepsize control
+ * (and automatic step initialization) and continuous output. This
+ * method uses 7 functions evaluations per step.</p>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 1.2
+ */
+
+public class HighamHall54Integrator extends EmbeddedRungeKuttaIntegrator {
+
+  /** Integrator method name. */
+  private static final String METHOD_NAME = "Higham-Hall 5(4)";
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    2.0/9.0, 1.0/3.0, 1.0/2.0, 3.0/5.0, 1.0, 1.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+    {2.0/9.0},
+    {1.0/12.0, 1.0/4.0},
+    {1.0/8.0, 0.0, 3.0/8.0},
+    {91.0/500.0, -27.0/100.0, 78.0/125.0, 8.0/125.0},
+    {-11.0/20.0, 27.0/20.0, 12.0/5.0, -36.0/5.0, 5.0},
+    {1.0/12.0, 0.0, 27.0/32.0, -4.0/3.0, 125.0/96.0, 5.0/48.0}
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    1.0/12.0, 0.0, 27.0/32.0, -4.0/3.0, 125.0/96.0, 5.0/48.0, 0.0
+  };
+
+  /** Error weights Butcher array. */
+  private static final double[] STATIC_E = {
+    -1.0/20.0, 0.0, 81.0/160.0, -6.0/5.0, 25.0/32.0, 1.0/16.0, -1.0/10.0
+  };
+
+  /** Simple constructor.
+   * Build a fifth order Higham and Hall integrator with the given step bounds
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param scalAbsoluteTolerance allowed absolute error
+   * @param scalRelativeTolerance allowed relative error
+   */
+  public HighamHall54Integrator(final double minStep, final double maxStep,
+                                final double scalAbsoluteTolerance,
+                                final double scalRelativeTolerance) {
+    super(METHOD_NAME, false, STATIC_C, STATIC_A, STATIC_B, new HighamHall54StepInterpolator(),
+          minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+  }
+
+  /** Simple constructor.
+   * Build a fifth order Higham and Hall integrator with the given step bounds
+   * @param minStep minimal step (must be positive even for backward
+   * integration), the last step can be smaller than this
+   * @param maxStep maximal step (must be positive even for backward
+   * integration)
+   * @param vecAbsoluteTolerance allowed absolute error
+   * @param vecRelativeTolerance allowed relative error
+   */
+  public HighamHall54Integrator(final double minStep, final double maxStep,
+                                final double[] vecAbsoluteTolerance,
+                                final double[] vecRelativeTolerance) {
+    super(METHOD_NAME, false, STATIC_C, STATIC_A, STATIC_B, new HighamHall54StepInterpolator(),
+          minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public int getOrder() {
+    return 5;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected double estimateError(final double[][] yDotK,
+                                 final double[] y0, final double[] y1,
+                                 final double h) {
+
+    double error = 0;
+
+    for (int j = 0; j < mainSetDimension; ++j) {
+      double errSum = STATIC_E[0] * yDotK[0][j];
+      for (int l = 1; l < STATIC_E.length; ++l) {
+        errSum += STATIC_E[l] * yDotK[l][j];
+      }
+
+      final double yScale = FastMath.max(FastMath.abs(y0[j]), FastMath.abs(y1[j]));
+      final double tol = (vecAbsoluteTolerance == null) ?
+                         (scalAbsoluteTolerance + scalRelativeTolerance * yScale) :
+                         (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale);
+      final double ratio  = h * errSum / tol;
+      error += ratio * ratio;
+
+    }
+
+    return FastMath.sqrt(error / mainSetDimension);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolator.java
new file mode 100644
index 0000000..f3eb9fb
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/HighamHall54StepInterpolator.java
@@ -0,0 +1,103 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class represents an interpolator over the last step during an
+ * ODE integration for the 5(4) Higham and Hall integrator.
+ *
+ * @see HighamHall54Integrator
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class HighamHall54StepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+  /** Serializable version identifier */
+  private static final long serialVersionUID = -3583240427587318654L;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link
+   * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize}
+   * method should be called before using the instance in order to
+   * initialize the internal arrays. This constructor is used only
+   * in order to delay the initialization in some cases. The {@link
+   * EmbeddedRungeKuttaIntegrator} uses the prototyping design pattern
+   * to create the step interpolators by cloning an uninitialized model
+   * and later initializing the copy.
+   */
+  public HighamHall54StepInterpolator() {
+    super();
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public HighamHall54StepInterpolator(final HighamHall54StepInterpolator interpolator) {
+    super(interpolator);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new HighamHall54StepInterpolator(this);
+  }
+
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+    throws DerivativeException {
+
+    final double theta2 = theta * theta;
+
+    final double b0 = h * (-1.0/12.0 + theta * (1.0 + theta * (-15.0/4.0 + theta * (16.0/3.0 + theta * -5.0/2.0))));
+    final double b2 = h * (-27.0/32.0 + theta2 * (459.0/32.0 + theta * (-243.0/8.0 + theta * 135.0/8.0)));
+    final double b3 = h * (4.0/3.0 + theta2 * (-22.0 + theta * (152.0/3.0  + theta * -30.0)));
+    final double b4 = h * (-125.0/96.0 + theta2 * (375.0/32.0 + theta * (-625.0/24.0 + theta * 125.0/8.0)));
+    final double b5 = h * (-5.0/48.0 + theta2 * (-5.0/16.0 + theta * 5.0/12.0));
+    final double bDot0 = 1 + theta * (-15.0/2.0 + theta * (16.0 - 10.0 * theta));
+    final double bDot2 = theta * (459.0/16.0 + theta * (-729.0/8.0 + 135.0/2.0 * theta));
+    final double bDot3 = theta * (-44.0 + theta * (152.0 - 120.0 * theta));
+    final double bDot4 = theta * (375.0/16.0 + theta * (-625.0/8.0 + 125.0/2.0 * theta));
+    final double bDot5 = theta * 5.0/8.0 * (2 * theta - 1);
+
+    for (int i = 0; i < interpolatedState.length; ++i) {
+        final double yDot0 = yDotK[0][i];
+        final double yDot2 = yDotK[2][i];
+        final double yDot3 = yDotK[3][i];
+        final double yDot4 = yDotK[4][i];
+        final double yDot5 = yDotK[5][i];
+        interpolatedState[i] =
+            currentState[i] + b0 * yDot0 + b2 * yDot2 + b3 * yDot3 + b4 * yDot4 + b5 * yDot5;
+        interpolatedDerivatives[i] =
+            bDot0 * yDot0 + bDot2 * yDot2 + bDot3 * yDot3 + bDot4 * yDot4 + bDot5 * yDot5;
+    }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointIntegrator.java
new file mode 100644
index 0000000..89d1d87
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointIntegrator.java
@@ -0,0 +1,68 @@
+/*
+ * 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.ode.nonstiff;
+
+
+/**
+ * This class implements a second order Runge-Kutta integrator for
+ * Ordinary Differential Equations.
+ *
+ * <p>This method is an explicit Runge-Kutta method, its Butcher-array
+ * is the following one :
+ * <pre>
+ *    0  |  0    0
+ *   1/2 | 1/2   0
+ *       |----------
+ *       |  0    1
+ * </pre>
+ * </p>
+ *
+ * @see EulerIntegrator
+ * @see ClassicalRungeKuttaIntegrator
+ * @see GillIntegrator
+ *
+ * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $
+ * @since 1.2
+ */
+
+public class MidpointIntegrator extends RungeKuttaIntegrator {
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    1.0 / 2.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+    { 1.0 / 2.0 }
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    0.0, 1.0
+  };
+
+  /** Simple constructor.
+   * Build a midpoint integrator with the given step.
+   * @param step integration step
+   */
+  public MidpointIntegrator(final double step) {
+    super("midpoint", STATIC_C, STATIC_A, STATIC_B, new MidpointStepInterpolator(), step);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolator.java
new file mode 100644
index 0000000..094ba7a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/MidpointStepInterpolator.java
@@ -0,0 +1,100 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class implements a step interpolator for second order
+ * Runge-Kutta integrator.
+ *
+ * <p>This interpolator computes dense output inside the last
+ * step computed. The interpolation equation is consistent with the
+ * integration scheme :
+ *
+ * <pre>
+ *   y(t_n + theta h) = y (t_n + h) + (1-theta) h [theta y'_1 - (1+theta) y'_2]
+ * </pre>
+ *
+ * where theta belongs to [0 ; 1] and where y'_1 and y'_2 are the two
+ * evaluations of the derivatives already computed during the
+ * step.</p>
+ *
+ * @see MidpointIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class MidpointStepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -865524111506042509L;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link
+   * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize}
+   * method should be called before using the instance in order to
+   * initialize the internal arrays. This constructor is used only
+   * in order to delay the initialization in some cases. The {@link
+   * RungeKuttaIntegrator} class uses the prototyping design pattern
+   * to create the step interpolators by cloning an uninitialized model
+   * and later initializing the copy.
+   */
+  public MidpointStepInterpolator() {
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public MidpointStepInterpolator(final MidpointStepInterpolator interpolator) {
+    super(interpolator);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new MidpointStepInterpolator(this);
+  }
+
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+    throws DerivativeException {
+
+    final double coeff1    = oneMinusThetaH * theta;
+    final double coeff2    = oneMinusThetaH * (1.0 + theta);
+    final double coeffDot2 = 2 * theta;
+    final double coeffDot1 = 1 - coeffDot2;
+
+    for (int i = 0; i < interpolatedState.length; ++i) {
+      final double yDot1 = yDotK[0][i];
+      final double yDot2 = yDotK[1][i];
+      interpolatedState[i] = currentState[i] + coeff1 * yDot1 - coeff2 * yDot2;
+      interpolatedDerivatives[i] = coeffDot1 * yDot1 + coeffDot2 * yDot2;
+    }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
new file mode 100644
index 0000000..c550f90
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
@@ -0,0 +1,197 @@
+/*
+ * 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.ode.nonstiff;
+
+
+import org.apache.commons.math.ode.AbstractIntegrator;
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
+import org.apache.commons.math.ode.sampling.DummyStepInterpolator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements the common part of all fixed step Runge-Kutta
+ * integrators for Ordinary Differential Equations.
+ *
+ * <p>These methods are explicit Runge-Kutta methods, their Butcher
+ * arrays are as follows :
+ * <pre>
+ *    0  |
+ *   c2  | a21
+ *   c3  | a31  a32
+ *   ... |        ...
+ *   cs  | as1  as2  ...  ass-1
+ *       |--------------------------
+ *       |  b1   b2  ...   bs-1  bs
+ * </pre>
+ * </p>
+ *
+ * @see EulerIntegrator
+ * @see ClassicalRungeKuttaIntegrator
+ * @see GillIntegrator
+ * @see MidpointIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public abstract class RungeKuttaIntegrator extends AbstractIntegrator {
+
+    /** Time steps from Butcher array (without the first zero). */
+    private final double[] c;
+
+    /** Internal weights from Butcher array (without the first empty row). */
+    private final double[][] a;
+
+    /** External weights for the high order method from Butcher array. */
+    private final double[] b;
+
+    /** Prototype of the step interpolator. */
+    private final RungeKuttaStepInterpolator prototype;
+
+    /** Integration step. */
+    private final double step;
+
+  /** Simple constructor.
+   * Build a Runge-Kutta integrator with the given
+   * step. The default step handler does nothing.
+   * @param name name of the method
+   * @param c time steps from Butcher array (without the first zero)
+   * @param a internal weights from Butcher array (without the first empty row)
+   * @param b propagation weights for the high order method from Butcher array
+   * @param prototype prototype of the step interpolator to use
+   * @param step integration step
+   */
+  protected RungeKuttaIntegrator(final String name,
+                                 final double[] c, final double[][] a, final double[] b,
+                                 final RungeKuttaStepInterpolator prototype,
+                                 final double step) {
+    super(name);
+    this.c          = c;
+    this.a          = a;
+    this.b          = b;
+    this.prototype  = prototype;
+    this.step       = FastMath.abs(step);
+  }
+
+  /** {@inheritDoc} */
+  public double integrate(final FirstOrderDifferentialEquations equations,
+                          final double t0, final double[] y0,
+                          final double t, final double[] y)
+  throws DerivativeException, IntegratorException {
+
+    sanityChecks(equations, t0, y0, t, y);
+    setEquations(equations);
+    resetEvaluations();
+    final boolean forward = t > t0;
+
+    // create some internal working arrays
+    final int stages = c.length + 1;
+    if (y != y0) {
+      System.arraycopy(y0, 0, y, 0, y0.length);
+    }
+    final double[][] yDotK = new double[stages][];
+    for (int i = 0; i < stages; ++i) {
+      yDotK [i] = new double[y0.length];
+    }
+    final double[] yTmp    = new double[y0.length];
+    final double[] yDotTmp = new double[y0.length];
+
+    // set up an interpolator sharing the integrator arrays
+    AbstractStepInterpolator interpolator;
+    if (requiresDenseOutput()) {
+      final RungeKuttaStepInterpolator rki = (RungeKuttaStepInterpolator) prototype.copy();
+      rki.reinitialize(this, yTmp, yDotK, forward);
+      interpolator = rki;
+    } else {
+      interpolator = new DummyStepInterpolator(yTmp, yDotK[stages - 1], forward);
+    }
+    interpolator.storeTime(t0);
+
+    // set up integration control objects
+    stepStart = t0;
+    stepSize  = forward ? step : -step;
+    for (StepHandler handler : stepHandlers) {
+        handler.reset();
+    }
+    setStateInitialized(false);
+
+    // main integration loop
+    isLastStep = false;
+    do {
+
+      interpolator.shift();
+
+      // first stage
+      computeDerivatives(stepStart, y, yDotK[0]);
+
+      // next stages
+      for (int k = 1; k < stages; ++k) {
+
+          for (int j = 0; j < y0.length; ++j) {
+              double sum = a[k-1][0] * yDotK[0][j];
+              for (int l = 1; l < k; ++l) {
+                  sum += a[k-1][l] * yDotK[l][j];
+              }
+              yTmp[j] = y[j] + stepSize * sum;
+          }
+
+          computeDerivatives(stepStart + c[k-1] * stepSize, yTmp, yDotK[k]);
+
+      }
+
+      // estimate the state at the end of the step
+      for (int j = 0; j < y0.length; ++j) {
+          double sum    = b[0] * yDotK[0][j];
+          for (int l = 1; l < stages; ++l) {
+              sum    += b[l] * yDotK[l][j];
+          }
+          yTmp[j] = y[j] + stepSize * sum;
+      }
+
+      // discrete events handling
+      interpolator.storeTime(stepStart + stepSize);
+      System.arraycopy(yTmp, 0, y, 0, y0.length);
+      System.arraycopy(yDotK[stages - 1], 0, yDotTmp, 0, y0.length);
+      stepStart = acceptStep(interpolator, y, yDotTmp, t);
+
+      if (!isLastStep) {
+
+          // prepare next step
+          interpolator.storeTime(stepStart);
+
+          // stepsize control for next step
+          final double  nextT      = stepStart + stepSize;
+          final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t);
+          if (nextIsLast) {
+              stepSize = t - stepStart;
+          }
+      }
+
+    } while (!isLastStep);
+
+    final double stopTime = stepStart;
+    stepStart = Double.NaN;
+    stepSize  = Double.NaN;
+    return stopTime;
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaStepInterpolator.java
new file mode 100644
index 0000000..97d9fe7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/RungeKuttaStepInterpolator.java
@@ -0,0 +1,183 @@
+/*
+ * 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.ode.nonstiff;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.apache.commons.math.ode.AbstractIntegrator;
+import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
+
+/** This class represents an interpolator over the last step during an
+ * ODE integration for Runge-Kutta and embedded Runge-Kutta integrators.
+ *
+ * @see RungeKuttaIntegrator
+ * @see EmbeddedRungeKuttaIntegrator
+ *
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ */
+
+abstract class RungeKuttaStepInterpolator
+  extends AbstractStepInterpolator {
+
+    /** Slopes at the intermediate points */
+    protected double[][] yDotK;
+
+    /** Reference to the integrator. */
+    protected AbstractIntegrator integrator;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link #reinitialize} method should be called before using the
+   * instance in order to initialize the internal arrays. This
+   * constructor is used only in order to delay the initialization in
+   * some cases. The {@link RungeKuttaIntegrator} and {@link
+   * EmbeddedRungeKuttaIntegrator} classes use the prototyping design
+   * pattern to create the step interpolators by cloning an
+   * uninitialized model and latter initializing the copy.
+   */
+  protected RungeKuttaStepInterpolator() {
+    super();
+    yDotK      = null;
+    integrator = null;
+  }
+
+  /** Copy constructor.
+
+  * <p>The copied interpolator should have been finalized before the
+  * copy, otherwise the copy will not be able to perform correctly any
+  * interpolation and will throw a {@link NullPointerException}
+  * later. Since we don't want this constructor to throw the
+  * exceptions finalization may involve and since we don't want this
+  * method to modify the state of the copied interpolator,
+  * finalization is <strong>not</strong> done automatically, it
+  * remains under user control.</p>
+
+  * <p>The copy is a deep copy: its arrays are separated from the
+  * original arrays of the instance.</p>
+
+  * @param interpolator interpolator to copy from.
+
+  */
+  public RungeKuttaStepInterpolator(final RungeKuttaStepInterpolator interpolator) {
+
+    super(interpolator);
+
+    if (interpolator.currentState != null) {
+      final int dimension = currentState.length;
+
+      yDotK = new double[interpolator.yDotK.length][];
+      for (int k = 0; k < interpolator.yDotK.length; ++k) {
+        yDotK[k] = new double[dimension];
+        System.arraycopy(interpolator.yDotK[k], 0,
+                         yDotK[k], 0, dimension);
+      }
+
+    } else {
+      yDotK = null;
+    }
+
+    // we cannot keep any reference to the equations in the copy
+    // the interpolator should have been finalized before
+    integrator = null;
+
+  }
+
+  /** Reinitialize the instance
+   * <p>Some Runge-Kutta integrators need fewer functions evaluations
+   * than their counterpart step interpolators. So the interpolator
+   * should perform the last evaluations they need by themselves. The
+   * {@link RungeKuttaIntegrator RungeKuttaIntegrator} and {@link
+   * EmbeddedRungeKuttaIntegrator EmbeddedRungeKuttaIntegrator}
+   * abstract classes call this method in order to let the step
+   * interpolator perform the evaluations it needs. These evaluations
+   * will be performed during the call to <code>doFinalize</code> if
+   * any, i.e. only if the step handler either calls the {@link
+   * AbstractStepInterpolator#finalizeStep finalizeStep} method or the
+   * {@link AbstractStepInterpolator#getInterpolatedState
+   * getInterpolatedState} method (for an interpolator which needs a
+   * finalization) or if it clones the step interpolator.</p>
+   * @param rkIntegrator integrator being used
+   * @param y reference to the integrator array holding the state at
+   * the end of the step
+   * @param yDotArray reference to the integrator array holding all the
+   * intermediate slopes
+   * @param forward integration direction indicator
+   */
+  public void reinitialize(final AbstractIntegrator rkIntegrator,
+                           final double[] y, final double[][] yDotArray, final boolean forward) {
+    reinitialize(y, forward);
+    this.yDotK = yDotArray;
+    this.integrator = rkIntegrator;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void writeExternal(final ObjectOutput out)
+    throws IOException {
+
+    // save the state of the base class
+    writeBaseExternal(out);
+
+    // save the local attributes
+    final int n = (currentState == null) ? -1 : currentState.length;
+    final int kMax = (yDotK == null) ? -1 : yDotK.length;
+    out.writeInt(kMax);
+    for (int k = 0; k < kMax; ++k) {
+      for (int i = 0; i < n; ++i) {
+        out.writeDouble(yDotK[k][i]);
+      }
+    }
+
+    // we do not save any reference to the equations
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public void readExternal(final ObjectInput in)
+    throws IOException {
+
+    // read the base class
+    final double t = readBaseExternal(in);
+
+    // read the local attributes
+    final int n = (currentState == null) ? -1 : currentState.length;
+    final int kMax = in.readInt();
+    yDotK = (kMax < 0) ? null : new double[kMax][];
+    for (int k = 0; k < kMax; ++k) {
+      yDotK[k] = (n < 0) ? null : new double[n];
+      for (int i = 0; i < n; ++i) {
+        yDotK[k][i] = in.readDouble();
+      }
+    }
+
+    integrator = null;
+
+    if (currentState != null) {
+        // we can now set the interpolated time and state
+        setInterpolatedTime(t);
+    } else {
+        interpolatedTime = t;
+    }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.java
new file mode 100644
index 0000000..60c39d0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ode.nonstiff;
+
+
+/**
+ * This class implements the 3/8 fourth order Runge-Kutta
+ * integrator for Ordinary Differential Equations.
+ *
+ * <p>This method is an explicit Runge-Kutta method, its Butcher-array
+ * is the following one :
+ * <pre>
+ *    0  |  0    0    0    0
+ *   1/3 | 1/3   0    0    0
+ *   2/3 |-1/3   1    0    0
+ *    1  |  1   -1    1    0
+ *       |--------------------
+ *       | 1/8  3/8  3/8  1/8
+ * </pre>
+ * </p>
+ *
+ * @see EulerIntegrator
+ * @see ClassicalRungeKuttaIntegrator
+ * @see GillIntegrator
+ * @see MidpointIntegrator
+ * @version $Revision: 810196 $ $Date: 2009-09-01 21:47:46 +0200 (mar. 01 sept. 2009) $
+ * @since 1.2
+ */
+
+public class ThreeEighthesIntegrator extends RungeKuttaIntegrator {
+
+  /** Time steps Butcher array. */
+  private static final double[] STATIC_C = {
+    1.0 / 3.0, 2.0 / 3.0, 1.0
+  };
+
+  /** Internal weights Butcher array. */
+  private static final double[][] STATIC_A = {
+    {  1.0 / 3.0 },
+    { -1.0 / 3.0, 1.0 },
+    {  1.0, -1.0, 1.0 }
+  };
+
+  /** Propagation weights Butcher array. */
+  private static final double[] STATIC_B = {
+    1.0 / 8.0, 3.0 / 8.0, 3.0 / 8.0, 1.0 / 8.0
+  };
+
+  /** Simple constructor.
+   * Build a 3/8 integrator with the given step.
+   * @param step integration step
+   */
+  public ThreeEighthesIntegrator(final double step) {
+    super("3/8", STATIC_C, STATIC_A, STATIC_B, new ThreeEighthesStepInterpolator(), step);
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolator.java
new file mode 100644
index 0000000..19d5693
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/ThreeEighthesStepInterpolator.java
@@ -0,0 +1,116 @@
+/*
+ * 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.ode.nonstiff;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
+
+/**
+ * This class implements a step interpolator for the 3/8 fourth
+ * order Runge-Kutta integrator.
+ *
+ * <p>This interpolator allows to compute dense output inside the last
+ * step computed. The interpolation equation is consistent with the
+ * integration scheme :
+ *
+ * <pre>
+ *   y(t_n + theta h) = y (t_n + h)
+ *                    - (1 - theta) (h/8) [ (1 - 7 theta + 8 theta^2) y'_1
+ *                                      + 3 (1 +   theta - 4 theta^2) y'_2
+ *                                      + 3 (1 +   theta)             y'_3
+ *                                      +   (1 +   theta + 4 theta^2) y'_4
+ *                                        ]
+ * </pre>
+ *
+ * where theta belongs to [0 ; 1] and where y'_1 to y'_4 are the four
+ * evaluations of the derivatives already computed during the
+ * step.</p>
+ *
+ * @see ThreeEighthesIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+class ThreeEighthesStepInterpolator
+  extends RungeKuttaStepInterpolator {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3345024435978721931L;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link
+   * org.apache.commons.math.ode.sampling.AbstractStepInterpolator#reinitialize}
+   * method should be called before using the instance in order to
+   * initialize the internal arrays. This constructor is used only
+   * in order to delay the initialization in some cases. The {@link
+   * RungeKuttaIntegrator} class uses the prototyping design pattern
+   * to create the step interpolators by cloning an uninitialized model
+   * and later initializing the copy.
+   */
+  public ThreeEighthesStepInterpolator() {
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public ThreeEighthesStepInterpolator(final ThreeEighthesStepInterpolator interpolator) {
+    super(interpolator);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new ThreeEighthesStepInterpolator(this);
+  }
+
+
+  /** {@inheritDoc} */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta,
+                                          final double oneMinusThetaH)
+      throws DerivativeException {
+
+      final double fourTheta2 = 4 * theta * theta;
+      final double s          = oneMinusThetaH / 8.0;
+      final double coeff1     = s * (1 - 7 * theta + 2 * fourTheta2);
+      final double coeff2     = 3 * s * (1 + theta - fourTheta2);
+      final double coeff3     = 3 * s * (1 + theta);
+      final double coeff4     = s * (1 + theta + fourTheta2);
+      final double coeffDot3  = 0.75 * theta;
+      final double coeffDot1  = coeffDot3 * (4 * theta - 5) + 1;
+      final double coeffDot2  = coeffDot3 * (5 - 6 * theta);
+      final double coeffDot4  = coeffDot3 * (2 * theta - 1);
+
+      for (int i = 0; i < interpolatedState.length; ++i) {
+          final double yDot1 = yDotK[0][i];
+          final double yDot2 = yDotK[1][i];
+          final double yDot3 = yDotK[2][i];
+          final double yDot4 = yDotK[3][i];
+          interpolatedState[i] =
+              currentState[i] - coeff1 * yDot1 - coeff2 * yDot2 - coeff3 * yDot3 - coeff4 * yDot4;
+          interpolatedDerivatives[i] =
+              coeffDot1 * yDot1 + coeffDot2 * yDot2 + coeffDot3 * yDot3 + coeffDot4 * yDot4;
+
+      }
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/nonstiff/package.html b/src/main/java/org/apache/commons/math/ode/nonstiff/package.html
new file mode 100644
index 0000000..3e68e82
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/nonstiff/package.html
@@ -0,0 +1,25 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 613620 $ -->
+<body>
+<p>
+This package provides classes to solve non-stiff Ordinary Differential Equations problems.
+</p>
+
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/ode/package.html b/src/main/java/org/apache/commons/math/ode/package.html
new file mode 100644
index 0000000..d390204
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/package.html
@@ -0,0 +1,167 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 920131 $ -->
+<body>
+<p>
+This package provides classes to solve Ordinary Differential Equations problems.
+</p>
+
+<p>
+This package solves Initial Value Problems of the form
+<code>y'=f(t,y)</code> with <code>t<sub>0</sub></code> and
+<code>y(t<sub>0</sub>)=y<sub>0</sub></code> known. The provided
+integrators compute an estimate of <code>y(t)</code> from
+<code>t=t<sub>0</sub></code> to <code>t=t<sub>1</sub></code>.
+If in addition to <code>y(t)</code> users need to get the
+derivatives with respect to the initial state
+<code>dy(t)/dy(t<sub>0</sub>)</code> or the derivatives with
+respect to some ODE parameters <code>dy(t)/dp</code>, then the
+classes from the <a href="./jacobians/package-summary.html">
+org.apache.commons.math.ode.jacobians</a> package must be used
+instead of the classes in this package.
+</p>
+
+<p>
+All integrators provide dense output. This means that besides
+computing the state vector at discrete times, they also provide a
+cheap mean to get the state between the time steps. They do so through
+classes extending the {@link
+org.apache.commons.math.ode.sampling.StepInterpolator StepInterpolator}
+abstract class, which are made available to the user at the end of
+each step.
+</p>
+
+<p>
+All integrators handle multiple discrete events detection based on switching
+functions. This means that the integrator can be driven by user specified
+discrete events. The steps are shortened as needed to ensure the events occur
+at step boundaries (even if the integrator is a fixed-step
+integrator). When the events are triggered, integration can be stopped
+(this is called a G-stop facility), the state vector can be changed,
+or integration can simply go on. The latter case is useful to handle
+discontinuities in the differential equations gracefully and get
+accurate dense output even close to the discontinuity.
+</p>
+
+<p>
+The user should describe his problem in his own classes
+(<code>UserProblem</code> in the diagram below) which should implement
+the {@link org.apache.commons.math.ode.FirstOrderDifferentialEquations
+FirstOrderDifferentialEquations} interface. Then he should pass it to
+the integrator he prefers among all the classes that implement the
+{@link org.apache.commons.math.ode.FirstOrderIntegrator
+FirstOrderIntegrator} interface.
+</p>
+
+<p>
+The solution of the integration problem is provided by two means. The
+first one is aimed towards simple use: the state vector at the end of
+the integration process is copied in the <code>y</code> array of the
+{@link org.apache.commons.math.ode.FirstOrderIntegrator#integrate
+FirstOrderIntegrator.integrate} method. The second one should be used
+when more in-depth information is needed throughout the integration
+process. The user can register an object implementing the {@link
+org.apache.commons.math.ode.sampling.StepHandler StepHandler} interface or a
+{@link org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer}
+object wrapping a user-specified object implementing the {@link
+org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler}
+interface into the integrator before calling the {@link
+org.apache.commons.math.ode.FirstOrderIntegrator#integrate
+FirstOrderIntegrator.integrate} method. The user object will be called
+appropriately during the integration process, allowing the user to
+process intermediate results. The default step handler does nothing.
+</p>
+
+<p>
+{@link org.apache.commons.math.ode.ContinuousOutputModel
+ContinuousOutputModel} is a special-purpose step handler that is able
+to store all steps and to provide transparent access to any
+intermediate result once the integration is over. An important feature
+of this class is that it implements the <code>Serializable</code>
+interface. This means that a complete continuous model of the
+integrated function throughout the integration range can be serialized
+and reused later (if stored into a persistent medium like a filesystem
+or a database) or elsewhere (if sent to another application). Only the
+result of the integration is stored, there is no reference to the
+integrated problem by itself.
+</p>
+
+<p>
+Other default implementations of the {@link
+org.apache.commons.math.ode.sampling.StepHandler StepHandler} interface are
+available for general needs ({@link
+org.apache.commons.math.ode.sampling.DummyStepHandler DummyStepHandler}, {@link
+org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer}) and custom
+implementations can be developed for specific needs. As an example,
+if an application is to be completely driven by the integration
+process, then most of the application code will be run inside a step
+handler specific to this application.
+</p>
+
+<p>
+Some integrators (the simple ones) use fixed steps that are set at
+creation time. The more efficient integrators use variable steps that
+are handled internally in order to control the integration error with
+respect to a specified accuracy (these integrators extend the {@link
+org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator
+AdaptiveStepsizeIntegrator} abstract class). In this case, the step
+handler which is called after each successful step shows up the
+variable stepsize. The {@link
+org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} class can
+be used to convert the variable stepsize into a fixed stepsize that
+can be handled by classes implementing the {@link
+org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler}
+interface. Adaptive stepsize integrators can automatically compute the
+initial stepsize by themselves, however the user can specify it if he
+prefers to retain full control over the integration or if the
+automatic guess is wrong.
+</p>
+
+<p>
+<table border="1" align="center">
+<tr BGCOLOR="#CCCCFF"><td colspan=2><font size="+2">Fixed Step Integrators</font></td></tr>
+<tr BGCOLOR="#EEEEFF"><font size="+1"><td>Name</td><td>Order</td></font></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.EulerIntegrator Euler}</td><td>1</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.MidpointIntegrator Midpoint}</td><td>2</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.ClassicalRungeKuttaIntegrator Classical Runge-Kutta}</td><td>4</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.GillIntegrator Gill}</td><td>4</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.ThreeEighthesIntegrator 3/8}</td><td>4</td></tr>
+</table>
+</p>
+
+<table border="1" align="center">
+<tr BGCOLOR="#CCCCFF"><td colspan=3><font size="+2">Adaptive Stepsize Integrators</font></td></tr>
+<tr BGCOLOR="#EEEEFF"><font size="+1"><td>Name</td><td>Integration Order</td><td>Error Estimation Order</td></font></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.HighamHall54Integrator Higham and Hall}</td><td>5</td><td>4</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.DormandPrince54Integrator Dormand-Prince 5(4)}</td><td>5</td><td>4</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator Dormand-Prince 8(5,3)}</td><td>8</td><td>5 and 3</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.GraggBulirschStoerIntegrator Gragg-Bulirsch-Stoer}</td><td>variable (up to 18 by default)</td><td>variable</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator Adams-Bashforth}</td><td>variable</td><td>variable</td></tr>
+<tr><td>{@link org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator Adams-Moulton}</td><td>variable</td><td>variable</td></tr>
+</table>
+</p>
+
+<p>
+In the table above, the {@link org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator
+Adams-Bashforth} and {@link org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator
+Adams-Moulton} integrators appear as variable-step ones. This is an experimental extension
+to the classical algorithms using the Nordsieck vector representation.
+</p>
+
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.java
new file mode 100644
index 0000000..5cb2979
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.java
@@ -0,0 +1,519 @@
+/*
+ * 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.ode.sampling;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/** This abstract class represents an interpolator over the last step
+ * during an ODE integration.
+ *
+ * <p>The various ODE integrators provide objects extending this class
+ * to the step handlers. The handlers can use these objects to
+ * retrieve the state vector at intermediate times between the
+ * previous and the current grid points (dense output).</p>
+ *
+ * @see org.apache.commons.math.ode.FirstOrderIntegrator
+ * @see org.apache.commons.math.ode.SecondOrderIntegrator
+ * @see StepHandler
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ *
+ */
+
+public abstract class AbstractStepInterpolator
+  implements StepInterpolator {
+
+  /** current time step */
+  protected double h;
+
+  /** current state */
+  protected double[] currentState;
+
+  /** interpolated time */
+  protected double interpolatedTime;
+
+  /** interpolated state */
+  protected double[] interpolatedState;
+
+  /** interpolated derivatives */
+  protected double[] interpolatedDerivatives;
+
+  /** global previous time */
+  private double globalPreviousTime;
+
+  /** global current time */
+  private double globalCurrentTime;
+
+  /** soft previous time */
+  private double softPreviousTime;
+
+  /** soft current time */
+  private double softCurrentTime;
+
+  /** indicate if the step has been finalized or not. */
+  private boolean finalized;
+
+  /** integration direction. */
+  private boolean forward;
+
+  /** indicator for dirty state. */
+  private boolean dirtyState;
+
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * {@link #reinitialize} method should be called before using the
+   * instance in order to initialize the internal arrays. This
+   * constructor is used only in order to delay the initialization in
+   * some cases. As an example, the {@link
+   * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator}
+   * class uses the prototyping design pattern to create the step
+   * interpolators by cloning an uninitialized model and latter
+   * initializing the copy.
+   */
+  protected AbstractStepInterpolator() {
+    globalPreviousTime      = Double.NaN;
+    globalCurrentTime       = Double.NaN;
+    softPreviousTime        = Double.NaN;
+    softCurrentTime         = Double.NaN;
+    h                       = Double.NaN;
+    interpolatedTime        = Double.NaN;
+    currentState            = null;
+    interpolatedState       = null;
+    interpolatedDerivatives = null;
+    finalized               = false;
+    this.forward            = true;
+    this.dirtyState         = true;
+  }
+
+  /** Simple constructor.
+   * @param y reference to the integrator array holding the state at
+   * the end of the step
+   * @param forward integration direction indicator
+   */
+  protected AbstractStepInterpolator(final double[] y, final boolean forward) {
+
+    globalPreviousTime = Double.NaN;
+    globalCurrentTime  = Double.NaN;
+    softPreviousTime   = Double.NaN;
+    softCurrentTime    = Double.NaN;
+    h                  = Double.NaN;
+    interpolatedTime   = Double.NaN;
+
+    currentState            = y;
+    interpolatedState       = new double[y.length];
+    interpolatedDerivatives = new double[y.length];
+
+    finalized         = false;
+    this.forward      = forward;
+    this.dirtyState   = true;
+
+  }
+
+  /** Copy constructor.
+
+   * <p>The copied interpolator should have been finalized before the
+   * copy, otherwise the copy will not be able to perform correctly
+   * any derivative computation and will throw a {@link
+   * NullPointerException} later. Since we don't want this constructor
+   * to throw the exceptions finalization may involve and since we
+   * don't want this method to modify the state of the copied
+   * interpolator, finalization is <strong>not</strong> done
+   * automatically, it remains under user control.</p>
+   *
+   * <p>The copy is a deep copy: its arrays are separated from the
+   * original arrays of the instance.</p>
+   *
+   * @param interpolator interpolator to copy from.
+   *
+   */
+  protected AbstractStepInterpolator(final AbstractStepInterpolator interpolator) {
+
+    globalPreviousTime = interpolator.globalPreviousTime;
+    globalCurrentTime  = interpolator.globalCurrentTime;
+    softPreviousTime   = interpolator.softPreviousTime;
+    softCurrentTime    = interpolator.softCurrentTime;
+    h                  = interpolator.h;
+    interpolatedTime   = interpolator.interpolatedTime;
+
+    if (interpolator.currentState != null) {
+      currentState            = interpolator.currentState.clone();
+      interpolatedState       = interpolator.interpolatedState.clone();
+      interpolatedDerivatives = interpolator.interpolatedDerivatives.clone();
+    } else {
+      currentState            = null;
+      interpolatedState       = null;
+      interpolatedDerivatives = null;
+    }
+
+    finalized  = interpolator.finalized;
+    forward    = interpolator.forward;
+    dirtyState = interpolator.dirtyState;
+
+  }
+
+  /** Reinitialize the instance
+   * @param y reference to the integrator array holding the state at
+   * the end of the step
+   * @param isForward integration direction indicator
+   */
+  protected void reinitialize(final double[] y, final boolean isForward) {
+
+    globalPreviousTime = Double.NaN;
+    globalCurrentTime  = Double.NaN;
+    softPreviousTime   = Double.NaN;
+    softCurrentTime    = Double.NaN;
+    h                  = Double.NaN;
+    interpolatedTime   = Double.NaN;
+
+    currentState            = y;
+    interpolatedState       = new double[y.length];
+    interpolatedDerivatives = new double[y.length];
+
+    finalized         = false;
+    this.forward      = isForward;
+    this.dirtyState   = true;
+
+  }
+
+  /** {@inheritDoc} */
+   public StepInterpolator copy() throws DerivativeException {
+
+     // finalize the step before performing copy
+     finalizeStep();
+
+     // create the new independent instance
+     return doCopy();
+
+   }
+
+   /** Really copy the finalized instance.
+    * <p>This method is called by {@link #copy()} after the
+    * step has been finalized. It must perform a deep copy
+    * to have an new instance completely independent for the
+    * original instance.
+    * @return a copy of the finalized instance
+    */
+   protected abstract StepInterpolator doCopy();
+
+  /** Shift one step forward.
+   * Copy the current time into the previous time, hence preparing the
+   * interpolator for future calls to {@link #storeTime storeTime}
+   */
+  public void shift() {
+    globalPreviousTime = globalCurrentTime;
+    softPreviousTime   = globalPreviousTime;
+    softCurrentTime    = globalCurrentTime;
+  }
+
+  /** Store the current step time.
+   * @param t current time
+   */
+  public void storeTime(final double t) {
+
+    globalCurrentTime = t;
+    softCurrentTime   = globalCurrentTime;
+    h                 = globalCurrentTime - globalPreviousTime;
+    setInterpolatedTime(t);
+
+    // the step is not finalized anymore
+    finalized  = false;
+
+  }
+
+  /** Restrict step range to a limited part of the global step.
+   * <p>
+   * This method can be used to restrict a step and make it appear
+   * as if the original step was smaller. Calling this method
+   * <em>only</em> changes the value returned by {@link #getPreviousTime()},
+   * it does not change any other property
+   * </p>
+   * @param softPreviousTime start of the restricted step
+   * @since 2.2
+   */
+  public void setSoftPreviousTime(final double softPreviousTime) {
+      this.softPreviousTime = softPreviousTime;
+  }
+
+  /** Restrict step range to a limited part of the global step.
+   * <p>
+   * This method can be used to restrict a step and make it appear
+   * as if the original step was smaller. Calling this method
+   * <em>only</em> changes the value returned by {@link #getCurrentTime()},
+   * it does not change any other property
+   * </p>
+   * @param softCurrentTime end of the restricted step
+   * @since 2.2
+   */
+  public void setSoftCurrentTime(final double softCurrentTime) {
+      this.softCurrentTime  = softCurrentTime;
+  }
+
+  /**
+   * Get the previous global grid point time.
+   * @return previous global grid point time
+   * @since 2.2
+   */
+  public double getGlobalPreviousTime() {
+    return globalPreviousTime;
+  }
+
+  /**
+   * Get the current global grid point time.
+   * @return current global grid point time
+   * @since 2.2
+   */
+  public double getGlobalCurrentTime() {
+    return globalCurrentTime;
+  }
+
+  /**
+   * Get the previous soft grid point time.
+   * @return previous soft grid point time
+   * @see #setSoftPreviousTime(double)
+   */
+  public double getPreviousTime() {
+    return softPreviousTime;
+  }
+
+  /**
+   * Get the current soft grid point time.
+   * @return current soft grid point time
+   * @see #setSoftCurrentTime(double)
+   */
+  public double getCurrentTime() {
+    return softCurrentTime;
+  }
+
+  /** {@inheritDoc} */
+  public double getInterpolatedTime() {
+    return interpolatedTime;
+  }
+
+  /** {@inheritDoc} */
+  public void setInterpolatedTime(final double time) {
+      interpolatedTime = time;
+      dirtyState       = true;
+  }
+
+  /** {@inheritDoc} */
+  public boolean isForward() {
+    return forward;
+  }
+
+  /** Compute the state and derivatives at the interpolated time.
+   * This is the main processing method that should be implemented by
+   * the derived classes to perform the interpolation.
+   * @param theta normalized interpolation abscissa within the step
+   * (theta is zero at the previous time step and one at the current time step)
+   * @param oneMinusThetaH time gap between the interpolated time and
+   * the current time
+   * @throws DerivativeException this exception is propagated to the caller if the
+   * underlying user function triggers one
+   */
+  protected abstract void computeInterpolatedStateAndDerivatives(double theta,
+                                                                 double oneMinusThetaH)
+    throws DerivativeException;
+
+  /** {@inheritDoc} */
+  public double[] getInterpolatedState() throws DerivativeException {
+
+      // lazy evaluation of the state
+      if (dirtyState) {
+          final double oneMinusThetaH = globalCurrentTime - interpolatedTime;
+          final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h;
+          computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH);
+          dirtyState = false;
+      }
+
+      return interpolatedState;
+
+  }
+
+  /** {@inheritDoc} */
+  public double[] getInterpolatedDerivatives() throws DerivativeException {
+
+      // lazy evaluation of the state
+      if (dirtyState) {
+          final double oneMinusThetaH = globalCurrentTime - interpolatedTime;
+          final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h;
+          computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH);
+          dirtyState = false;
+      }
+
+      return interpolatedDerivatives;
+
+  }
+
+  /**
+   * Finalize the step.
+   *
+   * <p>Some embedded Runge-Kutta integrators need fewer functions
+   * evaluations than their counterpart step interpolators. These
+   * interpolators should perform the last evaluations they need by
+   * themselves only if they need them. This method triggers these
+   * extra evaluations. It can be called directly by the user step
+   * handler and it is called automatically if {@link
+   * #setInterpolatedTime} is called.</p>
+   *
+   * <p>Once this method has been called, <strong>no</strong> other
+   * evaluation will be performed on this step. If there is a need to
+   * have some side effects between the step handler and the
+   * differential equations (for example update some data in the
+   * equations once the step has been done), it is advised to call
+   * this method explicitly from the step handler before these side
+   * effects are set up. If the step handler induces no side effect,
+   * then this method can safely be ignored, it will be called
+   * transparently as needed.</p>
+   *
+   * <p><strong>Warning</strong>: since the step interpolator provided
+   * to the step handler as a parameter of the {@link
+   * StepHandler#handleStep handleStep} is valid only for the duration
+   * of the {@link StepHandler#handleStep handleStep} call, one cannot
+   * simply store a reference and reuse it later. One should first
+   * finalize the instance, then copy this finalized instance into a
+   * new object that can be kept.</p>
+   *
+   * <p>This method calls the protected <code>doFinalize</code> method
+   * if it has never been called during this step and set a flag
+   * indicating that it has been called once. It is the <code>
+   * doFinalize</code> method which should perform the evaluations.
+   * This wrapping prevents from calling <code>doFinalize</code> several
+   * times and hence evaluating the differential equations too often.
+   * Therefore, subclasses are not allowed not reimplement it, they
+   * should rather reimplement <code>doFinalize</code>.</p>
+   *
+   * @throws DerivativeException this exception is propagated to the
+   * caller if the underlying user function triggers one
+   */
+  public final void finalizeStep()
+    throws DerivativeException {
+    if (! finalized) {
+      doFinalize();
+      finalized = true;
+    }
+  }
+
+  /**
+   * Really finalize the step.
+   * The default implementation of this method does nothing.
+   * @throws DerivativeException this exception is propagated to the
+   * caller if the underlying user function triggers one
+   */
+  protected void doFinalize()
+    throws DerivativeException {
+  }
+
+  /** {@inheritDoc} */
+  public abstract void writeExternal(ObjectOutput out)
+    throws IOException;
+
+  /** {@inheritDoc} */
+  public abstract void readExternal(ObjectInput in)
+    throws IOException, ClassNotFoundException;
+
+  /** Save the base state of the instance.
+   * This method performs step finalization if it has not been done
+   * before.
+   * @param out stream where to save the state
+   * @exception IOException in case of write error
+   */
+  protected void writeBaseExternal(final ObjectOutput out)
+    throws IOException {
+
+    if (currentState == null) {
+        out.writeInt(-1);
+    } else {
+        out.writeInt(currentState.length);
+    }
+    out.writeDouble(globalPreviousTime);
+    out.writeDouble(globalCurrentTime);
+    out.writeDouble(softPreviousTime);
+    out.writeDouble(softCurrentTime);
+    out.writeDouble(h);
+    out.writeBoolean(forward);
+
+    if (currentState != null) {
+        for (int i = 0; i < currentState.length; ++i) {
+            out.writeDouble(currentState[i]);
+        }
+    }
+
+    out.writeDouble(interpolatedTime);
+
+    // we do not store the interpolated state,
+    // it will be recomputed as needed after reading
+
+    // finalize the step (and don't bother saving the now true flag)
+    try {
+      finalizeStep();
+    } catch (DerivativeException e) {
+        IOException ioe = new IOException(e.getLocalizedMessage());
+        ioe.initCause(e);
+        throw ioe;
+    }
+
+  }
+
+  /** Read the base state of the instance.
+   * This method does <strong>neither</strong> set the interpolated
+   * time nor state. It is up to the derived class to reset it
+   * properly calling the {@link #setInterpolatedTime} method later,
+   * once all rest of the object state has been set up properly.
+   * @param in stream where to read the state from
+   * @return interpolated time be set later by the caller
+   * @exception IOException in case of read error
+   */
+  protected double readBaseExternal(final ObjectInput in)
+    throws IOException {
+
+    final int dimension = in.readInt();
+    globalPreviousTime  = in.readDouble();
+    globalCurrentTime   = in.readDouble();
+    softPreviousTime    = in.readDouble();
+    softCurrentTime     = in.readDouble();
+    h                   = in.readDouble();
+    forward             = in.readBoolean();
+    dirtyState          = true;
+
+    if (dimension < 0) {
+        currentState = null;
+    } else {
+        currentState  = new double[dimension];
+        for (int i = 0; i < currentState.length; ++i) {
+            currentState[i] = in.readDouble();
+        }
+    }
+
+    // we do NOT handle the interpolated time and state here
+    interpolatedTime        = Double.NaN;
+    interpolatedState       = (dimension < 0) ? null : new double[dimension];
+    interpolatedDerivatives = (dimension < 0) ? null : new double[dimension];
+
+    finalized = true;
+
+    return in.readDouble();
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/DummyStepHandler.java b/src/main/java/org/apache/commons/math/ode/sampling/DummyStepHandler.java
new file mode 100644
index 0000000..cc759b9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/DummyStepHandler.java
@@ -0,0 +1,101 @@
+/*
+ * 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.ode.sampling;
+
+/**
+ * This class is a step handler that does nothing.
+
+ * <p>This class is provided as a convenience for users who are only
+ * interested in the final state of an integration and not in the
+ * intermediate steps. Its handleStep method does nothing.</p>
+ *
+ * <p>Since this class has no internal state, it is implemented using
+ * the Singleton design pattern. This means that only one instance is
+ * ever created, which can be retrieved using the getInstance
+ * method. This explains why there is no public constructor.</p>
+ *
+ * @see StepHandler
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ */
+
+public class DummyStepHandler implements StepHandler {
+
+    /** Private constructor.
+     * The constructor is private to prevent users from creating
+     * instances (Singleton design-pattern).
+     */
+    private DummyStepHandler() {
+    }
+
+    /** Get the only instance.
+     * @return the only instance
+     */
+    public static DummyStepHandler getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    /** Determines whether this handler needs dense output.
+     * Since this handler does nothing, it does not require dense output.
+     * @return always false
+     */
+    public boolean requiresDenseOutput() {
+        return false;
+    }
+
+    /** Reset the step handler.
+     * Initialize the internal data as required before the first step is
+     * handled.
+     */
+    public void reset() {
+    }
+
+    /**
+     * Handle the last accepted step.
+     * This method does nothing in this class.
+     * @param interpolator interpolator for the last accepted step. For
+     * efficiency purposes, the various integrators reuse the same
+     * object on each call, so if the instance wants to keep it across
+     * all calls (for example to provide at the end of the integration a
+     * continuous model valid throughout the integration range), it
+     * should build a local copy using the clone method and store this
+     * copy.
+     * @param isLast true if the step is the last one
+     */
+    public void handleStep(final StepInterpolator interpolator, final boolean isLast) {
+    }
+
+    // CHECKSTYLE: stop HideUtilityClassConstructor
+    /** Holder for the instance.
+     * <p>We use here the Initialization On Demand Holder Idiom.</p>
+     */
+    private static class LazyHolder {
+        /** Cached field instance. */
+        private static final DummyStepHandler INSTANCE = new DummyStepHandler();
+    }
+    // CHECKSTYLE: resume HideUtilityClassConstructor
+
+    /** Handle deserialization of the singleton.
+     * @return the singleton instance
+     */
+    private Object readResolve() {
+        // return the singleton instance
+        return LazyHolder.INSTANCE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/DummyStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/sampling/DummyStepInterpolator.java
new file mode 100644
index 0000000..af28c13
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/DummyStepInterpolator.java
@@ -0,0 +1,150 @@
+/*
+ * 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.ode.sampling;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+/** This class is a step interpolator that does nothing.
+ *
+ * <p>This class is used when the {@link StepHandler "step handler"}
+ * set up by the user does not need step interpolation. It does not
+ * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime
+ * setInterpolatedTime} is called. This implies the interpolated state
+ * is always the state at the end of the current step.</p>
+ *
+ * @see StepHandler
+ *
+ * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
+ * @since 1.2
+ */
+
+public class DummyStepInterpolator
+  extends AbstractStepInterpolator {
+
+  /** Serializable version identifier. */
+  private static final long serialVersionUID = 1708010296707839488L;
+
+  /** Current derivative. */
+  private double[] currentDerivative;
+
+  /** Simple constructor.
+   * This constructor builds an instance that is not usable yet, the
+   * <code>AbstractStepInterpolator.reinitialize</code> protected method
+   * should be called before using the instance in order to initialize
+   * the internal arrays. This constructor is used only in order to delay
+   * the initialization in some cases. As an example, the {@link
+   * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses
+   * the prototyping design pattern to create the step interpolators by
+   * cloning an uninitialized model and latter initializing the copy.
+   */
+  public DummyStepInterpolator() {
+    super();
+    currentDerivative = null;
+  }
+
+  /** Simple constructor.
+   * @param y reference to the integrator array holding the state at
+   * the end of the step
+   * @param yDot reference to the integrator array holding the state
+   * derivative at some arbitrary point within the step
+   * @param forward integration direction indicator
+   */
+  public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) {
+    super(y, forward);
+    currentDerivative = yDot;
+  }
+
+  /** Copy constructor.
+   * @param interpolator interpolator to copy from. The copy is a deep
+   * copy: its arrays are separated from the original arrays of the
+   * instance
+   */
+  public DummyStepInterpolator(final DummyStepInterpolator interpolator) {
+    super(interpolator);
+    currentDerivative = interpolator.currentDerivative.clone();
+  }
+
+  /** Really copy the finalized instance.
+   * @return a copy of the finalized instance
+   */
+  @Override
+  protected StepInterpolator doCopy() {
+    return new DummyStepInterpolator(this);
+  }
+
+  /** Compute the state at the interpolated time.
+   * In this class, this method does nothing: the interpolated state
+   * is always the state at the end of the current step.
+   * @param theta normalized interpolation abscissa within the step
+   * (theta is zero at the previous time step and one at the current time step)
+   * @param oneMinusThetaH time gap between the interpolated time and
+   * the current time
+   */
+  @Override
+  protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) {
+      System.arraycopy(currentState,      0, interpolatedState,       0, currentState.length);
+      System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length);
+  }
+
+  /** Write the instance to an output channel.
+   * @param out output channel
+   * @exception IOException if the instance cannot be written
+   */
+  @Override
+  public void writeExternal(final ObjectOutput out)
+    throws IOException {
+
+      // save the state of the base class
+    writeBaseExternal(out);
+
+    if (currentDerivative != null) {
+        for (int i = 0; i < currentDerivative.length; ++i) {
+            out.writeDouble(currentDerivative[i]);
+        }
+    }
+
+  }
+
+  /** Read the instance from an input channel.
+   * @param in input channel
+   * @exception IOException if the instance cannot be read
+   */
+  @Override
+  public void readExternal(final ObjectInput in)
+    throws IOException {
+
+    // read the base class
+    final double t = readBaseExternal(in);
+
+    if (currentState == null) {
+        currentDerivative = null;
+    } else {
+        currentDerivative  = new double[currentState.length];
+        for (int i = 0; i < currentDerivative.length; ++i) {
+            currentDerivative[i] = in.readDouble();
+        }
+    }
+
+    // we can now set the interpolated time and state
+    setInterpolatedTime(t);
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/FixedStepHandler.java b/src/main/java/org/apache/commons/math/ode/sampling/FixedStepHandler.java
new file mode 100644
index 0000000..190c999
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/FixedStepHandler.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ode.sampling;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/**
+ * This interface represents a handler that should be called after
+ * each successful fixed step.
+
+ * <p>This interface should be implemented by anyone who is interested
+ * in getting the solution of an ordinary differential equation at
+ * fixed time steps. Objects implementing this interface should be
+ * wrapped within an instance of {@link StepNormalizer} that itself
+ * is used as the general {@link StepHandler} by the integrator. The
+ * {@link StepNormalizer} object is called according to the integrator
+ * internal algorithms and it calls objects implementing this
+ * interface as necessary at fixed time steps.</p>
+ *
+ * @see StepHandler
+ * @see StepNormalizer
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface FixedStepHandler  {
+
+  /**
+   * Handle the last accepted step
+   * @param t time of the current step
+   * @param y state vector at t. For efficiency purposes, the {@link
+   * StepNormalizer} class reuses the same array on each call, so if
+   * the instance wants to keep it across all calls (for example to
+   * provide at the end of the integration a complete array of all
+   * steps), it should build a local copy store this copy.
+   * @param yDot derivatives of the state vector state vector at t.
+   * For efficiency purposes, the {@link StepNormalizer} class reuses
+   * the same array on each call, so if
+   * the instance wants to keep it across all calls (for example to
+   * provide at the end of the integration a complete array of all
+   * steps), it should build a local copy store this copy.
+   * @param isLast true if the step is the last one
+   * @throws DerivativeException if some error condition is encountered
+   */
+  void handleStep(double t, double[] y, double[] yDot, boolean isLast) throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java b/src/main/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java
new file mode 100644
index 0000000..2090276
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java
@@ -0,0 +1,291 @@
+/*
+ * 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.ode.sampling;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements an interpolator for integrators using Nordsieck representation.
+ *
+ * <p>This interpolator computes dense output around the current point.
+ * The interpolation equation is based on Taylor series formulas.
+ *
+ * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator
+ * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+
+public class NordsieckStepInterpolator extends AbstractStepInterpolator {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -7179861704951334960L;
+
+    /** State variation. */
+    protected double[] stateVariation;
+
+    /** Step size used in the first scaled derivative and Nordsieck vector. */
+    private double scalingH;
+
+    /** Reference time for all arrays.
+     * <p>Sometimes, the reference time is the same as previousTime,
+     * sometimes it is the same as currentTime, so we use a separate
+     * field to avoid any confusion.
+     * </p>
+     */
+    private double referenceTime;
+
+    /** First scaled derivative. */
+    private double[] scaled;
+
+    /** Nordsieck vector. */
+    private Array2DRowRealMatrix nordsieck;
+
+    /** Simple constructor.
+     * This constructor builds an instance that is not usable yet, the
+     * {@link AbstractStepInterpolator#reinitialize} method should be called
+     * before using the instance in order to initialize the internal arrays. This
+     * constructor is used only in order to delay the initialization in
+     * some cases.
+     */
+    public NordsieckStepInterpolator() {
+    }
+
+    /** Copy constructor.
+     * @param interpolator interpolator to copy from. The copy is a deep
+     * copy: its arrays are separated from the original arrays of the
+     * instance
+     */
+    public NordsieckStepInterpolator(final NordsieckStepInterpolator interpolator) {
+        super(interpolator);
+        scalingH      = interpolator.scalingH;
+        referenceTime = interpolator.referenceTime;
+        if (interpolator.scaled != null) {
+            scaled = interpolator.scaled.clone();
+        }
+        if (interpolator.nordsieck != null) {
+            nordsieck = new Array2DRowRealMatrix(interpolator.nordsieck.getDataRef(), true);
+        }
+        if (interpolator.stateVariation != null) {
+            stateVariation = interpolator.stateVariation.clone();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected StepInterpolator doCopy() {
+        return new NordsieckStepInterpolator(this);
+    }
+
+    /** Reinitialize the instance.
+     * <p>Beware that all arrays <em>must</em> be references to integrator
+     * arrays, in order to ensure proper update without copy.</p>
+     * @param y reference to the integrator array holding the state at
+     * the end of the step
+     * @param forward integration direction indicator
+     */
+    @Override
+    public void reinitialize(final double[] y, final boolean forward) {
+        super.reinitialize(y, forward);
+        stateVariation = new double[y.length];
+    }
+
+    /** Reinitialize the instance.
+     * <p>Beware that all arrays <em>must</em> be references to integrator
+     * arrays, in order to ensure proper update without copy.</p>
+     * @param time time at which all arrays are defined
+     * @param stepSize step size used in the scaled and nordsieck arrays
+     * @param scaledDerivative reference to the integrator array holding the first
+     * scaled derivative
+     * @param nordsieckVector reference to the integrator matrix holding the
+     * nordsieck vector
+     */
+    public void reinitialize(final double time, final double stepSize,
+                             final double[] scaledDerivative,
+                             final Array2DRowRealMatrix nordsieckVector) {
+        this.referenceTime = time;
+        this.scalingH      = stepSize;
+        this.scaled        = scaledDerivative;
+        this.nordsieck     = nordsieckVector;
+
+        // make sure the state and derivatives will depend on the new arrays
+        setInterpolatedTime(getInterpolatedTime());
+
+    }
+
+    /** Rescale the instance.
+     * <p>Since the scaled and Nordiseck arrays are shared with the caller,
+     * this method has the side effect of rescaling this arrays in the caller too.</p>
+     * @param stepSize new step size to use in the scaled and nordsieck arrays
+     */
+    public void rescale(final double stepSize) {
+
+        final double ratio = stepSize / scalingH;
+        for (int i = 0; i < scaled.length; ++i) {
+            scaled[i] *= ratio;
+        }
+
+        final double[][] nData = nordsieck.getDataRef();
+        double power = ratio;
+        for (int i = 0; i < nData.length; ++i) {
+            power *= ratio;
+            final double[] nDataI = nData[i];
+            for (int j = 0; j < nDataI.length; ++j) {
+                nDataI[j] *= power;
+            }
+        }
+
+        scalingH = stepSize;
+
+    }
+
+    /**
+     * Get the state vector variation from current to interpolated state.
+     * <p>This method is aimed at computing y(t<sub>interpolation</sub>)
+     * -y(t<sub>current</sub>) accurately by avoiding the cancellation errors
+     * that would occur if the subtraction were performed explicitly.</p>
+     * <p>The returned vector is a reference to a reused array, so
+     * it should not be modified and it should be copied if it needs
+     * to be preserved across several calls.</p>
+     * @return state vector at time {@link #getInterpolatedTime}
+     * @see #getInterpolatedDerivatives()
+     * @throws DerivativeException if this call induces an automatic
+     * step finalization that throws one
+     */
+    public double[] getInterpolatedStateVariation()
+        throws DerivativeException {
+        // compute and ignore interpolated state
+        // to make sure state variation is computed as a side effect
+        getInterpolatedState();
+        return stateVariation;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) {
+
+        final double x = interpolatedTime - referenceTime;
+        final double normalizedAbscissa = x / scalingH;
+
+        Arrays.fill(stateVariation, 0.0);
+        Arrays.fill(interpolatedDerivatives, 0.0);
+
+        // apply Taylor formula from high order to low order,
+        // for the sake of numerical accuracy
+        final double[][] nData = nordsieck.getDataRef();
+        for (int i = nData.length - 1; i >= 0; --i) {
+            final int order = i + 2;
+            final double[] nDataI = nData[i];
+            final double power = FastMath.pow(normalizedAbscissa, order);
+            for (int j = 0; j < nDataI.length; ++j) {
+                final double d = nDataI[j] * power;
+                stateVariation[j]          += d;
+                interpolatedDerivatives[j] += order * d;
+            }
+        }
+
+        for (int j = 0; j < currentState.length; ++j) {
+            stateVariation[j] += scaled[j] * normalizedAbscissa;
+            interpolatedState[j] = currentState[j] + stateVariation[j];
+            interpolatedDerivatives[j] =
+                (interpolatedDerivatives[j] + scaled[j] * normalizedAbscissa) / x;
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void writeExternal(final ObjectOutput out)
+        throws IOException {
+
+        // save the state of the base class
+        writeBaseExternal(out);
+
+        // save the local attributes
+        out.writeDouble(scalingH);
+        out.writeDouble(referenceTime);
+
+        final int n = (currentState == null) ? -1 : currentState.length;
+        if (scaled == null) {
+            out.writeBoolean(false);
+        } else {
+            out.writeBoolean(true);
+            for (int j = 0; j < n; ++j) {
+                out.writeDouble(scaled[j]);
+            }
+        }
+
+        if (nordsieck == null) {
+            out.writeBoolean(false);
+        } else {
+            out.writeBoolean(true);
+            out.writeObject(nordsieck);
+        }
+
+        // we don't save state variation, it will be recomputed
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void readExternal(final ObjectInput in)
+        throws IOException, ClassNotFoundException {
+
+        // read the base class
+        final double t = readBaseExternal(in);
+
+        // read the local attributes
+        scalingH      = in.readDouble();
+        referenceTime = in.readDouble();
+
+        final int n = (currentState == null) ? -1 : currentState.length;
+        final boolean hasScaled = in.readBoolean();
+        if (hasScaled) {
+            scaled = new double[n];
+            for (int j = 0; j < n; ++j) {
+                scaled[j] = in.readDouble();
+            }
+        } else {
+            scaled = null;
+        }
+
+        final boolean hasNordsieck = in.readBoolean();
+        if (hasNordsieck) {
+            nordsieck = (Array2DRowRealMatrix) in.readObject();
+        } else {
+            nordsieck = null;
+        }
+
+        if (hasScaled && hasNordsieck) {
+            // we can now set the interpolated time and state
+            stateVariation = new double[n];
+            setInterpolatedTime(t);
+        } else {
+            stateVariation = null;
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/StepHandler.java b/src/main/java/org/apache/commons/math/ode/sampling/StepHandler.java
new file mode 100644
index 0000000..53c2fbe
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/StepHandler.java
@@ -0,0 +1,78 @@
+/*
+ * 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.ode.sampling;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/**
+ * This interface represents a handler that should be called after
+ * each successful step.
+ *
+ * <p>The ODE integrators compute the evolution of the state vector at
+ * some grid points that depend on their own internal algorithm. Once
+ * they have found a new grid point (possibly after having computed
+ * several evaluation of the derivative at intermediate points), they
+ * provide it to objects implementing this interface. These objects
+ * typically either ignore the intermediate steps and wait for the
+ * last one, store the points in an ephemeris, or forward them to
+ * specialized processing or output methods.</p>
+ *
+ * @see org.apache.commons.math.ode.FirstOrderIntegrator
+ * @see org.apache.commons.math.ode.SecondOrderIntegrator
+ * @see StepInterpolator
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface StepHandler {
+
+  /** Determines whether this handler needs dense output.
+   * <p>This method allows the integrator to avoid performing extra
+   * computation if the handler does not need dense output. If this
+   * method returns false, the integrator will call the {@link
+   * #handleStep} method with a {@link DummyStepInterpolator} rather
+   * than a custom interpolator.</p>
+   * @return true if the handler needs dense output
+   */
+  boolean requiresDenseOutput();
+
+  /** Reset the step handler.
+   * Initialize the internal data as required before the first step is
+   * handled.
+   */
+  void reset();
+
+  /**
+   * Handle the last accepted step
+   * @param interpolator interpolator for the last accepted step. For
+   * efficiency purposes, the various integrators reuse the same
+   * object on each call, so if the instance wants to keep it across
+   * all calls (for example to provide at the end of the integration a
+   * continuous model valid throughout the integration range, as the
+   * {@link org.apache.commons.math.ode.ContinuousOutputModel
+   * ContinuousOutputModel} class does), it should build a local copy
+   * using the clone method of the interpolator and store this copy.
+   * Keeping only a reference to the interpolator and reusing it will
+   * result in unpredictable behavior (potentially crashing the application).
+   * @param isLast true if the step is the last one
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   */
+  void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/StepInterpolator.java b/src/main/java/org/apache/commons/math/ode/sampling/StepInterpolator.java
new file mode 100644
index 0000000..ceb5a86
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/StepInterpolator.java
@@ -0,0 +1,132 @@
+/*
+ * 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.ode.sampling;
+
+import java.io.Externalizable;
+
+import org.apache.commons.math.ode.DerivativeException;
+
+/** This interface represents an interpolator over the last step
+ * during an ODE integration.
+ *
+ * <p>The various ODE integrators provide objects implementing this
+ * interface to the step handlers. These objects are often custom
+ * objects tightly bound to the integrator internal algorithms. The
+ * handlers can use these objects to retrieve the state vector at
+ * intermediate times between the previous and the current grid points
+ * (this feature is often called dense output).</p>
+ * <p>One important thing to note is that the step handlers may be so
+ * tightly bound to the integrators that they often share some internal
+ * state arrays. This imply that one should <em>never</em> use a direct
+ * reference to a step interpolator outside of the step handler, either
+ * for future use or for use in another thread. If such a need arise, the
+ * step interpolator <em>must</em> be copied using the dedicated
+ * {@link #copy()} method.
+ * </p>
+ *
+ * @see org.apache.commons.math.ode.FirstOrderIntegrator
+ * @see org.apache.commons.math.ode.SecondOrderIntegrator
+ * @see StepHandler
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public interface StepInterpolator extends Externalizable {
+
+  /**
+   * Get the previous grid point time.
+   * @return previous grid point time
+   */
+  double getPreviousTime();
+
+  /**
+   * Get the current grid point time.
+   * @return current grid point time
+   */
+  double getCurrentTime();
+
+  /**
+   * Get the time of the interpolated point.
+   * If {@link #setInterpolatedTime} has not been called, it returns
+   * the current grid point time.
+   * @return interpolation point time
+   */
+  double getInterpolatedTime();
+
+  /**
+   * Set the time of the interpolated point.
+   * <p>Setting the time outside of the current step is now allowed, but
+   * should be used with care since the accuracy of the interpolator will
+   * probably be very poor far from this step. This allowance has been
+   * added to simplify implementation of search algorithms near the
+   * step endpoints.</p>
+   * <p>Setting the time changes the instance internal state. If a
+   * specific state must be preserved, a copy of the instance must be
+   * created using {@link #copy()}.</p>
+   * @param time time of the interpolated point
+   */
+  void setInterpolatedTime(double time);
+
+  /**
+   * Get the state vector of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return state vector at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedDerivatives()
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   */
+  double[] getInterpolatedState() throws DerivativeException;
+
+  /**
+   * Get the derivatives of the state vector of the interpolated point.
+   * <p>The returned vector is a reference to a reused array, so
+   * it should not be modified and it should be copied if it needs
+   * to be preserved across several calls.</p>
+   * @return derivatives of the state vector at time {@link #getInterpolatedTime}
+   * @see #getInterpolatedState()
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   * @since 2.0
+   */
+  double[] getInterpolatedDerivatives() throws DerivativeException;
+
+  /** Check if the natural integration direction is forward.
+   * <p>This method provides the integration direction as specified by
+   * the integrator itself, it avoid some nasty problems in
+   * degenerated cases like null steps due to cancellation at step
+   * initialization, step control or discrete events
+   * triggering.</p>
+   * @return true if the integration variable (time) increases during
+   * integration
+   */
+  boolean isForward();
+
+  /** Copy the instance.
+   * <p>The copied instance is guaranteed to be independent from the
+   * original one. Both can be used with different settings for
+   * interpolated time without any side effect.</p>
+   * @return a deep copy of the instance, which can be used independently.
+   * @exception DerivativeException if user code called from step interpolator
+   * finalization triggers one
+   * @see #setInterpolatedTime(double)
+   */
+   StepInterpolator copy() throws DerivativeException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java b/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java
new file mode 100644
index 0000000..73bcc23
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java
@@ -0,0 +1,161 @@
+/*
+ * 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.ode.sampling;
+
+import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class wraps an object implementing {@link FixedStepHandler}
+ * into a {@link StepHandler}.
+
+ * <p>This wrapper allows to use fixed step handlers with general
+ * integrators which cannot guaranty their integration steps will
+ * remain constant and therefore only accept general step
+ * handlers.</p>
+ *
+ * <p>The stepsize used is selected at construction time. The {@link
+ * FixedStepHandler#handleStep handleStep} method of the underlying
+ * {@link FixedStepHandler} object is called at the beginning time of
+ * the integration t0 and also at times t0+h, t0+2h, ... If the
+ * integration range is an integer multiple of the stepsize, then the
+ * last point handled will be the endpoint of the integration tend, if
+ * not, the last point will belong to the interval [tend - h ;
+ * tend].</p>
+ *
+ * <p>There is no constraint on the integrator, it can use any
+ * timestep it needs (time steps longer or shorter than the fixed time
+ * step and non-integer ratios are all allowed).</p>
+ *
+ * @see StepHandler
+ * @see FixedStepHandler
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ */
+
+public class StepNormalizer implements StepHandler {
+
+    /** Fixed time step. */
+    private double h;
+
+    /** Underlying step handler. */
+    private final FixedStepHandler handler;
+
+    /** Last step time. */
+    private double lastTime;
+
+    /** Last State vector. */
+    private double[] lastState;
+
+    /** Last Derivatives vector. */
+    private double[] lastDerivatives;
+
+    /** Integration direction indicator. */
+    private boolean forward;
+
+    /** Simple constructor.
+     * @param h fixed time step (sign is not used)
+     * @param handler fixed time step handler to wrap
+     */
+    public StepNormalizer(final double h, final FixedStepHandler handler) {
+        this.h       = FastMath.abs(h);
+        this.handler = handler;
+        reset();
+    }
+
+    /** Determines whether this handler needs dense output.
+     * This handler needs dense output in order to provide data at
+     * regularly spaced steps regardless of the steps the integrator
+     * uses, so this method always returns true.
+     * @return always true
+     */
+    public boolean requiresDenseOutput() {
+        return true;
+    }
+
+    /** Reset the step handler.
+     * Initialize the internal data as required before the first step is
+     * handled.
+     */
+    public void reset() {
+        lastTime        = Double.NaN;
+        lastState       = null;
+        lastDerivatives = null;
+        forward         = true;
+    }
+
+    /**
+     * Handle the last accepted step
+     * @param interpolator interpolator for the last accepted step. For
+     * efficiency purposes, the various integrators reuse the same
+     * object on each call, so if the instance wants to keep it across
+     * all calls (for example to provide at the end of the integration a
+     * continuous model valid throughout the integration range), it
+     * should build a local copy using the clone method and store this
+     * copy.
+     * @param isLast true if the step is the last one
+     * @throws DerivativeException this exception is propagated to the
+     * caller if the underlying user function triggers one
+     */
+    public void handleStep(final StepInterpolator interpolator, final boolean isLast)
+        throws DerivativeException {
+
+        if (lastState == null) {
+
+            lastTime = interpolator.getPreviousTime();
+            interpolator.setInterpolatedTime(lastTime);
+            lastState = interpolator.getInterpolatedState().clone();
+            lastDerivatives = interpolator.getInterpolatedDerivatives().clone();
+
+            // take the integration direction into account
+            forward = interpolator.getCurrentTime() >= lastTime;
+            if (! forward) {
+                h = -h;
+            }
+
+        }
+
+        double nextTime = lastTime + h;
+        boolean nextInStep = forward ^ (nextTime > interpolator.getCurrentTime());
+        while (nextInStep) {
+
+            // output the stored previous step
+            handler.handleStep(lastTime, lastState, lastDerivatives, false);
+
+            // store the next step
+            lastTime = nextTime;
+            interpolator.setInterpolatedTime(lastTime);
+            System.arraycopy(interpolator.getInterpolatedState(), 0,
+                             lastState, 0, lastState.length);
+            System.arraycopy(interpolator.getInterpolatedDerivatives(), 0,
+                             lastDerivatives, 0, lastDerivatives.length);
+
+            nextTime  += h;
+            nextInStep = forward ^ (nextTime > interpolator.getCurrentTime());
+
+        }
+
+        if (isLast) {
+            // there will be no more steps,
+            // the stored one should be flagged as being the last
+            handler.handleStep(lastTime, lastState, lastDerivatives, true);
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/ode/sampling/package.html b/src/main/java/org/apache/commons/math/ode/sampling/package.html
new file mode 100644
index 0000000..46de4ef
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/ode/sampling/package.html
@@ -0,0 +1,60 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 613620 $ -->
+<body>
+<p>
+This package provides classes to handle sampling steps during
+Ordinary Differential Equations integration.
+</p>
+
+<p>
+In addition to computing the evolution of the state vector at some grid points, all
+ODE integrators also build up interpolation models of this evolution <em>inside</em> the
+last computed step. If users are interested in these interpolators, they can register a
+{@link org.apache.commons.math.ode.sampling.StepHandler StepHandler} instance using the
+{@link org.apache.commons.math.ode.FirstOrderIntegrator#addStepHandler addStepHandler}
+method which is supported by all integrators. The integrator will call this instance
+at the end of each accepted step and provide it the interpolator. The user can do
+whatever he wants with this interpolator, which computes both the state and its
+time-derivative. A typical use of step handler is to provide some output to monitor
+the integration process.
+</p>
+
+<p>
+In a sense, this is a kind of Inversion Of Control: rather than having the master
+application driving the slave integrator by providing the target end value for
+the free variable, we get a master integrator scheduling the free variable
+evolution and calling the slave application callbacks that were registered at
+configuration time.
+</p>
+
+<p>
+Since some integrators may use variable step size, the generic {@link
+org.apache.commons.math.ode.sampling.StepHandler StepHandler} interface can be called
+either at regular or irregular rate. This interface allows to navigate to any location
+within the last computed step, thanks to the provided {@link
+org.apache.commons.math.ode.sampling.StepInterpolator StepInterpolator} object.
+If regular output is desired (for example in order to write an ephemeris file), then
+the simpler {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler}
+interface can be used. Objects implementing this interface should be wrapped within a
+{@link org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} instance
+in order to be registered to the integrator.
+</p>
+
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateRealOptimizer.java
new file mode 100644
index 0000000..b7b7dbb
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateRealOptimizer.java
@@ -0,0 +1,112 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
+
+/**
+ * This interface represents an optimization algorithm for
+ * {@link DifferentiableMultivariateRealFunction scalar differentiable objective
+ * functions}.
+ * Optimization algorithms find the input point set that either {@link GoalType
+ * maximize or minimize} an objective function.
+ *
+ * @see MultivariateRealOptimizer
+ * @see DifferentiableMultivariateVectorialOptimizer
+ * @version $Revision: 1065484 $ $Date: 2011-01-31 06:45:14 +0100 (lun. 31 janv. 2011) $
+ * @since 2.0
+ */
+public interface DifferentiableMultivariateRealOptimizer {
+
+    /** Set the maximal number of iterations of the algorithm.
+     * @param maxIterations maximal number of function calls
+     */
+    void setMaxIterations(int maxIterations);
+
+    /** Get the maximal number of iterations of the algorithm.
+     * @return maximal number of iterations
+     */
+    int getMaxIterations();
+
+    /** Get the number of iterations realized by the algorithm.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@code optimize} method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of iterations
+     */
+    int getIterations();
+
+    /** Set the maximal number of functions evaluations.
+     * @param maxEvaluations maximal number of function evaluations
+     */
+    void setMaxEvaluations(int maxEvaluations);
+
+    /** Get the maximal number of functions evaluations.
+     * @return maximal number of functions evaluations
+     */
+    int getMaxEvaluations();
+
+    /** Get the number of evaluations of the objective function.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize}
+     * method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the objective function
+     */
+    int getEvaluations();
+
+    /** Get the number of evaluations of the objective function gradient.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize}
+     * method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the objective function gradient
+     */
+    int getGradientEvaluations();
+
+    /** Set the convergence checker.
+     * @param checker object to use to check for convergence
+     */
+    void setConvergenceChecker(RealConvergenceChecker checker);
+
+    /** Get the convergence checker.
+     * @return object used to check for convergence
+     */
+    RealConvergenceChecker getConvergenceChecker();
+
+    /** Optimizes an objective function.
+     * @param f objective function
+     * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE}
+     * or {@link GoalType#MINIMIZE}
+     * @param startPoint the start point for optimization
+     * @return the point/value pair giving the optimal value for objective function
+     * @exception FunctionEvaluationException if the objective function throws one during
+     * the search
+     * @exception OptimizationException if the algorithm failed to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    RealPointValuePair optimize(DifferentiableMultivariateRealFunction f,
+                                  GoalType goalType,
+                                  double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateVectorialOptimizer.java b/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateVectorialOptimizer.java
new file mode 100644
index 0000000..51f0763
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/DifferentiableMultivariateVectorialOptimizer.java
@@ -0,0 +1,114 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * This interface represents an optimization algorithm for {@link DifferentiableMultivariateVectorialFunction
+ * vectorial differentiable objective functions}.
+ * <p>Optimization algorithms find the input point set that either {@link GoalType
+ * maximize or minimize} an objective function.</p>
+ * @see MultivariateRealOptimizer
+ * @see DifferentiableMultivariateRealOptimizer
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface DifferentiableMultivariateVectorialOptimizer {
+
+    /** Set the maximal number of iterations of the algorithm.
+     * @param maxIterations maximal number of function calls
+     * .
+     */
+    void setMaxIterations(int maxIterations);
+
+    /** Get the maximal number of iterations of the algorithm.
+      * @return maximal number of iterations
+     */
+    int getMaxIterations();
+
+    /** Get the number of iterations realized by the algorithm.
+     * @return number of iterations
+    */
+   int getIterations();
+
+   /** Set the maximal number of functions evaluations.
+    * @param maxEvaluations maximal number of function evaluations
+    */
+   void setMaxEvaluations(int maxEvaluations);
+
+   /** Get the maximal number of functions evaluations.
+    * @return maximal number of functions evaluations
+    */
+   int getMaxEvaluations();
+
+    /** Get the number of evaluations of the objective function.
+     * <p>
+     * The number of evaluation correspond to the last call to the
+     * {@link #optimize(DifferentiableMultivariateVectorialFunction,
+     * double[], double[], double[]) optimize} method. It is 0 if
+     * the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the objective function
+     */
+    int getEvaluations();
+
+    /** Get the number of evaluations of the objective function jacobian .
+     * <p>
+     * The number of evaluation correspond to the last call to the
+     * {@link #optimize(DifferentiableMultivariateVectorialFunction,
+     * double[], double[], double[]) optimize} method. It is 0 if
+     * the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the objective function jacobian
+     */
+    int getJacobianEvaluations();
+
+    /** Set the convergence checker.
+     * @param checker object to use to check for convergence
+     */
+    void setConvergenceChecker(VectorialConvergenceChecker checker);
+
+    /** Get the convergence checker.
+     * @return object used to check for convergence
+     */
+    VectorialConvergenceChecker getConvergenceChecker();
+
+    /** Optimizes an objective function.
+     * <p>
+     * Optimization is considered to be a weighted least-squares minimization.
+     * The cost function to be minimized is
+     * &sum;weight<sub>i</sub>(objective<sub>i</sub>-target<sub>i</sub>)<sup>2</sup>
+     * </p>
+     * @param f objective function
+     * @param target target value for the objective functions at optimum
+     * @param weights weight for the least squares cost computation
+     * @param startPoint the start point for optimization
+     * @return the point/value pair giving the optimal value for objective function
+     * @exception FunctionEvaluationException if the objective function throws one during
+     * the search
+     * @exception OptimizationException if the algorithm failed to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    VectorialPointValuePair optimize(DifferentiableMultivariateVectorialFunction f,
+                                     double[] target, double[] weights,
+                                     double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/GoalType.java b/src/main/java/org/apache/commons/math/optimization/GoalType.java
new file mode 100644
index 0000000..1392d27
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/GoalType.java
@@ -0,0 +1,35 @@
+/*
+ * 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.optimization;
+
+import java.io.Serializable;
+
+/**
+ * Goal type for an optimization problem.
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public enum GoalType implements Serializable {
+
+    /** Maximization goal. */
+    MAXIMIZE,
+
+    /** Minimization goal. */
+    MINIMIZE
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java b/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java
new file mode 100644
index 0000000..0ed2efd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/LeastSquaresConverter.java
@@ -0,0 +1,193 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.analysis.MultivariateVectorialFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.RealMatrix;
+
+/** This class converts {@link MultivariateVectorialFunction vectorial
+ * objective functions} to {@link MultivariateRealFunction scalar objective functions}
+ * when the goal is to minimize them.
+ * <p>
+ * This class is mostly used when the vectorial objective function represents
+ * a theoretical result computed from a point set applied to a model and
+ * the models point must be adjusted to fit the theoretical result to some
+ * reference observations. The observations may be obtained for example from
+ * physical measurements whether the model is built from theoretical
+ * considerations.
+ * </p>
+ * <p>
+ * This class computes a possibly weighted squared sum of the residuals, which is
+ * a scalar value. The residuals are the difference between the theoretical model
+ * (i.e. the output of the vectorial objective function) and the observations. The
+ * class implements the {@link MultivariateRealFunction} interface and can therefore be
+ * minimized by any optimizer supporting scalar objectives functions.This is one way
+ * to perform a least square estimation. There are other ways to do this without using
+ * this converter, as some optimization algorithms directly support vectorial objective
+ * functions.
+ * </p>
+ * <p>
+ * This class support combination of residuals with or without weights and correlations.
+ * </p>
+  *
+ * @see MultivariateRealFunction
+ * @see MultivariateVectorialFunction
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+
+public class LeastSquaresConverter implements MultivariateRealFunction {
+
+    /** Underlying vectorial function. */
+    private final MultivariateVectorialFunction function;
+
+    /** Observations to be compared to objective function to compute residuals. */
+    private final double[] observations;
+
+    /** Optional weights for the residuals. */
+    private final double[] weights;
+
+    /** Optional scaling matrix (weight and correlations) for the residuals. */
+    private final RealMatrix scale;
+
+    /** Build a simple converter for uncorrelated residuals with the same weight.
+     * @param function vectorial residuals function to wrap
+     * @param observations observations to be compared to objective function to compute residuals
+     */
+    public LeastSquaresConverter(final MultivariateVectorialFunction function,
+                                 final double[] observations) {
+        this.function     = function;
+        this.observations = observations.clone();
+        this.weights      = null;
+        this.scale        = null;
+    }
+
+    /** Build a simple converter for uncorrelated residuals with the specific weights.
+     * <p>
+     * The scalar objective function value is computed as:
+     * <pre>
+     * objective = &sum;weight<sub>i</sub>(observation<sub>i</sub>-objective<sub>i</sub>)<sup>2</sup>
+     * </pre>
+     * </p>
+     * <p>
+     * Weights can be used for example to combine residuals with different standard
+     * deviations. As an example, consider a residuals array in which even elements
+     * are angular measurements in degrees with a 0.01&deg; standard deviation and
+     * odd elements are distance measurements in meters with a 15m standard deviation.
+     * In this case, the weights array should be initialized with value
+     * 1.0/(0.01<sup>2</sup>) in the even elements and 1.0/(15.0<sup>2</sup>) in the
+     * odd elements (i.e. reciprocals of variances).
+     * </p>
+     * <p>
+     * The array computed by the objective function, the observations array and the
+     * weights array must have consistent sizes or a {@link FunctionEvaluationException} will be
+     * triggered while computing the scalar objective.
+     * </p>
+     * @param function vectorial residuals function to wrap
+     * @param observations observations to be compared to objective function to compute residuals
+     * @param weights weights to apply to the residuals
+     * @exception IllegalArgumentException if the observations vector and the weights
+     * vector dimensions don't match (objective function dimension is checked only when
+     * the {@link #value(double[])} method is called)
+     */
+    public LeastSquaresConverter(final MultivariateVectorialFunction function,
+                                 final double[] observations, final double[] weights)
+        throws IllegalArgumentException {
+        if (observations.length != weights.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                    observations.length, weights.length);
+        }
+        this.function     = function;
+        this.observations = observations.clone();
+        this.weights      = weights.clone();
+        this.scale        = null;
+    }
+
+    /** Build a simple converter for correlated residuals with the specific weights.
+     * <p>
+     * The scalar objective function value is computed as:
+     * <pre>
+     * objective = y<sup>T</sup>y with y = scale&times;(observation-objective)
+     * </pre>
+     * </p>
+     * <p>
+     * The array computed by the objective function, the observations array and the
+     * the scaling matrix must have consistent sizes or a {@link FunctionEvaluationException}
+     * will be triggered while computing the scalar objective.
+     * </p>
+     * @param function vectorial residuals function to wrap
+     * @param observations observations to be compared to objective function to compute residuals
+     * @param scale scaling matrix
+     * @exception IllegalArgumentException if the observations vector and the scale
+     * matrix dimensions don't match (objective function dimension is checked only when
+     * the {@link #value(double[])} method is called)
+     */
+    public LeastSquaresConverter(final MultivariateVectorialFunction function,
+                                 final double[] observations, final RealMatrix scale)
+        throws IllegalArgumentException {
+        if (observations.length != scale.getColumnDimension()) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                    observations.length, scale.getColumnDimension());
+        }
+        this.function     = function;
+        this.observations = observations.clone();
+        this.weights      = null;
+        this.scale        = scale.copy();
+    }
+
+    /** {@inheritDoc} */
+    public double value(final double[] point) throws FunctionEvaluationException {
+
+        // compute residuals
+        final double[] residuals = function.value(point);
+        if (residuals.length != observations.length) {
+            throw new FunctionEvaluationException(point,LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                                        residuals.length, observations.length);
+        }
+        for (int i = 0; i < residuals.length; ++i) {
+            residuals[i] -= observations[i];
+        }
+
+        // compute sum of squares
+        double sumSquares = 0;
+        if (weights != null) {
+            for (int i = 0; i < residuals.length; ++i) {
+                final double ri = residuals[i];
+                sumSquares +=  weights[i] * ri * ri;
+            }
+        } else if (scale != null) {
+            for (final double yi : scale.operate(residuals)) {
+                sumSquares += yi * yi;
+            }
+        } else {
+            for (final double ri : residuals) {
+                sumSquares += ri * ri;
+            }
+        }
+
+        return sumSquares;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java
new file mode 100644
index 0000000..9cde37b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java
@@ -0,0 +1,228 @@
+/*
+ * 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.optimization;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomVectorGenerator;
+
+/**
+ * Special implementation of the {@link DifferentiableMultivariateRealOptimizer} interface adding
+ * multi-start features to an existing optimizer.
+ * <p>
+ * This class wraps a classical optimizer to use it several times in
+ * turn with different starting points in order to avoid being trapped
+ * into a local extremum when looking for a global one.
+ * </p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class MultiStartDifferentiableMultivariateRealOptimizer
+    implements DifferentiableMultivariateRealOptimizer {
+
+    /** Underlying classical optimizer. */
+    private final DifferentiableMultivariateRealOptimizer optimizer;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Number of iterations already performed for all starts. */
+    private int totalIterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+
+    /** Number of gradient evaluations already performed for all starts. */
+    private int totalGradientEvaluations;
+
+    /** Number of starts to go. */
+    private int starts;
+
+    /** Random generator for multi-start. */
+    private RandomVectorGenerator generator;
+
+    /** Found optima. */
+    private RealPointValuePair[] optima;
+
+    /**
+     * Create a multi-start optimizer from a single-start optimizer
+     * @param optimizer single-start optimizer to wrap
+     * @param starts number of starts to perform (including the
+     * first one), multi-start is disabled if value is less than or
+     * equal to 1
+     * @param generator random vector generator to use for restarts
+     */
+    public MultiStartDifferentiableMultivariateRealOptimizer(final DifferentiableMultivariateRealOptimizer optimizer,
+                                                             final int starts,
+                                                             final RandomVectorGenerator generator) {
+        this.optimizer                = optimizer;
+        this.totalIterations          = 0;
+        this.totalEvaluations         = 0;
+        this.totalGradientEvaluations = 0;
+        this.starts                   = starts;
+        this.generator                = generator;
+        this.optima                   = null;
+        setMaxIterations(Integer.MAX_VALUE);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** Get all the optima found during the last call to {@link
+     * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[])
+     * optimize}.
+     * <p>The optimizer stores all the optima found during a set of
+     * restarts. The {@link #optimize(DifferentiableMultivariateRealFunction,
+     * GoalType, double[]) optimize} method returns the best point only. This
+     * method returns all the points found at the end of each starts,
+     * including the best one already returned by the {@link
+     * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[])
+     * optimize} method.
+     * </p>
+     * <p>
+     * The returned array as one element for each start as specified
+     * in the constructor. It is ordered with the results from the
+     * runs that did converge first, sorted from best to worst
+     * objective value (i.e in ascending order if minimizing and in
+     * descending order if maximizing), followed by and null elements
+     * corresponding to the runs that did not converge. This means all
+     * elements will be null if the {@link #optimize(DifferentiableMultivariateRealFunction,
+     * GoalType, double[]) optimize} method did throw a {@link
+     * org.apache.commons.math.ConvergenceException ConvergenceException}).
+     * This also means that if the first element is non null, it is the best
+     * point found across all starts.</p>
+     * @return array containing the optima
+     * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateRealFunction,
+     * GoalType, double[]) optimize} has not been called
+     */
+    public RealPointValuePair[] getOptima() throws IllegalStateException {
+        if (optima == null) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
+        }
+        return optima.clone();
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return totalIterations;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getGradientEvaluations() {
+        return totalGradientEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setConvergenceChecker(RealConvergenceChecker checker) {
+        optimizer.setConvergenceChecker(checker);
+    }
+
+    /** {@inheritDoc} */
+    public RealConvergenceChecker getConvergenceChecker() {
+        return optimizer.getConvergenceChecker();
+    }
+
+    /** {@inheritDoc} */
+    public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f,
+                                         final GoalType goalType,
+                                         double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, FunctionEvaluationException {
+
+        optima                   = new RealPointValuePair[starts];
+        totalIterations          = 0;
+        totalEvaluations         = 0;
+        totalGradientEvaluations = 0;
+
+        // multi-start loop
+        for (int i = 0; i < starts; ++i) {
+
+            try {
+                optimizer.setMaxIterations(maxIterations - totalIterations);
+                optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+                optima[i] = optimizer.optimize(f, goalType,
+                                               (i == 0) ? startPoint : generator.nextVector());
+            } catch (FunctionEvaluationException fee) {
+                optima[i] = null;
+            } catch (OptimizationException oe) {
+                optima[i] = null;
+            }
+
+            totalIterations          += optimizer.getIterations();
+            totalEvaluations         += optimizer.getEvaluations();
+            totalGradientEvaluations += optimizer.getGradientEvaluations();
+
+        }
+
+        // sort the optima from best to worst, followed by null elements
+        Arrays.sort(optima, new Comparator<RealPointValuePair>() {
+            public int compare(final RealPointValuePair o1, final RealPointValuePair o2) {
+                if (o1 == null) {
+                    return (o2 == null) ? 0 : +1;
+                } else if (o2 == null) {
+                    return -1;
+                }
+                final double v1 = o1.getValue();
+                final double v2 = o2.getValue();
+                return (goalType == GoalType.MINIMIZE) ?
+                        Double.compare(v1, v2) : Double.compare(v2, v1);
+            }
+        });
+
+        if (optima[0] == null) {
+            throw new OptimizationException(
+                    LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT,
+                    starts);
+        }
+
+        // return the found point given the best objective function value
+        return optima[0];
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizer.java b/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizer.java
new file mode 100644
index 0000000..d2d5268
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizer.java
@@ -0,0 +1,238 @@
+/*
+ * 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.optimization;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomVectorGenerator;
+
+/**
+ * Special implementation of the {@link DifferentiableMultivariateVectorialOptimizer} interface adding
+ * multi-start features to an existing optimizer.
+ * <p>
+ * This class wraps a classical optimizer to use it several times in
+ * turn with different starting points in order to avoid being trapped
+ * into a local extremum when looking for a global one.
+ * </p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class MultiStartDifferentiableMultivariateVectorialOptimizer
+    implements DifferentiableMultivariateVectorialOptimizer {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 9206382258980561530L;
+
+    /** Underlying classical optimizer. */
+    private final DifferentiableMultivariateVectorialOptimizer optimizer;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Number of iterations already performed for all starts. */
+    private int totalIterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+
+    /** Number of jacobian evaluations already performed for all starts. */
+    private int totalJacobianEvaluations;
+
+    /** Number of starts to go. */
+    private int starts;
+
+    /** Random generator for multi-start. */
+    private RandomVectorGenerator generator;
+
+    /** Found optima. */
+    private VectorialPointValuePair[] optima;
+
+    /**
+     * Create a multi-start optimizer from a single-start optimizer
+     * @param optimizer single-start optimizer to wrap
+     * @param starts number of starts to perform (including the
+     * first one), multi-start is disabled if value is less than or
+     * equal to 1
+     * @param generator random vector generator to use for restarts
+     */
+    public MultiStartDifferentiableMultivariateVectorialOptimizer(
+                final DifferentiableMultivariateVectorialOptimizer optimizer,
+                final int starts,
+                final RandomVectorGenerator generator) {
+        this.optimizer                = optimizer;
+        this.totalIterations          = 0;
+        this.totalEvaluations         = 0;
+        this.totalJacobianEvaluations = 0;
+        this.starts                   = starts;
+        this.generator                = generator;
+        this.optima                   = null;
+        setMaxIterations(Integer.MAX_VALUE);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** Get all the optima found during the last call to {@link
+     * #optimize(DifferentiableMultivariateVectorialFunction,
+     * double[], double[], double[]) optimize}.
+     * <p>The optimizer stores all the optima found during a set of
+     * restarts. The {@link #optimize(DifferentiableMultivariateVectorialFunction,
+     * double[], double[], double[]) optimize} method returns the
+     * best point only. This method returns all the points found at the
+     * end of each starts, including the best one already returned by the {@link
+     * #optimize(DifferentiableMultivariateVectorialFunction, double[],
+     * double[], double[]) optimize} method.
+     * </p>
+     * <p>
+     * The returned array as one element for each start as specified
+     * in the constructor. It is ordered with the results from the
+     * runs that did converge first, sorted from best to worst
+     * objective value (i.e in ascending order if minimizing and in
+     * descending order if maximizing), followed by and null elements
+     * corresponding to the runs that did not converge. This means all
+     * elements will be null if the {@link #optimize(DifferentiableMultivariateVectorialFunction,
+     * double[], double[], double[]) optimize} method did throw a {@link
+     * org.apache.commons.math.ConvergenceException ConvergenceException}).
+     * This also means that if the first element is non null, it is the best
+     * point found across all starts.</p>
+     * @return array containing the optima
+     * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateVectorialFunction,
+     * double[], double[], double[]) optimize} has not been called
+     */
+    public VectorialPointValuePair[] getOptima() throws IllegalStateException {
+        if (optima == null) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
+        }
+        return optima.clone();
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return totalIterations;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getJacobianEvaluations() {
+        return totalJacobianEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setConvergenceChecker(VectorialConvergenceChecker checker) {
+        optimizer.setConvergenceChecker(checker);
+    }
+
+    /** {@inheritDoc} */
+    public VectorialConvergenceChecker getConvergenceChecker() {
+        return optimizer.getConvergenceChecker();
+    }
+
+    /** {@inheritDoc} */
+    public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f,
+                                            final double[] target, final double[] weights,
+                                            final double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        optima                   = new VectorialPointValuePair[starts];
+        totalIterations          = 0;
+        totalEvaluations         = 0;
+        totalJacobianEvaluations = 0;
+
+        // multi-start loop
+        for (int i = 0; i < starts; ++i) {
+
+            try {
+                optimizer.setMaxIterations(maxIterations - totalIterations);
+                optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+                optima[i] = optimizer.optimize(f, target, weights,
+                                               (i == 0) ? startPoint : generator.nextVector());
+            } catch (FunctionEvaluationException fee) {
+                optima[i] = null;
+            } catch (OptimizationException oe) {
+                optima[i] = null;
+            }
+
+            totalIterations          += optimizer.getIterations();
+            totalEvaluations         += optimizer.getEvaluations();
+            totalJacobianEvaluations += optimizer.getJacobianEvaluations();
+
+        }
+
+        // sort the optima from best to worst, followed by null elements
+        Arrays.sort(optima, new Comparator<VectorialPointValuePair>() {
+            public int compare(final VectorialPointValuePair o1, final VectorialPointValuePair o2) {
+                if (o1 == null) {
+                    return (o2 == null) ? 0 : +1;
+                } else if (o2 == null) {
+                    return -1;
+                }
+                return Double.compare(weightedResidual(o1), weightedResidual(o2));
+            }
+            private double weightedResidual(final VectorialPointValuePair pv) {
+                final double[] value = pv.getValueRef();
+                double sum = 0;
+                for (int i = 0; i < value.length; ++i) {
+                    final double ri = value[i] - target[i];
+                    sum += weights[i] * ri * ri;
+                }
+                return sum;
+            }
+        });
+
+        if (optima[0] == null) {
+            throw new OptimizationException(
+                    LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT,
+                    starts);
+        }
+
+        // return the found point given the best objective function value
+        return optima[0];
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java
new file mode 100644
index 0000000..fdba1d5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.java
@@ -0,0 +1,216 @@
+/*
+ * 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.optimization;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomVectorGenerator;
+
+/**
+ * Special implementation of the {@link MultivariateRealOptimizer} interface adding
+ * multi-start features to an existing optimizer.
+ * <p>
+ * This class wraps a classical optimizer to use it several times in
+ * turn with different starting points in order to avoid being trapped
+ * into a local extremum when looking for a global one.
+ * </p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class MultiStartMultivariateRealOptimizer
+    implements MultivariateRealOptimizer {
+
+    /** Underlying classical optimizer. */
+    private final MultivariateRealOptimizer optimizer;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of iterations already performed for all starts. */
+    private int totalIterations;
+
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+
+    /** Number of starts to go. */
+    private int starts;
+
+    /** Random generator for multi-start. */
+    private RandomVectorGenerator generator;
+
+    /** Found optima. */
+    private RealPointValuePair[] optima;
+
+    /**
+     * Create a multi-start optimizer from a single-start optimizer
+     * @param optimizer single-start optimizer to wrap
+     * @param starts number of starts to perform (including the
+     * first one), multi-start is disabled if value is less than or
+     * equal to 1
+     * @param generator random vector generator to use for restarts
+     */
+    public MultiStartMultivariateRealOptimizer(final MultivariateRealOptimizer optimizer,
+                                               final int starts,
+                                               final RandomVectorGenerator generator) {
+        this.optimizer        = optimizer;
+        this.totalIterations  = 0;
+        this.totalEvaluations = 0;
+        this.starts           = starts;
+        this.generator        = generator;
+        this.optima           = null;
+        setMaxIterations(Integer.MAX_VALUE);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** Get all the optima found during the last call to {@link
+     * #optimize(MultivariateRealFunction, GoalType, double[]) optimize}.
+     * <p>The optimizer stores all the optima found during a set of
+     * restarts. The {@link #optimize(MultivariateRealFunction, GoalType,
+     * double[]) optimize} method returns the best point only. This
+     * method returns all the points found at the end of each starts,
+     * including the best one already returned by the {@link
+     * #optimize(MultivariateRealFunction, GoalType, double[]) optimize}
+     * method.
+     * </p>
+     * <p>
+     * The returned array as one element for each start as specified
+     * in the constructor. It is ordered with the results from the
+     * runs that did converge first, sorted from best to worst
+     * objective value (i.e in ascending order if minimizing and in
+     * descending order if maximizing), followed by and null elements
+     * corresponding to the runs that did not converge. This means all
+     * elements will be null if the {@link #optimize(MultivariateRealFunction,
+     * GoalType, double[]) optimize} method did throw a {@link
+     * org.apache.commons.math.ConvergenceException ConvergenceException}).
+     * This also means that if the first element is non null, it is the best
+     * point found across all starts.</p>
+     * @return array containing the optima
+     * @exception IllegalStateException if {@link #optimize(MultivariateRealFunction,
+     * GoalType, double[]) optimize} has not been called
+     */
+    public RealPointValuePair[] getOptima() throws IllegalStateException {
+        if (optima == null) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
+        }
+        return optima.clone();
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return totalIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setConvergenceChecker(RealConvergenceChecker checker) {
+        optimizer.setConvergenceChecker(checker);
+    }
+
+    /** {@inheritDoc} */
+    public RealConvergenceChecker getConvergenceChecker() {
+        return optimizer.getConvergenceChecker();
+    }
+
+    /** {@inheritDoc} */
+    public RealPointValuePair optimize(final MultivariateRealFunction f,
+                                         final GoalType goalType,
+                                         double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, FunctionEvaluationException {
+
+        optima           = new RealPointValuePair[starts];
+        totalIterations  = 0;
+        totalEvaluations = 0;
+
+        // multi-start loop
+        for (int i = 0; i < starts; ++i) {
+
+            try {
+                optimizer.setMaxIterations(maxIterations - totalIterations);
+                optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+                optima[i] = optimizer.optimize(f, goalType,
+                                               (i == 0) ? startPoint : generator.nextVector());
+            } catch (FunctionEvaluationException fee) {
+                optima[i] = null;
+            } catch (OptimizationException oe) {
+                optima[i] = null;
+            }
+
+            totalIterations  += optimizer.getIterations();
+            totalEvaluations += optimizer.getEvaluations();
+
+        }
+
+        // sort the optima from best to worst, followed by null elements
+        Arrays.sort(optima, new Comparator<RealPointValuePair>() {
+            public int compare(final RealPointValuePair o1, final RealPointValuePair o2) {
+                if (o1 == null) {
+                    return (o2 == null) ? 0 : +1;
+                } else if (o2 == null) {
+                    return -1;
+                }
+                final double v1 = o1.getValue();
+                final double v2 = o2.getValue();
+                return (goalType == GoalType.MINIMIZE) ?
+                        Double.compare(v1, v2) : Double.compare(v2, v1);
+            }
+        });
+
+        if (optima[0] == null) {
+            throw new OptimizationException(
+                    LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT,
+                    starts);
+        }
+
+        // return the found point given the best objective function value
+        return optima[0];
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizer.java
new file mode 100644
index 0000000..b5ccc5f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizer.java
@@ -0,0 +1,318 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.random.RandomGenerator;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Special implementation of the {@link UnivariateRealOptimizer} interface adding
+ * multi-start features to an existing optimizer.
+ * <p>
+ * This class wraps a classical optimizer to use it several times in
+ * turn with different starting points in order to avoid being trapped
+ * into a local extremum when looking for a global one.
+ * </p>
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public class MultiStartUnivariateRealOptimizer implements UnivariateRealOptimizer {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 5983375963110961019L;
+
+    /** Underlying classical optimizer. */
+    private final UnivariateRealOptimizer optimizer;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of iterations already performed for all starts. */
+    private int totalIterations;
+
+    /** Number of evaluations already performed for all starts. */
+    private int totalEvaluations;
+
+    /** Number of starts to go. */
+    private int starts;
+
+    /** Random generator for multi-start. */
+    private RandomGenerator generator;
+
+    /** Found optima. */
+    private double[] optima;
+
+    /** Found function values at optima. */
+    private double[] optimaValues;
+
+    /**
+     * Create a multi-start optimizer from a single-start optimizer
+     * @param optimizer single-start optimizer to wrap
+     * @param starts number of starts to perform (including the
+     * first one), multi-start is disabled if value is less than or
+     * equal to 1
+     * @param generator random generator to use for restarts
+     */
+    public MultiStartUnivariateRealOptimizer(final UnivariateRealOptimizer optimizer,
+                                             final int starts,
+                                             final RandomGenerator generator) {
+        this.optimizer        = optimizer;
+        this.totalIterations  = 0;
+        this.starts           = starts;
+        this.generator        = generator;
+        this.optima           = null;
+        setMaximalIterationCount(Integer.MAX_VALUE);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** {@inheritDoc} */
+    public double getFunctionValue() {
+        return optimaValues[0];
+    }
+
+    /** {@inheritDoc} */
+    public double getResult() {
+        return optima[0];
+    }
+
+    /** {@inheritDoc} */
+    public double getAbsoluteAccuracy() {
+        return optimizer.getAbsoluteAccuracy();
+    }
+
+    /** {@inheritDoc} */
+    public int getIterationCount() {
+        return totalIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaximalIterationCount() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return totalEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public double getRelativeAccuracy() {
+        return optimizer.getRelativeAccuracy();
+    }
+
+    /** {@inheritDoc} */
+    public void resetAbsoluteAccuracy() {
+        optimizer.resetAbsoluteAccuracy();
+    }
+
+    /** {@inheritDoc} */
+    public void resetMaximalIterationCount() {
+        optimizer.resetMaximalIterationCount();
+    }
+
+    /** {@inheritDoc} */
+    public void resetRelativeAccuracy() {
+        optimizer.resetRelativeAccuracy();
+    }
+
+    /** {@inheritDoc} */
+    public void setAbsoluteAccuracy(double accuracy) {
+        optimizer.setAbsoluteAccuracy(accuracy);
+    }
+
+    /** {@inheritDoc} */
+    public void setMaximalIterationCount(int count) {
+        this.maxIterations = count;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setRelativeAccuracy(double accuracy) {
+        optimizer.setRelativeAccuracy(accuracy);
+    }
+
+    /** Get all the optima found during the last call to {@link
+     * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}.
+     * <p>The optimizer stores all the optima found during a set of
+     * restarts. The {@link #optimize(UnivariateRealFunction, GoalType,
+     * double, double) optimize} method returns the best point only. This
+     * method returns all the points found at the end of each starts,
+     * including the best one already returned by the {@link
+     * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}
+     * method.
+     * </p>
+     * <p>
+     * The returned array as one element for each start as specified
+     * in the constructor. It is ordered with the results from the
+     * runs that did converge first, sorted from best to worst
+     * objective value (i.e in ascending order if minimizing and in
+     * descending order if maximizing), followed by Double.NaN elements
+     * corresponding to the runs that did not converge. This means all
+     * elements will be NaN if the {@link #optimize(UnivariateRealFunction,
+     * GoalType, double, double) optimize} method did throw a {@link
+     * ConvergenceException ConvergenceException}). This also means that
+     * if the first element is not NaN, it is the best point found across
+     * all starts.</p>
+     * @return array containing the optima
+     * @exception IllegalStateException if {@link #optimize(UnivariateRealFunction,
+     * GoalType, double, double) optimize} has not been called
+     * @see #getOptimaValues()
+     */
+    public double[] getOptima() throws IllegalStateException {
+        if (optima == null) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
+        }
+        return optima.clone();
+    }
+
+    /** Get all the function values at optima found during the last call to {@link
+     * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}.
+     * <p>
+     * The returned array as one element for each start as specified
+     * in the constructor. It is ordered with the results from the
+     * runs that did converge first, sorted from best to worst
+     * objective value (i.e in ascending order if minimizing and in
+     * descending order if maximizing), followed by Double.NaN elements
+     * corresponding to the runs that did not converge. This means all
+     * elements will be NaN if the {@link #optimize(UnivariateRealFunction,
+     * GoalType, double, double) optimize} method did throw a {@link
+     * ConvergenceException ConvergenceException}). This also means that
+     * if the first element is not NaN, it is the best point found across
+     * all starts.</p>
+     * @return array containing the optima
+     * @exception IllegalStateException if {@link #optimize(UnivariateRealFunction,
+     * GoalType, double, double) optimize} has not been called
+     * @see #getOptima()
+     */
+    public double[] getOptimaValues() throws IllegalStateException {
+        if (optimaValues == null) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
+        }
+        return optimaValues.clone();
+    }
+
+    /** {@inheritDoc} */
+    public double optimize(final UnivariateRealFunction f, final GoalType goalType,
+                           final double min, final double max)
+        throws ConvergenceException, FunctionEvaluationException {
+
+        optima           = new double[starts];
+        optimaValues     = new double[starts];
+        totalIterations  = 0;
+        totalEvaluations = 0;
+
+        // multi-start loop
+        for (int i = 0; i < starts; ++i) {
+
+            try {
+                optimizer.setMaximalIterationCount(maxIterations - totalIterations);
+                optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
+                final double bound1 = (i == 0) ? min : min + generator.nextDouble() * (max - min);
+                final double bound2 = (i == 0) ? max : min + generator.nextDouble() * (max - min);
+                optima[i]       = optimizer.optimize(f, goalType,
+                                                     FastMath.min(bound1, bound2),
+                                                     FastMath.max(bound1, bound2));
+                optimaValues[i] = optimizer.getFunctionValue();
+            } catch (FunctionEvaluationException fee) {
+                optima[i]       = Double.NaN;
+                optimaValues[i] = Double.NaN;
+            } catch (ConvergenceException ce) {
+                optima[i]       = Double.NaN;
+                optimaValues[i] = Double.NaN;
+            }
+
+            totalIterations  += optimizer.getIterationCount();
+            totalEvaluations += optimizer.getEvaluations();
+
+        }
+
+        // sort the optima from best to worst, followed by NaN elements
+        int lastNaN = optima.length;
+        for (int i = 0; i < lastNaN; ++i) {
+            if (Double.isNaN(optima[i])) {
+                optima[i] = optima[--lastNaN];
+                optima[lastNaN + 1] = Double.NaN;
+                optimaValues[i] = optimaValues[--lastNaN];
+                optimaValues[lastNaN + 1] = Double.NaN;
+            }
+        }
+
+        double currX = optima[0];
+        double currY = optimaValues[0];
+        for (int j = 1; j < lastNaN; ++j) {
+            final double prevY = currY;
+            currX = optima[j];
+            currY = optimaValues[j];
+            if ((goalType == GoalType.MAXIMIZE) ^ (currY < prevY)) {
+                // the current element should be inserted closer to the beginning
+                int i = j - 1;
+                double mIX = optima[i];
+                double mIY = optimaValues[i];
+                while ((i >= 0) && ((goalType == GoalType.MAXIMIZE) ^ (currY < mIY))) {
+                    optima[i + 1]       = mIX;
+                    optimaValues[i + 1] = mIY;
+                    if (i-- != 0) {
+                        mIX = optima[i];
+                        mIY = optimaValues[i];
+                    } else {
+                        mIX = Double.NaN;
+                        mIY = Double.NaN;
+                    }
+                }
+                optima[i + 1]       = currX;
+                optimaValues[i + 1] = currY;
+                currX = optima[j];
+                currY = optimaValues[j];
+            }
+        }
+
+        if (Double.isNaN(optima[0])) {
+            throw new OptimizationException(
+                    LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT,
+                    starts);
+        }
+
+        // return the found point given the best objective function value
+        return optima[0];
+
+    }
+
+    /** {@inheritDoc} */
+    public double optimize(final UnivariateRealFunction f, final GoalType goalType,
+                           final double min, final double max, final double startValue)
+            throws ConvergenceException, FunctionEvaluationException {
+        return optimize(f, goalType, min, max);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java
new file mode 100644
index 0000000..d63afcd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/MultivariateRealOptimizer.java
@@ -0,0 +1,101 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+
+/**
+ * This interface represents an optimization algorithm for {@link MultivariateRealFunction
+ * scalar objective functions}.
+ * <p>Optimization algorithms find the input point set that either {@link GoalType
+ * maximize or minimize} an objective function.</p>
+ * @see DifferentiableMultivariateRealOptimizer
+ * @see DifferentiableMultivariateVectorialOptimizer
+ * @version $Revision: 1065481 $ $Date: 2011-01-31 06:31:41 +0100 (lun. 31 janv. 2011) $
+ * @since 2.0
+ */
+public interface MultivariateRealOptimizer {
+
+    /** Set the maximal number of iterations of the algorithm.
+     * @param maxIterations maximal number of algorithm iterations
+     */
+    void setMaxIterations(int maxIterations);
+
+    /** Get the maximal number of iterations of the algorithm.
+     * @return maximal number of iterations
+     */
+    int getMaxIterations();
+
+    /** Set the maximal number of functions evaluations.
+     * @param maxEvaluations maximal number of function evaluations
+     */
+    void setMaxEvaluations(int maxEvaluations);
+
+    /** Get the maximal number of functions evaluations.
+     * @return maximal number of functions evaluations
+     */
+    int getMaxEvaluations();
+
+    /** Get the number of iterations realized by the algorithm.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@link #optimize(MultivariateRealFunction, GoalType, double[]) optimize}
+     * method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of iterations
+     */
+    int getIterations();
+
+    /** Get the number of evaluations of the objective function.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@link #optimize(MultivariateRealFunction, GoalType, double[]) optimize}
+     * method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of evaluations of the objective function
+     */
+    int getEvaluations();
+
+    /** Set the convergence checker.
+     * @param checker object to use to check for convergence
+     */
+    void setConvergenceChecker(RealConvergenceChecker checker);
+
+    /** Get the convergence checker.
+     * @return object used to check for convergence
+     */
+    RealConvergenceChecker getConvergenceChecker();
+
+    /** Optimizes an objective function.
+     * @param f objective function
+     * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE}
+     * or {@link GoalType#MINIMIZE}
+     * @param startPoint the start point for optimization
+     * @return the point/value pair giving the optimal value for objective function
+     * @exception FunctionEvaluationException if the objective function throws one during
+     * the search
+     * @exception OptimizationException if the algorithm failed to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    RealPointValuePair optimize(MultivariateRealFunction f,
+                                  GoalType goalType,
+                                  double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/OptimizationException.java b/src/main/java/org/apache/commons/math/optimization/OptimizationException.java
new file mode 100644
index 0000000..b76f51a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/OptimizationException.java
@@ -0,0 +1,68 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.exception.util.DummyLocalizable;
+import org.apache.commons.math.exception.util.Localizable;
+
+/**
+ * This class represents exceptions thrown by optimizers.
+ *
+ * @version $Revision: 1044015 $ $Date: 2010-12-09 17:06:26 +0100 (jeu. 09 déc. 2010) $
+ * @since 1.2
+ * @deprecated in 2.2 (to be removed in 3.0).
+ */
+
+public class OptimizationException extends ConvergenceException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -4605887730798282127L;
+
+    /**
+     * Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @deprecated as of 2.2 replaced by {@link #OptimizationException(Localizable, Object...)}
+     */
+    @Deprecated
+    public OptimizationException(String specifier, Object ... parts) {
+        this(new DummyLocalizable(specifier), parts);
+    }
+
+    /**
+     * Simple constructor.
+     * Build an exception by translating and formating a message
+     * @param specifier format specifier (to be translated)
+     * @param parts to insert in the format (no translation)
+     * @since 2.2
+     */
+    public OptimizationException(Localizable specifier, Object ... parts) {
+        super(specifier, parts);
+    }
+
+    /**
+     * Create an exception with a given root cause.
+     * @param cause  the exception or error that caused this exception to be thrown
+     */
+    public OptimizationException(Throwable cause) {
+        super(cause);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/RealConvergenceChecker.java b/src/main/java/org/apache/commons/math/optimization/RealConvergenceChecker.java
new file mode 100644
index 0000000..0ab37f5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/RealConvergenceChecker.java
@@ -0,0 +1,55 @@
+/*
+ * 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.optimization;
+
+/** This interface specifies how to check if an {@link MultivariateRealOptimizer optimization
+ * algorithm} has converged.
+ *
+ * <p>Deciding if convergence has been reached is a problem-dependent issue. The
+ * user should provide a class implementing this interface to allow the optimization
+ * algorithm to stop its search according to the problem at hand.</p>
+ * <p>For convenience, two implementations that fit simple needs are already provided:
+ * {@link SimpleScalarValueChecker} and {@link SimpleRealPointChecker}. The first
+ * one considers convergence is reached when the objective function value does not
+ * change much anymore, it does not use the point set at all. The second one
+ * considers convergence is reached when the input point set does not change
+ * much anymore, it does not use objective function value at all.</p>
+ *
+ * @version $Revision: 799857 $ $Date: 2009-08-01 15:07:12 +0200 (sam. 01 août 2009) $
+ * @since 2.0
+ */
+
+public interface RealConvergenceChecker {
+
+  /** Check if the optimization algorithm has converged considering the last points.
+   * <p>
+   * This method may be called several time from the same algorithm iteration with
+   * different points. This can be detected by checking the iteration number at each
+   * call if needed. Each time this method is called, the previous and current point
+   * correspond to points with the same role at each iteration, so they can be
+   * compared. As an example, simplex-based algorithms call this method for all
+   * points of the simplex, not only for the best or worst ones.
+   * </p>
+   * @param iteration index of current iteration
+   * @param previous point from previous iteration
+   * @param current point from current iteration
+   * @return true if the algorithm is considered to have converged
+   */
+  boolean converged(int iteration, RealPointValuePair previous, RealPointValuePair current);
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/RealPointValuePair.java b/src/main/java/org/apache/commons/math/optimization/RealPointValuePair.java
new file mode 100644
index 0000000..25ecec9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/RealPointValuePair.java
@@ -0,0 +1,88 @@
+/*
+ * 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.optimization;
+
+import java.io.Serializable;
+
+
+/**
+ * This class holds a point and the value of an objective function at this point.
+ * <p>This is a simple immutable container.</p>
+ * @see VectorialPointValuePair
+ * @see org.apache.commons.math.analysis.MultivariateRealFunction
+ * @version $Revision: 980981 $ $Date: 2010-07-31 00:03:04 +0200 (sam. 31 juil. 2010) $
+ * @since 2.0
+ */
+public class RealPointValuePair implements Serializable {
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 1003888396256744753L;
+
+    /** Point coordinates. */
+    private final double[] point;
+
+    /** Value of the objective function at the point. */
+    private final double value;
+
+    /** Build a point/objective function value pair.
+     * @param point point coordinates (the built instance will store
+     * a copy of the array, not the array passed as argument)
+     * @param value value of an objective function at the point
+     */
+    public RealPointValuePair(final double[] point, final double value) {
+        this.point = (point == null) ? null : point.clone();
+        this.value  = value;
+    }
+
+    /** Build a point/objective function value pair.
+     * @param point point coordinates (the built instance will store
+     * a copy of the array, not the array passed as argument)
+     * @param value value of an objective function at the point
+     * @param copyArray if true, the input array will be copied, otherwise
+     * it will be referenced
+     */
+    public RealPointValuePair(final double[] point, final double value,
+                              final boolean copyArray) {
+        this.point = copyArray ?
+                     ((point == null) ? null : point.clone()) :
+                     point;
+        this.value  = value;
+    }
+
+    /** Get the point.
+     * @return a copy of the stored point
+     */
+    public double[] getPoint() {
+        return (point == null) ? null : point.clone();
+    }
+
+    /** Get a reference to the point.
+     * <p>This method is provided as a convenience to avoid copying
+     * the array, the elements of the array should <em>not</em> be modified.</p>
+     * @return a reference to the internal array storing the point
+     */
+    public double[] getPointRef() {
+        return point;
+    }
+
+    /** Get the value of the objective function.
+     * @return the stored value of the objective function
+     */
+    public double getValue() {
+        return value;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/SimpleRealPointChecker.java b/src/main/java/org/apache/commons/math/optimization/SimpleRealPointChecker.java
new file mode 100644
index 0000000..6cf0725
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/SimpleRealPointChecker.java
@@ -0,0 +1,87 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Simple implementation of the {@link RealConvergenceChecker} interface using
+ * only point coordinates.
+ * <p>
+ * Convergence is considered to have been reached if either the relative
+ * difference between each point coordinate are smaller than a threshold
+ * or if either the absolute difference between the point coordinates are
+ * smaller than another threshold.
+ * </p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class SimpleRealPointChecker implements RealConvergenceChecker {
+
+    /** Default relative threshold. */
+    private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON;
+
+    /** Default absolute threshold. */
+    private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN;
+
+    /** Relative tolerance threshold. */
+    private final double relativeThreshold;
+
+    /** Absolute tolerance threshold. */
+    private final double absoluteThreshold;
+
+   /** Build an instance with default threshold.
+     */
+    public SimpleRealPointChecker() {
+        this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD;
+        this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD;
+    }
+
+    /** Build an instance with a specified threshold.
+     * <p>
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     * </p>
+     * @param relativeThreshold relative tolerance threshold
+     * @param absoluteThreshold absolute tolerance threshold
+     */
+    public SimpleRealPointChecker(final double relativeThreshold,
+                                 final double absoluteThreshold) {
+        this.relativeThreshold = relativeThreshold;
+        this.absoluteThreshold = absoluteThreshold;
+    }
+
+    /** {@inheritDoc} */
+    public boolean converged(final int iteration,
+                             final RealPointValuePair previous,
+                             final RealPointValuePair current) {
+        final double[] p        = previous.getPoint();
+        final double[] c        = current.getPoint();
+        for (int i = 0; i < p.length; ++i) {
+            final double difference = FastMath.abs(p[i] - c[i]);
+            final double size       = FastMath.max(FastMath.abs(p[i]), FastMath.abs(c[i]));
+            if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/SimpleScalarValueChecker.java b/src/main/java/org/apache/commons/math/optimization/SimpleScalarValueChecker.java
new file mode 100644
index 0000000..fbfd30c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/SimpleScalarValueChecker.java
@@ -0,0 +1,81 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Simple implementation of the {@link RealConvergenceChecker} interface using
+ * only objective function values.
+ * <p>
+ * Convergence is considered to have been reached if either the relative
+ * difference between the objective function values is smaller than a
+ * threshold or if either the absolute difference between the objective
+ * function values is smaller than another threshold.
+ * </p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class SimpleScalarValueChecker implements RealConvergenceChecker {
+
+    /** Default relative threshold. */
+    private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON;
+
+    /** Default absolute threshold. */
+    private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN;
+
+    /** Relative tolerance threshold. */
+    private final double relativeThreshold;
+
+    /** Absolute tolerance threshold. */
+    private final double absoluteThreshold;
+
+   /** Build an instance with default threshold.
+     */
+    public SimpleScalarValueChecker() {
+        this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD;
+        this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD;
+    }
+
+    /** Build an instance with a specified threshold.
+     * <p>
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     * </p>
+     * @param relativeThreshold relative tolerance threshold
+     * @param absoluteThreshold absolute tolerance threshold
+     */
+    public SimpleScalarValueChecker(final double relativeThreshold,
+                                    final double absoluteThreshold) {
+        this.relativeThreshold = relativeThreshold;
+        this.absoluteThreshold = absoluteThreshold;
+    }
+
+    /** {@inheritDoc} */
+    public boolean converged(final int iteration,
+                             final RealPointValuePair previous,
+                             final RealPointValuePair current) {
+        final double p          = previous.getValue();
+        final double c          = current.getValue();
+        final double difference = FastMath.abs(p - c);
+        final double size       = FastMath.max(FastMath.abs(p), FastMath.abs(c));
+        return (difference <= (size * relativeThreshold)) || (difference <= absoluteThreshold);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/SimpleVectorialPointChecker.java b/src/main/java/org/apache/commons/math/optimization/SimpleVectorialPointChecker.java
new file mode 100644
index 0000000..0c69ca8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/SimpleVectorialPointChecker.java
@@ -0,0 +1,90 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Simple implementation of the {@link VectorialConvergenceChecker} interface using
+ * only point coordinates.
+ * <p>
+ * Convergence is considered to have been reached if either the relative
+ * difference between each point coordinate are smaller than a threshold
+ * or if either the absolute difference between the point coordinates are
+ * smaller than another threshold.
+ * </p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class SimpleVectorialPointChecker implements VectorialConvergenceChecker {
+
+    /** Default relative threshold. */
+    private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON;
+
+    /** Default absolute threshold. */
+    private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN;
+
+    /** Relative tolerance threshold. */
+    private final double relativeThreshold;
+
+    /** Absolute tolerance threshold. */
+    private final double absoluteThreshold;
+
+   /** Build an instance with default threshold.
+     */
+    public SimpleVectorialPointChecker() {
+        this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD;
+        this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD;
+    }
+
+    /** Build an instance with a specified threshold.
+     * <p>
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     * </p>
+     * @param relativeThreshold relative tolerance threshold
+     * @param absoluteThreshold absolute tolerance threshold
+     */
+    public SimpleVectorialPointChecker(final double relativeThreshold,
+                                       final double absoluteThreshold) {
+        this.relativeThreshold = relativeThreshold;
+        this.absoluteThreshold = absoluteThreshold;
+    }
+
+    /** {@inheritDoc} */
+    public boolean converged(final int iteration,
+                             final VectorialPointValuePair previous,
+                             final VectorialPointValuePair current) {
+        final double[] p = previous.getPointRef();
+        final double[] c = current.getPointRef();
+        for (int i = 0; i < p.length; ++i) {
+            final double pi         = p[i];
+            final double ci         = c[i];
+            final double difference = FastMath.abs(pi - ci);
+            final double size       = FastMath.max(FastMath.abs(pi), FastMath.abs(ci));
+            if ((difference > (size * relativeThreshold)) &&
+                (difference > absoluteThreshold)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/SimpleVectorialValueChecker.java b/src/main/java/org/apache/commons/math/optimization/SimpleVectorialValueChecker.java
new file mode 100644
index 0000000..8be67ee
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/SimpleVectorialValueChecker.java
@@ -0,0 +1,90 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Simple implementation of the {@link VectorialConvergenceChecker} interface using
+ * only objective function values.
+ * <p>
+ * Convergence is considered to have been reached if either the relative
+ * difference between the objective function values is smaller than a
+ * threshold or if either the absolute difference between the objective
+ * function values is smaller than another threshold for all vectors elements.
+ * </p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class SimpleVectorialValueChecker implements VectorialConvergenceChecker {
+
+    /** Default relative threshold. */
+    private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON;
+
+    /** Default absolute threshold. */
+    private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN;
+
+    /** Relative tolerance threshold. */
+    private final double relativeThreshold;
+
+    /** Absolute tolerance threshold. */
+    private final double absoluteThreshold;
+
+   /** Build an instance with default threshold.
+     */
+    public SimpleVectorialValueChecker() {
+        this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD;
+        this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD;
+    }
+
+    /** Build an instance with a specified threshold.
+     * <p>
+     * In order to perform only relative checks, the absolute tolerance
+     * must be set to a negative value. In order to perform only absolute
+     * checks, the relative tolerance must be set to a negative value.
+     * </p>
+     * @param relativeThreshold relative tolerance threshold
+     * @param absoluteThreshold absolute tolerance threshold
+     */
+    public SimpleVectorialValueChecker(final double relativeThreshold,
+                                       final double absoluteThreshold) {
+        this.relativeThreshold = relativeThreshold;
+        this.absoluteThreshold = absoluteThreshold;
+    }
+
+    /** {@inheritDoc} */
+    public boolean converged(final int iteration,
+                             final VectorialPointValuePair previous,
+                             final VectorialPointValuePair current) {
+        final double[] p        = previous.getValueRef();
+        final double[] c        = current.getValueRef();
+        for (int i = 0; i < p.length; ++i) {
+            final double pi         = p[i];
+            final double ci         = c[i];
+            final double difference = FastMath.abs(pi - ci);
+            final double size       = FastMath.max(FastMath.abs(pi), FastMath.abs(ci));
+            if ((difference > (size * relativeThreshold)) &&
+                (difference > absoluteThreshold)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/UnivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/UnivariateRealOptimizer.java
new file mode 100644
index 0000000..df17133
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/UnivariateRealOptimizer.java
@@ -0,0 +1,116 @@
+/*
+ * 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.optimization;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.ConvergingAlgorithm;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+
+/**
+ * Interface for (univariate real) optimization algorithms.
+ *
+ * @version $Revision: 1073658 $ $Date: 2011-02-23 10:45:42 +0100 (mer. 23 févr. 2011) $
+ * @since 2.0
+ */
+public interface UnivariateRealOptimizer extends ConvergingAlgorithm {
+
+    /** Set the maximal number of functions evaluations.
+     * @param maxEvaluations maximal number of function evaluations
+     */
+    void setMaxEvaluations(int maxEvaluations);
+
+    /** Get the maximal number of functions evaluations.
+     * @return the maximal number of functions evaluations.
+     */
+    int getMaxEvaluations();
+
+    /** Get the number of evaluations of the objective function.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@link #optimize(UnivariateRealFunction, GoalType, double, double) optimize}
+     * method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return the number of evaluations of the objective function.
+     */
+    int getEvaluations();
+
+    /**
+     * Find an optimum in the given interval.
+     * <p>
+     * An optimizer may require that the interval brackets a single optimum.
+     * </p>
+     * @param f the function to optimize.
+     * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE}
+     * or {@link GoalType#MINIMIZE}.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @return a value where the function is optimum.
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the optimizer detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function.
+     * @throws IllegalArgumentException if min > max or the endpoints do not
+     * satisfy the requirements specified by the optimizer.
+     */
+    double optimize(UnivariateRealFunction f, GoalType goalType,
+                    double min, double max)
+        throws ConvergenceException, FunctionEvaluationException;
+
+    /**
+     * Find an optimum in the given interval, start at startValue.
+     * <p>
+     * An optimizer may require that the interval brackets a single optimum.
+     * </p>
+     * @param f the function to optimize.
+     * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE}
+     * or {@link GoalType#MINIMIZE}.
+     * @param min the lower bound for the interval.
+     * @param max the upper bound for the interval.
+     * @param startValue the start value to use.
+     * @return a value where the function is optimum.
+     * @throws ConvergenceException if the maximum iteration count is exceeded
+     * or the optimizer detects convergence problems otherwise.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function.
+     * @throws IllegalArgumentException if min > max or the arguments do not
+     * satisfy the requirements specified by the optimizer.
+     * @throws IllegalStateException if there are no data.
+     */
+    double optimize(UnivariateRealFunction f, GoalType goalType,
+                    double min, double max, double startValue)
+        throws ConvergenceException, FunctionEvaluationException;
+
+    /**
+     * Get the result of the last run of the optimizer.
+     *
+     * @return the optimum.
+     * @throws IllegalStateException if there is no result available, either
+     * because no result was yet computed or the last attempt failed.
+     */
+    double getResult();
+
+    /**
+     * Get the result of the last run of the optimizer.
+     *
+     * @return the value of the function at the optimum.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function.
+     * @throws IllegalStateException if there is no result available, either
+     * because no result was yet computed or the last attempt failed.
+     */
+    double getFunctionValue() throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/VectorialConvergenceChecker.java b/src/main/java/org/apache/commons/math/optimization/VectorialConvergenceChecker.java
new file mode 100644
index 0000000..e2befd6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/VectorialConvergenceChecker.java
@@ -0,0 +1,55 @@
+/*
+ * 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.optimization;
+
+/** This interface specifies how to check if a {@link
+ * DifferentiableMultivariateVectorialOptimizer optimization algorithm} has converged.
+ *
+ * <p>Deciding if convergence has been reached is a problem-dependent issue. The
+ * user should provide a class implementing this interface to allow the optimization
+ * algorithm to stop its search according to the problem at hand.</p>
+ * <p>For convenience, two implementations that fit simple needs are already provided:
+ * {@link SimpleVectorialValueChecker} and {@link SimpleVectorialPointChecker}. The first
+ * one considers convergence is reached when the objective function value does not
+ * change much anymore, it does not use the point set at all. The second one
+ * considers convergence is reached when the input point set does not change
+ * much anymore, it does not use objective function value at all.</p>
+ *
+ * @version $Revision: 780674 $ $Date: 2009-06-01 17:10:55 +0200 (lun. 01 juin 2009) $
+ * @since 2.0
+ */
+
+public interface VectorialConvergenceChecker {
+
+  /** Check if the optimization algorithm has converged considering the last points.
+   * <p>
+   * This method may be called several time from the same algorithm iteration with
+   * different points. This can be detected by checking the iteration number at each
+   * call if needed. Each time this method is called, the previous and current point
+   * correspond to points with the same role at each iteration, so they can be
+   * compared. As an example, simplex-based algorithms call this method for all
+   * points of the simplex, not only for the best or worst ones.
+   * </p>
+   * @param iteration index of current iteration
+   * @param previous point from previous iteration
+   * @param current point from current iteration
+   * @return true if the algorithm is considered to have converged
+   */
+  boolean converged(int iteration, VectorialPointValuePair previous, VectorialPointValuePair current);
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/VectorialPointValuePair.java b/src/main/java/org/apache/commons/math/optimization/VectorialPointValuePair.java
new file mode 100644
index 0000000..13f1134
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/VectorialPointValuePair.java
@@ -0,0 +1,100 @@
+/*
+ * 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.optimization;
+
+import java.io.Serializable;
+
+/**
+ * This class holds a point and the vectorial value of an objective function at this point.
+ * <p>This is a simple immutable container.</p>
+ * @see RealPointValuePair
+ * @see org.apache.commons.math.analysis.MultivariateVectorialFunction
+ * @version $Revision: 980981 $ $Date: 2010-07-31 00:03:04 +0200 (sam. 31 juil. 2010) $
+ * @since 2.0
+ */
+public class VectorialPointValuePair implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 1003888396256744753L;
+
+    /** Point coordinates. */
+    private final double[] point;
+
+    /** Vectorial value of the objective function at the point. */
+    private final double[] value;
+
+    /** Build a point/objective function value pair.
+     * @param point point coordinates (the built instance will store
+     * a copy of the array, not the array passed as argument)
+     * @param value value of an objective function at the point
+     */
+    public VectorialPointValuePair(final double[] point, final double[] value) {
+        this.point = (point == null) ? null : point.clone();
+        this.value = (value == null) ? null : value.clone();
+    }
+
+    /** Build a point/objective function value pair.
+     * @param point point coordinates (the built instance will store
+     * a copy of the array, not the array passed as argument)
+     * @param value value of an objective function at the point
+     * @param copyArray if true, the input arrays will be copied, otherwise
+     * they will be referenced
+     */
+    public VectorialPointValuePair(final double[] point, final double[] value,
+                                   final boolean copyArray) {
+        this.point = copyArray ?
+                      ((point == null) ? null : point.clone()) :
+                      point;
+        this.value = copyArray ?
+                      ((value == null) ? null : value.clone()) :
+                      value;
+    }
+
+    /** Get the point.
+     * @return a copy of the stored point
+     */
+    public double[] getPoint() {
+        return (point == null) ? null : point.clone();
+    }
+
+    /** Get a reference to the point.
+     * <p>This method is provided as a convenience to avoid copying
+     * the array, the elements of the array should <em>not</em> be modified.</p>
+     * @return a reference to the internal array storing the point
+     */
+    public double[] getPointRef() {
+        return point;
+    }
+
+    /** Get the value of the objective function.
+     * @return a copy of the stored value of the objective function
+     */
+    public double[] getValue() {
+        return (value == null) ? null : value.clone();
+    }
+
+    /** Get a reference to the value of the objective function.
+     * <p>This method is provided as a convenience to avoid copying
+     * the array, the elements of the array should <em>not</em> be modified.</p>
+     * @return a reference to the internal array storing the value of the objective function
+     */
+    public double[] getValueRef() {
+        return value;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java b/src/main/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java
new file mode 100644
index 0000000..3f9fac2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.java
@@ -0,0 +1,418 @@
+/*
+ * 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.optimization.direct;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.MultivariateRealOptimizer;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealConvergenceChecker;
+import org.apache.commons.math.optimization.RealPointValuePair;
+import org.apache.commons.math.optimization.SimpleScalarValueChecker;
+
+/**
+ * This class implements simplex-based direct search optimization
+ * algorithms.
+ *
+ * <p>Direct search methods only use objective function values, they don't
+ * need derivatives and don't either try to compute approximation of
+ * the derivatives. According to a 1996 paper by Margaret H. Wright
+ * (<a href="http://cm.bell-labs.com/cm/cs/doc/96/4-02.ps.gz">Direct
+ * Search Methods: Once Scorned, Now Respectable</a>), they are used
+ * when either the computation of the derivative is impossible (noisy
+ * functions, unpredictable discontinuities) or difficult (complexity,
+ * computation cost). In the first cases, rather than an optimum, a
+ * <em>not too bad</em> point is desired. In the latter cases, an
+ * optimum is desired but cannot be reasonably found. In all cases
+ * direct search methods can be useful.</p>
+ *
+ * <p>Simplex-based direct search methods are based on comparison of
+ * the objective function values at the vertices of a simplex (which is a
+ * set of n+1 points in dimension n) that is updated by the algorithms
+ * steps.<p>
+ *
+ * <p>The initial configuration of the simplex can be set using either
+ * {@link #setStartConfiguration(double[])} or {@link
+ * #setStartConfiguration(double[][])}. If neither method has been called
+ * before optimization is attempted, an explicit call to the first method
+ * with all steps set to +1 is triggered, thus building a default
+ * configuration from a unit hypercube. Each call to {@link
+ * #optimize(MultivariateRealFunction, GoalType, double[]) optimize} will reuse
+ * the current start configuration and move it such that its first vertex
+ * is at the provided start point of the optimization. If the {@code optimize}
+ * method is called to solve a different problem and the number of parameters
+ * change, the start configuration will be reset to a default one with the
+ * appropriate dimensions.</p>
+ *
+ * <p>If {@link #setConvergenceChecker(RealConvergenceChecker)} is not called,
+ * a default {@link SimpleScalarValueChecker} is used.</p>
+ *
+ * <p>Convergence is checked by providing the <em>worst</em> points of
+ * previous and current simplex to the convergence checker, not the best ones.</p>
+ *
+ * <p>This class is the base class performing the boilerplate simplex
+ * initialization and handling. The simplex update by itself is
+ * performed by the derived classes according to the implemented
+ * algorithms.</p>
+ *
+ * implements MultivariateRealOptimizer since 2.0
+ *
+ * @see MultivariateRealFunction
+ * @see NelderMead
+ * @see MultiDirectional
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public abstract class DirectSearchOptimizer implements MultivariateRealOptimizer {
+
+    /** Simplex. */
+    protected RealPointValuePair[] simplex;
+
+    /** Objective function. */
+    private MultivariateRealFunction f;
+
+    /** Convergence checker. */
+    private RealConvergenceChecker checker;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Number of iterations already performed. */
+    private int iterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed. */
+    private int evaluations;
+
+    /** Start simplex configuration. */
+    private double[][] startConfiguration;
+
+    /** Simple constructor.
+     */
+    protected DirectSearchOptimizer() {
+        setConvergenceChecker(new SimpleScalarValueChecker());
+        setMaxIterations(Integer.MAX_VALUE);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** Set start configuration for simplex.
+     * <p>The start configuration for simplex is built from a box parallel to
+     * the canonical axes of the space. The simplex is the subset of vertices
+     * of a box parallel to the canonical axes. It is built as the path followed
+     * while traveling from one vertex of the box to the diagonally opposite
+     * vertex moving only along the box edges. The first vertex of the box will
+     * be located at the start point of the optimization.</p>
+     * <p>As an example, in dimension 3 a simplex has 4 vertices. Setting the
+     * steps to (1, 10, 2) and the start point to (1, 1, 1) would imply the
+     * start simplex would be: { (1, 1, 1), (2, 1, 1), (2, 11, 1), (2, 11, 3) }.
+     * The first vertex would be set to the start point at (1, 1, 1) and the
+     * last vertex would be set to the diagonally opposite vertex at (2, 11, 3).</p>
+     * @param steps steps along the canonical axes representing box edges,
+     * they may be negative but not null
+     * @exception IllegalArgumentException if one step is null
+     */
+    public void setStartConfiguration(final double[] steps)
+        throws IllegalArgumentException {
+        // only the relative position of the n final vertices with respect
+        // to the first one are stored
+        final int n = steps.length;
+        startConfiguration = new double[n][n];
+        for (int i = 0; i < n; ++i) {
+            final double[] vertexI = startConfiguration[i];
+            for (int j = 0; j < i + 1; ++j) {
+                if (steps[j] == 0.0) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.EQUAL_VERTICES_IN_SIMPLEX, j, j + 1);
+                }
+                System.arraycopy(steps, 0, vertexI, 0, j + 1);
+            }
+        }
+    }
+
+    /** Set start configuration for simplex.
+     * <p>The real initial simplex will be set up by moving the reference
+     * simplex such that its first point is located at the start point of the
+     * optimization.</p>
+     * @param referenceSimplex reference simplex
+     * @exception IllegalArgumentException if the reference simplex does not
+     * contain at least one point, or if there is a dimension mismatch
+     * in the reference simplex or if one of its vertices is duplicated
+     */
+    public void setStartConfiguration(final double[][] referenceSimplex)
+        throws IllegalArgumentException {
+
+        // only the relative position of the n final vertices with respect
+        // to the first one are stored
+        final int n = referenceSimplex.length - 1;
+        if (n < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.SIMPLEX_NEED_ONE_POINT);
+        }
+        startConfiguration = new double[n][n];
+        final double[] ref0 = referenceSimplex[0];
+
+        // vertices loop
+        for (int i = 0; i < n + 1; ++i) {
+
+            final double[] refI = referenceSimplex[i];
+
+            // safety checks
+            if (refI.length != n) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, refI.length, n);
+            }
+            for (int j = 0; j < i; ++j) {
+                final double[] refJ = referenceSimplex[j];
+                boolean allEquals = true;
+                for (int k = 0; k < n; ++k) {
+                    if (refI[k] != refJ[k]) {
+                        allEquals = false;
+                        break;
+                    }
+                }
+                if (allEquals) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.EQUAL_VERTICES_IN_SIMPLEX, i, j);
+                }
+            }
+
+            // store vertex i position relative to vertex 0 position
+            if (i > 0) {
+                final double[] confI = startConfiguration[i - 1];
+                for (int k = 0; k < n; ++k) {
+                    confI[k] = refI[k] - ref0[k];
+                }
+            }
+
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return iterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return evaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) {
+        this.checker = convergenceChecker;
+    }
+
+    /** {@inheritDoc} */
+    public RealConvergenceChecker getConvergenceChecker() {
+        return checker;
+    }
+
+    /** {@inheritDoc} */
+    public RealPointValuePair optimize(final MultivariateRealFunction function,
+                                       final GoalType goalType,
+                                       final double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        if ((startConfiguration == null) ||
+            (startConfiguration.length != startPoint.length)) {
+            // no initial configuration has been set up for simplex
+            // build a default one from a unit hypercube
+            final double[] unit = new double[startPoint.length];
+            Arrays.fill(unit, 1.0);
+            setStartConfiguration(unit);
+        }
+
+        this.f = function;
+        final Comparator<RealPointValuePair> comparator =
+            new Comparator<RealPointValuePair>() {
+                public int compare(final RealPointValuePair o1,
+                                   final RealPointValuePair o2) {
+                    final double v1 = o1.getValue();
+                    final double v2 = o2.getValue();
+                    return (goalType == GoalType.MINIMIZE) ?
+                            Double.compare(v1, v2) : Double.compare(v2, v1);
+                }
+            };
+
+        // initialize search
+        iterations  = 0;
+        evaluations = 0;
+        buildSimplex(startPoint);
+        evaluateSimplex(comparator);
+
+        RealPointValuePair[] previous = new RealPointValuePair[simplex.length];
+        while (true) {
+
+            if (iterations > 0) {
+                boolean converged = true;
+                for (int i = 0; i < simplex.length; ++i) {
+                    converged &= checker.converged(iterations, previous[i], simplex[i]);
+                }
+                if (converged) {
+                    // we have found an optimum
+                    return simplex[0];
+                }
+            }
+
+            // we still need to search
+            System.arraycopy(simplex, 0, previous, 0, simplex.length);
+            iterateSimplex(comparator);
+
+        }
+
+    }
+
+    /** Increment the iterations counter by 1.
+     * @exception OptimizationException if the maximal number
+     * of iterations is exceeded
+     */
+    protected void incrementIterationsCounter()
+        throws OptimizationException {
+        if (++iterations > maxIterations) {
+            throw new OptimizationException(new MaxIterationsExceededException(maxIterations));
+        }
+    }
+
+    /** Compute the next simplex of the algorithm.
+     * @param comparator comparator to use to sort simplex vertices from best to worst
+     * @exception FunctionEvaluationException if the function cannot be evaluated at
+     * some point
+     * @exception OptimizationException if the algorithm fails to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    protected abstract void iterateSimplex(final Comparator<RealPointValuePair> comparator)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
+    /** Evaluate the objective function on one point.
+     * <p>A side effect of this method is to count the number of
+     * function evaluations</p>
+     * @param x point on which the objective function should be evaluated
+     * @return objective function value at the given point
+     * @exception FunctionEvaluationException if no value can be computed for the
+     * parameters or if the maximal number of evaluations is exceeded
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    protected double evaluate(final double[] x)
+        throws FunctionEvaluationException, IllegalArgumentException {
+        if (++evaluations > maxEvaluations) {
+            throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), x);
+        }
+        return f.value(x);
+    }
+
+    /** Build an initial simplex.
+     * @param startPoint the start point for optimization
+     * @exception IllegalArgumentException if the start point does not match
+     * simplex dimension
+     */
+    private void buildSimplex(final double[] startPoint)
+        throws IllegalArgumentException {
+
+        final int n = startPoint.length;
+        if (n != startConfiguration.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, n, startConfiguration.length);
+        }
+
+        // set first vertex
+        simplex = new RealPointValuePair[n + 1];
+        simplex[0] = new RealPointValuePair(startPoint, Double.NaN);
+
+        // set remaining vertices
+        for (int i = 0; i < n; ++i) {
+            final double[] confI   = startConfiguration[i];
+            final double[] vertexI = new double[n];
+            for (int k = 0; k < n; ++k) {
+                vertexI[k] = startPoint[k] + confI[k];
+            }
+            simplex[i + 1] = new RealPointValuePair(vertexI, Double.NaN);
+        }
+
+    }
+
+    /** Evaluate all the non-evaluated points of the simplex.
+     * @param comparator comparator to use to sort simplex vertices from best to worst
+     * @exception FunctionEvaluationException if no value can be computed for the parameters
+     * @exception OptimizationException if the maximal number of evaluations is exceeded
+     */
+    protected void evaluateSimplex(final Comparator<RealPointValuePair> comparator)
+        throws FunctionEvaluationException, OptimizationException {
+
+        // evaluate the objective function at all non-evaluated simplex points
+        for (int i = 0; i < simplex.length; ++i) {
+            final RealPointValuePair vertex = simplex[i];
+            final double[] point = vertex.getPointRef();
+            if (Double.isNaN(vertex.getValue())) {
+                simplex[i] = new RealPointValuePair(point, evaluate(point), false);
+            }
+        }
+
+        // sort the simplex from best to worst
+        Arrays.sort(simplex, comparator);
+
+    }
+
+    /** Replace the worst point of the simplex by a new point.
+     * @param pointValuePair point to insert
+     * @param comparator comparator to use to sort simplex vertices from best to worst
+     */
+    protected void replaceWorstPoint(RealPointValuePair pointValuePair,
+                                     final Comparator<RealPointValuePair> comparator) {
+        int n = simplex.length - 1;
+        for (int i = 0; i < n; ++i) {
+            if (comparator.compare(simplex[i], pointValuePair) > 0) {
+                RealPointValuePair tmp = simplex[i];
+                simplex[i]         = pointValuePair;
+                pointValuePair     = tmp;
+            }
+        }
+        simplex[n] = pointValuePair;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java b/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
new file mode 100644
index 0000000..ea8816b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/direct/MultiDirectional.java
@@ -0,0 +1,144 @@
+/*
+ * 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.optimization.direct;
+
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealConvergenceChecker;
+import org.apache.commons.math.optimization.RealPointValuePair;
+
+/**
+ * This class implements the multi-directional direct search method.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @see NelderMead
+ * @since 1.2
+ */
+public class MultiDirectional extends DirectSearchOptimizer {
+
+    /** Expansion coefficient. */
+    private final double khi;
+
+    /** Contraction coefficient. */
+    private final double gamma;
+
+    /** Build a multi-directional optimizer with default coefficients.
+     * <p>The default values are 2.0 for khi and 0.5 for gamma.</p>
+     */
+    public MultiDirectional() {
+        this.khi   = 2.0;
+        this.gamma = 0.5;
+    }
+
+    /** Build a multi-directional optimizer with specified coefficients.
+     * @param khi expansion coefficient
+     * @param gamma contraction coefficient
+     */
+    public MultiDirectional(final double khi, final double gamma) {
+        this.khi   = khi;
+        this.gamma = gamma;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void iterateSimplex(final Comparator<RealPointValuePair> comparator)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        final RealConvergenceChecker checker = getConvergenceChecker();
+        while (true) {
+
+            incrementIterationsCounter();
+
+            // save the original vertex
+            final RealPointValuePair[] original = simplex;
+            final RealPointValuePair best = original[0];
+
+            // perform a reflection step
+            final RealPointValuePair reflected = evaluateNewSimplex(original, 1.0, comparator);
+            if (comparator.compare(reflected, best) < 0) {
+
+                // compute the expanded simplex
+                final RealPointValuePair[] reflectedSimplex = simplex;
+                final RealPointValuePair expanded = evaluateNewSimplex(original, khi, comparator);
+                if (comparator.compare(reflected, expanded) <= 0) {
+                    // accept the reflected simplex
+                    simplex = reflectedSimplex;
+                }
+
+                return;
+
+            }
+
+            // compute the contracted simplex
+            final RealPointValuePair contracted = evaluateNewSimplex(original, gamma, comparator);
+            if (comparator.compare(contracted, best) < 0) {
+                // accept the contracted simplex
+                return;
+            }
+
+            // check convergence
+            final int iter = getIterations();
+            boolean converged = true;
+            for (int i = 0; i < simplex.length; ++i) {
+                converged &= checker.converged(iter, original[i], simplex[i]);
+            }
+            if (converged) {
+                return;
+            }
+
+        }
+
+    }
+
+    /** Compute and evaluate a new simplex.
+     * @param original original simplex (to be preserved)
+     * @param coeff linear coefficient
+     * @param comparator comparator to use to sort simplex vertices from best to poorest
+     * @return best point in the transformed simplex
+     * @exception FunctionEvaluationException if the function cannot be evaluated at some point
+     * @exception OptimizationException if the maximal number of evaluations is exceeded
+     */
+    private RealPointValuePair evaluateNewSimplex(final RealPointValuePair[] original,
+                                              final double coeff,
+                                              final Comparator<RealPointValuePair> comparator)
+        throws FunctionEvaluationException, OptimizationException {
+
+        final double[] xSmallest = original[0].getPointRef();
+        final int n = xSmallest.length;
+
+        // create the linearly transformed simplex
+        simplex = new RealPointValuePair[n + 1];
+        simplex[0] = original[0];
+        for (int i = 1; i <= n; ++i) {
+            final double[] xOriginal    = original[i].getPointRef();
+            final double[] xTransformed = new double[n];
+            for (int j = 0; j < n; ++j) {
+                xTransformed[j] = xSmallest[j] + coeff * (xSmallest[j] - xOriginal[j]);
+            }
+            simplex[i] = new RealPointValuePair(xTransformed, Double.NaN, false);
+        }
+
+        // evaluate it
+        evaluateSimplex(comparator);
+        return simplex[0];
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/direct/NelderMead.java b/src/main/java/org/apache/commons/math/optimization/direct/NelderMead.java
new file mode 100644
index 0000000..8b8b205
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/direct/NelderMead.java
@@ -0,0 +1,181 @@
+/*
+ * 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.optimization.direct;
+
+import java.util.Comparator;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealPointValuePair;
+
+/**
+ * This class implements the Nelder-Mead direct search method.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @see MultiDirectional
+ * @since 1.2
+ */
+public class NelderMead extends DirectSearchOptimizer {
+
+    /** Reflection coefficient. */
+    private final double rho;
+
+    /** Expansion coefficient. */
+    private final double khi;
+
+    /** Contraction coefficient. */
+    private final double gamma;
+
+    /** Shrinkage coefficient. */
+    private final double sigma;
+
+    /** Build a Nelder-Mead optimizer with default coefficients.
+     * <p>The default coefficients are 1.0 for rho, 2.0 for khi and 0.5
+     * for both gamma and sigma.</p>
+     */
+    public NelderMead() {
+        this.rho   = 1.0;
+        this.khi   = 2.0;
+        this.gamma = 0.5;
+        this.sigma = 0.5;
+    }
+
+    /** Build a Nelder-Mead optimizer with specified coefficients.
+     * @param rho reflection coefficient
+     * @param khi expansion coefficient
+     * @param gamma contraction coefficient
+     * @param sigma shrinkage coefficient
+     */
+    public NelderMead(final double rho, final double khi,
+                      final double gamma, final double sigma) {
+        this.rho   = rho;
+        this.khi   = khi;
+        this.gamma = gamma;
+        this.sigma = sigma;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void iterateSimplex(final Comparator<RealPointValuePair> comparator)
+        throws FunctionEvaluationException, OptimizationException {
+
+        incrementIterationsCounter();
+
+        // the simplex has n+1 point if dimension is n
+        final int n = simplex.length - 1;
+
+        // interesting values
+        final RealPointValuePair best       = simplex[0];
+        final RealPointValuePair secondBest = simplex[n-1];
+        final RealPointValuePair worst      = simplex[n];
+        final double[] xWorst = worst.getPointRef();
+
+        // compute the centroid of the best vertices
+        // (dismissing the worst point at index n)
+        final double[] centroid = new double[n];
+        for (int i = 0; i < n; ++i) {
+            final double[] x = simplex[i].getPointRef();
+            for (int j = 0; j < n; ++j) {
+                centroid[j] += x[j];
+            }
+        }
+        final double scaling = 1.0 / n;
+        for (int j = 0; j < n; ++j) {
+            centroid[j] *= scaling;
+        }
+
+        // compute the reflection point
+        final double[] xR = new double[n];
+        for (int j = 0; j < n; ++j) {
+            xR[j] = centroid[j] + rho * (centroid[j] - xWorst[j]);
+        }
+        final RealPointValuePair reflected = new RealPointValuePair(xR, evaluate(xR), false);
+
+        if ((comparator.compare(best, reflected) <= 0) &&
+            (comparator.compare(reflected, secondBest) < 0)) {
+
+            // accept the reflected point
+            replaceWorstPoint(reflected, comparator);
+
+        } else if (comparator.compare(reflected, best) < 0) {
+
+            // compute the expansion point
+            final double[] xE = new double[n];
+            for (int j = 0; j < n; ++j) {
+                xE[j] = centroid[j] + khi * (xR[j] - centroid[j]);
+            }
+            final RealPointValuePair expanded = new RealPointValuePair(xE, evaluate(xE), false);
+
+            if (comparator.compare(expanded, reflected) < 0) {
+                // accept the expansion point
+                replaceWorstPoint(expanded, comparator);
+            } else {
+                // accept the reflected point
+                replaceWorstPoint(reflected, comparator);
+            }
+
+        } else {
+
+            if (comparator.compare(reflected, worst) < 0) {
+
+                // perform an outside contraction
+                final double[] xC = new double[n];
+                for (int j = 0; j < n; ++j) {
+                    xC[j] = centroid[j] + gamma * (xR[j] - centroid[j]);
+                }
+                final RealPointValuePair outContracted = new RealPointValuePair(xC, evaluate(xC), false);
+
+                if (comparator.compare(outContracted, reflected) <= 0) {
+                    // accept the contraction point
+                    replaceWorstPoint(outContracted, comparator);
+                    return;
+                }
+
+            } else {
+
+                // perform an inside contraction
+                final double[] xC = new double[n];
+                for (int j = 0; j < n; ++j) {
+                    xC[j] = centroid[j] - gamma * (centroid[j] - xWorst[j]);
+                }
+                final RealPointValuePair inContracted = new RealPointValuePair(xC, evaluate(xC), false);
+
+                if (comparator.compare(inContracted, worst) < 0) {
+                    // accept the contraction point
+                    replaceWorstPoint(inContracted, comparator);
+                    return;
+                }
+
+            }
+
+            // perform a shrink
+            final double[] xSmallest = simplex[0].getPointRef();
+            for (int i = 1; i < simplex.length; ++i) {
+                final double[] x = simplex[i].getPoint();
+                for (int j = 0; j < n; ++j) {
+                    x[j] = xSmallest[j] + sigma * (x[j] - xSmallest[j]);
+                }
+                simplex[i] = new RealPointValuePair(x, Double.NaN, false);
+            }
+            evaluateSimplex(comparator);
+
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/direct/PowellOptimizer.java b/src/main/java/org/apache/commons/math/optimization/direct/PowellOptimizer.java
new file mode 100644
index 0000000..6332951
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/direct/PowellOptimizer.java
@@ -0,0 +1,298 @@
+/*
+ * 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.optimization.direct;
+
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealPointValuePair;
+import org.apache.commons.math.optimization.general.AbstractScalarDifferentiableOptimizer;
+import org.apache.commons.math.optimization.univariate.AbstractUnivariateRealOptimizer;
+import org.apache.commons.math.optimization.univariate.BracketFinder;
+import org.apache.commons.math.optimization.univariate.BrentOptimizer;
+
+/**
+ * Powell algorithm.
+ * This code is translated and adapted from the Python version of this
+ * algorithm (as implemented in module {@code optimize.py} v0.5 of
+ * <em>SciPy</em>).
+ *
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class PowellOptimizer
+    extends AbstractScalarDifferentiableOptimizer {
+    /**
+     * Default relative tolerance for line search ({@value}).
+     */
+    public static final double DEFAULT_LS_RELATIVE_TOLERANCE = 1e-7;
+    /**
+     * Default absolute tolerance for line search ({@value}).
+     */
+    public static final double DEFAULT_LS_ABSOLUTE_TOLERANCE = 1e-11;
+    /**
+     * Line search.
+     */
+    private final LineSearch line;
+
+    /**
+     * Constructor with default line search tolerances (see the
+     * {@link #PowellOptimizer(double,double) other constructor}).
+     */
+    public PowellOptimizer() {
+        this(DEFAULT_LS_RELATIVE_TOLERANCE,
+             DEFAULT_LS_ABSOLUTE_TOLERANCE);
+    }
+
+    /**
+     * Constructor with default absolute line search tolerances (see
+     * the {@link #PowellOptimizer(double,double) other constructor}).
+     *
+     * @param lsRelativeTolerance Relative error tolerance for
+     * the line search algorithm ({@link BrentOptimizer}).
+     */
+    public PowellOptimizer(double lsRelativeTolerance) {
+        this(lsRelativeTolerance,
+             DEFAULT_LS_ABSOLUTE_TOLERANCE);
+    }
+
+    /**
+     * @param lsRelativeTolerance Relative error tolerance for
+     * the line search algorithm ({@link BrentOptimizer}).
+     * @param lsAbsoluteTolerance Relative error tolerance for
+     * the line search algorithm ({@link BrentOptimizer}).
+     */
+    public PowellOptimizer(double lsRelativeTolerance,
+                           double lsAbsoluteTolerance) {
+        line = new LineSearch(lsRelativeTolerance,
+                              lsAbsoluteTolerance);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected RealPointValuePair doOptimize()
+        throws FunctionEvaluationException,
+               OptimizationException {
+        final double[] guess = point.clone();
+        final int n = guess.length;
+
+        final double[][] direc = new double[n][n];
+        for (int i = 0; i < n; i++) {
+            direc[i][i] = 1;
+        }
+
+        double[] x = guess;
+        double fVal = computeObjectiveValue(x);
+        double[] x1 = x.clone();
+        while (true) {
+            incrementIterationsCounter();
+
+            double fX = fVal;
+            double fX2 = 0;
+            double delta = 0;
+            int bigInd = 0;
+            double alphaMin = 0;
+
+            for (int i = 0; i < n; i++) {
+                final double[] d = /* Arrays.*/ copyOf(direc[i], n); // Java 1.5 does not support Arrays.copyOf()
+
+                fX2 = fVal;
+
+                line.search(x, d);
+                fVal = line.getValueAtOptimum();
+                alphaMin = line.getOptimum();
+                final double[][] result = newPointAndDirection(x, d, alphaMin);
+                x = result[0];
+
+                if ((fX2 - fVal) > delta) {
+                    delta = fX2 - fVal;
+                    bigInd = i;
+                }
+            }
+
+            final RealPointValuePair previous = new RealPointValuePair(x1, fX);
+            final RealPointValuePair current = new RealPointValuePair(x, fVal);
+            if (getConvergenceChecker().converged(getIterations(), previous, current)) {
+                if (goal == GoalType.MINIMIZE) {
+                    return (fVal < fX) ? current : previous;
+                } else {
+                    return (fVal > fX) ? current : previous;
+                }
+            }
+
+            final double[] d = new double[n];
+            final double[] x2 = new double[n];
+            for (int i = 0; i < n; i++) {
+                d[i] = x[i] - x1[i];
+                x2[i] = 2 * x[i] - x1[i];
+            }
+
+            x1 = x.clone();
+            fX2 = computeObjectiveValue(x2);
+
+            if (fX > fX2) {
+                double t = 2 * (fX + fX2 - 2 * fVal);
+                double temp = fX - fVal - delta;
+                t *= temp * temp;
+                temp = fX - fX2;
+                t -= delta * temp * temp;
+
+                if (t < 0.0) {
+                    line.search(x, d);
+                    fVal = line.getValueAtOptimum();
+                    alphaMin = line.getOptimum();
+                    final double[][] result = newPointAndDirection(x, d, alphaMin);
+                    x = result[0];
+
+                    final int lastInd = n - 1;
+                    direc[bigInd] = direc[lastInd];
+                    direc[lastInd] = result[1];
+                }
+            }
+        }
+    }
+
+    /**
+     * Compute a new point (in the original space) and a new direction
+     * vector, resulting from the line search.
+     * The parameters {@code p} and {@code d} will be changed in-place.
+     *
+     * @param p Point used in the line search.
+     * @param d Direction used in the line search.
+     * @param optimum Optimum found by the line search.
+     * @return a 2-element array containing the new point (at index 0) and
+     * the new direction (at index 1).
+     */
+    private double[][] newPointAndDirection(double[] p,
+                                            double[] d,
+                                            double optimum) {
+        final int n = p.length;
+        final double[][] result = new double[2][n];
+        final double[] nP = result[0];
+        final double[] nD = result[1];
+        for (int i = 0; i < n; i++) {
+            nD[i] = d[i] * optimum;
+            nP[i] = p[i] + nD[i];
+        }
+        return result;
+    }
+
+    /**
+     * Class for finding the minimum of the objective function along a given
+     * direction.
+     */
+    private class LineSearch {
+        /**
+         * Optimizer.
+         */
+        private final AbstractUnivariateRealOptimizer optim = new BrentOptimizer();
+        /**
+         * Automatic bracketing.
+         */
+        private final BracketFinder bracket = new BracketFinder();
+        /**
+         * Value of the optimum.
+         */
+        private double optimum = Double.NaN;
+        /**
+         * Value of the objective function at the optimum.
+         */
+        private double valueAtOptimum = Double.NaN;
+
+        /**
+         * @param relativeTolerance Relative tolerance.
+         * @param absoluteTolerance Absolute tolerance.
+         */
+        public LineSearch(double relativeTolerance,
+                          double absoluteTolerance) {
+            optim.setRelativeAccuracy(relativeTolerance);
+            optim.setAbsoluteAccuracy(absoluteTolerance);
+        }
+
+        /**
+         * Find the minimum of the function {@code f(p + alpha * d)}.
+         *
+         * @param p Starting point.
+         * @param d Search direction.
+         * @throws FunctionEvaluationException if function cannot be evaluated at some test point
+         * @throws OptimizationException if algorithm fails to converge
+         */
+        public void search(final double[] p, final double[] d)
+            throws OptimizationException, FunctionEvaluationException {
+
+            // Reset.
+            optimum = Double.NaN;
+            valueAtOptimum = Double.NaN;
+
+            try {
+                final int n = p.length;
+                final UnivariateRealFunction f = new UnivariateRealFunction() {
+                        public double value(double alpha)
+                            throws FunctionEvaluationException {
+
+                            final double[] x = new double[n];
+                            for (int i = 0; i < n; i++) {
+                                x[i] = p[i] + alpha * d[i];
+                            }
+                            final double obj;
+                            obj = computeObjectiveValue(x);
+                            return obj;
+                        }
+                    };
+
+                bracket.search(f, goal, 0, 1);
+                optimum = optim.optimize(f, goal,
+                                         bracket.getLo(),
+                                         bracket.getHi(),
+                                         bracket.getMid());
+                valueAtOptimum = optim.getFunctionValue();
+            } catch (MaxIterationsExceededException e) {
+                throw new OptimizationException(e);
+            }
+        }
+
+        /**
+         * @return the optimum.
+         */
+        public double getOptimum() {
+            return optimum;
+        }
+        /**
+         * @return the value of the function at the optimum.
+         */
+        public double getValueAtOptimum() {
+            return valueAtOptimum;
+        }
+    }
+
+    /**
+     * Java 1.5 does not support Arrays.copyOf()
+     *
+     * @param source the array to be copied
+     * @param newLen the length of the copy to be returned
+     * @return the copied array, truncated or padded as necessary.
+     */
+     private double[] copyOf(double[] source, int newLen) {
+         double[] output = new double[newLen];
+         System.arraycopy(source, 0, output, 0, Math.min(source.length, newLen));
+         return output;
+     }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/direct/package.html b/src/main/java/org/apache/commons/math/optimization/direct/package.html
new file mode 100644
index 0000000..8e9c48e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/direct/package.html
@@ -0,0 +1,24 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 748274 $ -->
+<body>
+<p>
+This package provides optimization algorithms that don't require derivatives.
+</p>
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java b/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java
new file mode 100644
index 0000000..9bb70d1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/CurveFitter.java
@@ -0,0 +1,197 @@
+/*
+ * 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.optimization.fitting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
+import org.apache.commons.math.analysis.MultivariateMatrixFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.VectorialPointValuePair;
+
+/** Fitter for parametric univariate real functions y = f(x).
+ * <p>When a univariate real function y = f(x) does depend on some
+ * unknown parameters p<sub>0</sub>, p<sub>1</sub> ... p<sub>n-1</sub>,
+ * this class can be used to find these parameters. It does this
+ * by <em>fitting</em> the curve so it remains very close to a set of
+ * observed points (x<sub>0</sub>, y<sub>0</sub>), (x<sub>1</sub>,
+ * y<sub>1</sub>) ... (x<sub>k-1</sub>, y<sub>k-1</sub>). This fitting
+ * is done by finding the parameters values that minimizes the objective
+ * function &sum;(y<sub>i</sub>-f(x<sub>i</sub>))<sup>2</sup>. This is
+ * really a least squares problem.</p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class CurveFitter {
+
+    /** Optimizer to use for the fitting. */
+    private final DifferentiableMultivariateVectorialOptimizer optimizer;
+
+    /** Observed points. */
+    private final List<WeightedObservedPoint> observations;
+
+    /** Simple constructor.
+     * @param optimizer optimizer to use for the fitting
+     */
+    public CurveFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) {
+        this.optimizer = optimizer;
+        observations = new ArrayList<WeightedObservedPoint>();
+    }
+
+    /** Add an observed (x,y) point to the sample with unit weight.
+     * <p>Calling this method is equivalent to call
+     * <code>addObservedPoint(1.0, x, y)</code>.</p>
+     * @param x abscissa of the point
+     * @param y observed value of the point at x, after fitting we should
+     * have f(x) as close as possible to this value
+     * @see #addObservedPoint(double, double, double)
+     * @see #addObservedPoint(WeightedObservedPoint)
+     * @see #getObservations()
+     */
+    public void addObservedPoint(double x, double y) {
+        addObservedPoint(1.0, x, y);
+    }
+
+    /** Add an observed weighted (x,y) point to the sample.
+     * @param weight weight of the observed point in the fit
+     * @param x abscissa of the point
+     * @param y observed value of the point at x, after fitting we should
+     * have f(x) as close as possible to this value
+     * @see #addObservedPoint(double, double)
+     * @see #addObservedPoint(WeightedObservedPoint)
+     * @see #getObservations()
+     */
+    public void addObservedPoint(double weight, double x, double y) {
+        observations.add(new WeightedObservedPoint(weight, x, y));
+    }
+
+    /** Add an observed weighted (x,y) point to the sample.
+     * @param observed observed point to add
+     * @see #addObservedPoint(double, double)
+     * @see #addObservedPoint(double, double, double)
+     * @see #getObservations()
+     */
+    public void addObservedPoint(WeightedObservedPoint observed) {
+        observations.add(observed);
+    }
+
+    /** Get the observed points.
+     * @return observed points
+     * @see #addObservedPoint(double, double)
+     * @see #addObservedPoint(double, double, double)
+     * @see #addObservedPoint(WeightedObservedPoint)
+     */
+    public WeightedObservedPoint[] getObservations() {
+        return observations.toArray(new WeightedObservedPoint[observations.size()]);
+    }
+
+    /**
+     * Remove all observations.
+     */
+    public void clearObservations() {
+        observations.clear();
+    }
+
+    /** Fit a curve.
+     * <p>This method compute the coefficients of the curve that best
+     * fit the sample of observed points previously given through calls
+     * to the {@link #addObservedPoint(WeightedObservedPoint)
+     * addObservedPoint} method.</p>
+     * @param f parametric function to fit
+     * @param initialGuess first guess of the function parameters
+     * @return fitted parameters
+     * @exception FunctionEvaluationException if the objective function throws one during the search
+     * @exception OptimizationException if the algorithm failed to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    public double[] fit(final ParametricRealFunction f,
+                        final double[] initialGuess)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        // prepare least squares problem
+        double[] target  = new double[observations.size()];
+        double[] weights = new double[observations.size()];
+        int i = 0;
+        for (WeightedObservedPoint point : observations) {
+            target[i]  = point.getY();
+            weights[i] = point.getWeight();
+            ++i;
+        }
+
+        // perform the fit
+        VectorialPointValuePair optimum =
+            optimizer.optimize(new TheoreticalValuesFunction(f), target, weights, initialGuess);
+
+        // extract the coefficients
+        return optimum.getPointRef();
+
+    }
+
+    /** Vectorial function computing function theoretical values. */
+    private class TheoreticalValuesFunction
+        implements DifferentiableMultivariateVectorialFunction {
+
+        /** Function to fit. */
+        private final ParametricRealFunction f;
+
+        /** Simple constructor.
+         * @param f function to fit.
+         */
+        public TheoreticalValuesFunction(final ParametricRealFunction f) {
+            this.f = f;
+        }
+
+        /** {@inheritDoc} */
+        public MultivariateMatrixFunction jacobian() {
+            return new MultivariateMatrixFunction() {
+                public double[][] value(double[] point)
+                    throws FunctionEvaluationException, IllegalArgumentException {
+
+                    final double[][] jacobian = new double[observations.size()][];
+
+                    int i = 0;
+                    for (WeightedObservedPoint observed : observations) {
+                        jacobian[i++] = f.gradient(observed.getX(), point);
+                    }
+
+                    return jacobian;
+
+                }
+            };
+        }
+
+        /** {@inheritDoc} */
+        public double[] value(double[] point) throws FunctionEvaluationException, IllegalArgumentException {
+
+            // compute the residuals
+            final double[] values = new double[observations.size()];
+            int i = 0;
+            for (WeightedObservedPoint observed : observations) {
+                values[i++] = f.value(observed.getX(), point);
+            }
+
+            return values;
+
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/GaussianDerivativeFunction.java b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianDerivativeFunction.java
new file mode 100644
index 0000000..7112d17
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianDerivativeFunction.java
@@ -0,0 +1,104 @@
+/*
+ * 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.optimization.fitting;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.ZeroException;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * The derivative of {@link GaussianFunction}.  Specifically:
+ * <p>
+ * <tt>f'(x) = (-b / (d^2)) * (x - c) * exp(-((x - c)^2) / (2*(d^2)))</tt>
+ * <p>
+ * Notation key:
+ * <ul>
+ * <li><tt>x^n</tt>: <tt>x</tt> raised to the power of <tt>n</tt>
+ * <li><tt>exp(x)</tt>: <i>e</i><tt>^x</tt>
+ * </ul>
+ *
+ * @since 2.2
+ * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
+ */
+public class GaussianDerivativeFunction implements UnivariateRealFunction, Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -6500229089670174766L;
+
+    /** Parameter b of this function. */
+    private final double b;
+
+    /** Parameter c of this function. */
+    private final double c;
+
+    /** Square of the parameter d of this function. */
+    private final double d2;
+
+    /**
+     * Constructs an instance with the specified parameters.
+     *
+     * @param b <tt>b</tt> parameter value
+     * @param c <tt>c</tt> parameter value
+     * @param d <tt>d</tt> parameter value
+     *
+     * @throws IllegalArgumentException if <code>d</code> is 0
+     */
+    public GaussianDerivativeFunction(double b, double c, double d) {
+        if (d == 0.0) {
+            throw new ZeroException();
+        }
+        this.b = b;
+        this.c = c;
+        this.d2 = d * d;
+    }
+
+    /**
+     * Constructs an instance with the specified parameters.
+     *
+     * @param parameters <tt>b</tt>, <tt>c</tt>, and <tt>d</tt> parameter values
+     *
+     * @throws IllegalArgumentException if <code>parameters</code> is null,
+     *         <code>parameters</code> length is not 3, or if
+     *         <code>parameters[2]</code> is 0
+     */
+    public GaussianDerivativeFunction(double[] parameters) {
+        if (parameters == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        if (parameters.length != 3) {
+            throw new DimensionMismatchException(3, parameters.length);
+        }
+        if (parameters[2] == 0.0) {
+            throw new ZeroException();
+        }
+        this.b = parameters[0];
+        this.c = parameters[1];
+        this.d2 = parameters[2] * parameters[2];
+    }
+
+    /** {@inheritDoc} */
+    public double value(double x) {
+        final double xMc = x - c;
+        return (-b / d2) * xMc * Math.exp(-(xMc * xMc) / (2.0 * d2));
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java
new file mode 100644
index 0000000..6bc9f22
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFitter.java
@@ -0,0 +1,117 @@
+/*
+ * 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.optimization.fitting;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.fitting.CurveFitter;
+import org.apache.commons.math.optimization.fitting.WeightedObservedPoint;
+
+/**
+ * Fits points to a Gaussian function (that is, a {@link GaussianFunction}).
+ * <p>
+ * Usage example:
+ * <pre>
+ *   GaussianFitter fitter = new GaussianFitter(
+ *     new LevenbergMarquardtOptimizer());
+ *   fitter.addObservedPoint(4.0254623,  531026.0);
+ *   fitter.addObservedPoint(4.03128248, 984167.0);
+ *   fitter.addObservedPoint(4.03839603, 1887233.0);
+ *   fitter.addObservedPoint(4.04421621, 2687152.0);
+ *   fitter.addObservedPoint(4.05132976, 3461228.0);
+ *   fitter.addObservedPoint(4.05326982, 3580526.0);
+ *   fitter.addObservedPoint(4.05779662, 3439750.0);
+ *   fitter.addObservedPoint(4.0636168,  2877648.0);
+ *   fitter.addObservedPoint(4.06943698, 2175960.0);
+ *   fitter.addObservedPoint(4.07525716, 1447024.0);
+ *   fitter.addObservedPoint(4.08237071, 717104.0);
+ *   fitter.addObservedPoint(4.08366408, 620014.0);
+ *  GaussianFunction fitFunction = fitter.fit();
+ * </pre>
+ *
+ * @see ParametricGaussianFunction
+ * @since 2.2
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ */
+public class GaussianFitter {
+
+    /** Fitter used for fitting. */
+    private final CurveFitter fitter;
+
+    /**
+     * Constructs an instance using the specified optimizer.
+     *
+     * @param optimizer optimizer to use for the fitting
+     */
+    public GaussianFitter(DifferentiableMultivariateVectorialOptimizer optimizer) {
+        fitter = new CurveFitter(optimizer);
+    }
+
+    /**
+     * Adds point (<code>x</code>, <code>y</code>) to list of observed points
+     * with a weight of 1.0.
+     *
+     * @param x <tt>x</tt> point value
+     * @param y <tt>y</tt> point value
+     */
+    public void addObservedPoint(double x, double y) {
+        addObservedPoint(1.0, x, y);
+    }
+
+    /**
+     * Adds point (<code>x</code>, <code>y</code>) to list of observed points
+     * with a weight of <code>weight</code>.
+     *
+     * @param weight weight assigned to point
+     * @param x <tt>x</tt> point value
+     * @param y <tt>y</tt> point value
+     */
+    public void addObservedPoint(double weight, double x, double y) {
+        fitter.addObservedPoint(weight, x, y);
+    }
+
+    /**
+     * Fits Gaussian function to the observed points.
+     *
+     * @return Gaussian function best fitting the observed points
+     *
+     * @throws FunctionEvaluationException if <code>CurveFitter.fit</code> throws it
+     * @throws OptimizationException if <code>CurveFitter.fit</code> throws it
+     * @throws IllegalArgumentException if <code>CurveFitter.fit</code> throws it
+     *
+     * @see CurveFitter
+     */
+    public GaussianFunction fit() throws FunctionEvaluationException, OptimizationException {
+        return new GaussianFunction(fitter.fit(new ParametricGaussianFunction(),
+                                               createParametersGuesser(fitter.getObservations()).guess()));
+    }
+
+    /**
+     * Factory method to create a <code>GaussianParametersGuesser</code>
+     * instance initialized with the specified observations.
+     *
+     * @param observations points used to initialize the created
+     *        <code>GaussianParametersGuesser</code> instance
+     *
+     * @return new <code>GaussianParametersGuesser</code> instance
+     */
+    protected GaussianParametersGuesser createParametersGuesser(WeightedObservedPoint[] observations) {
+        return new GaussianParametersGuesser(observations);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFunction.java b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFunction.java
new file mode 100644
index 0000000..06a0391
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianFunction.java
@@ -0,0 +1,159 @@
+/*
+ * 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.optimization.fitting;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.ZeroException;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * A Gaussian function.  Specifically:
+ * <p>
+ * <tt>f(x) = a + b*exp(-((x - c)^2 / (2*d^2)))</tt>
+ * <p>
+ * Notation key:
+ * <ul>
+ * <li><tt>x^n</tt>: <tt>x</tt> raised to the power of <tt>n</tt>
+ * <li><tt>exp(x)</tt>: <i>e</i><tt>^x</tt>
+ * </ul>
+ * References:
+ * <ul>
+ * <li><a href="http://en.wikipedia.org/wiki/Gaussian_function">Wikipedia:
+ *   Gaussian function</a>
+ * </ul>
+ *
+ * @see GaussianDerivativeFunction
+ * @see ParametricGaussianFunction
+ * @since 2.2
+ * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
+ */
+public class GaussianFunction implements DifferentiableUnivariateRealFunction, Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -3195385616125629512L;
+
+    /** Parameter a of this function. */
+    private final double a;
+
+    /** Parameter b of this function. */
+    private final double b;
+
+    /** Parameter c of this function. */
+    private final double c;
+
+    /** Parameter d of this function. */
+    private final double d;
+
+    /**
+     * Constructs an instance with the specified parameters.
+     *
+     * @param a <tt>a</tt> parameter value
+     * @param b <tt>b</tt> parameter value
+     * @param c <tt>c</tt> parameter value
+     * @param d <tt>d</tt> parameter value
+     *
+     * @throws IllegalArgumentException if <code>d</code> is 0
+     */
+    public GaussianFunction(double a, double b, double c, double d) {
+        if (d == 0.0) {
+            throw new ZeroException();
+        }
+        this.a = a;
+        this.b = b;
+        this.c = c;
+        this.d = d;
+    }
+
+    /**
+     * Constructs an instance with the specified parameters.
+     *
+     * @param parameters <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and <tt>d</tt>
+     *        parameter values
+     *
+     * @throws IllegalArgumentException if <code>parameters</code> is null,
+     *         <code>parameters</code> length is not 4, or if
+     *         <code>parameters[3]</code> is 0
+     */
+    public GaussianFunction(double[] parameters) {
+        if (parameters == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        if (parameters.length != 4) {
+            throw new DimensionMismatchException(4, parameters.length);
+        }
+        if (parameters[3] == 0.0) {
+            throw new ZeroException();
+        }
+        this.a = parameters[0];
+        this.b = parameters[1];
+        this.c = parameters[2];
+        this.d = parameters[3];
+    }
+
+    /** {@inheritDoc} */
+    public UnivariateRealFunction derivative() {
+        return new GaussianDerivativeFunction(b, c, d);
+    }
+
+    /** {@inheritDoc} */
+    public double value(double x) {
+        final double xMc = x - c;
+        return a + b * Math.exp(-xMc * xMc / (2.0 * (d * d)));
+    }
+
+    /**
+     * Gets <tt>a</tt> parameter value.
+     *
+     * @return <tt>a</tt> parameter value
+     */
+    public double getA() {
+        return a;
+    }
+
+    /**
+     * Gets <tt>b</tt> parameter value.
+     *
+     * @return <tt>b</tt> parameter value
+     */
+    public double getB() {
+        return b;
+    }
+
+    /**
+     * Gets <tt>c</tt> parameter value.
+     *
+     * @return <tt>c</tt> parameter value
+     */
+    public double getC() {
+        return c;
+    }
+
+    /**
+     * Gets <tt>d</tt> parameter value.
+     *
+     * @return <tt>d</tt> parameter value
+     */
+    public double getD() {
+        return d;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/GaussianParametersGuesser.java b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianParametersGuesser.java
new file mode 100644
index 0000000..3fb3698
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/GaussianParametersGuesser.java
@@ -0,0 +1,271 @@
+/*
+ * 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.optimization.fitting;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NumberIsTooSmallException;
+import org.apache.commons.math.exception.OutOfRangeException;
+import org.apache.commons.math.exception.ZeroException;
+import org.apache.commons.math.exception.NullArgumentException;
+
+/**
+ * Guesses the parameters ({@code a}, {@code b}, {@code c}, and {@code d})
+ * of a {@link ParametricGaussianFunction} based on the specified observed
+ * points.
+ *
+ * @since 2.2
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class GaussianParametersGuesser {
+
+    /** Observed points. */
+    private final WeightedObservedPoint[] observations;
+
+    /** Resulting guessed parameters. */
+    private double[] parameters;
+
+    /**
+     * Constructs instance with the specified observed points.
+     *
+     * @param observations observed points upon which should base guess
+     */
+    public GaussianParametersGuesser(WeightedObservedPoint[] observations) {
+        if (observations == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        if (observations.length < 3) {
+            throw new NumberIsTooSmallException(observations.length, 3, true);
+        }
+        this.observations = observations.clone();
+    }
+
+    /**
+     * Guesses the parameters based on the observed points.
+     *
+     * @return guessed parameters array <code>{a, b, c, d}</code>
+     */
+    public double[] guess() {
+        if (parameters == null) {
+            parameters = basicGuess(observations);
+        }
+        return parameters.clone();
+    }
+
+    /**
+     * Guesses the parameters based on the specified observed points.
+     *
+     * @param points observed points upon which should base guess
+     *
+     * @return guessed parameters array <code>{a, b, c, d}</code>
+     */
+    private double[] basicGuess(WeightedObservedPoint[] points) {
+        Arrays.sort(points, createWeightedObservedPointComparator());
+        double[] params = new double[4];
+
+        int minYIdx = findMinY(points);
+        params[0] = points[minYIdx].getY();
+
+        int maxYIdx = findMaxY(points);
+        params[1] = points[maxYIdx].getY();
+        params[2] = points[maxYIdx].getX();
+
+        double fwhmApprox;
+        try {
+            double halfY = params[0] + ((params[1] - params[0]) / 2.0);
+            double fwhmX1 = interpolateXAtY(points, maxYIdx, -1, halfY);
+            double fwhmX2 = interpolateXAtY(points, maxYIdx, +1, halfY);
+            fwhmApprox = fwhmX2 - fwhmX1;
+        } catch (OutOfRangeException e) {
+            fwhmApprox = points[points.length - 1].getX() - points[0].getX();
+        }
+        params[3] = fwhmApprox / (2.0 * Math.sqrt(2.0 * Math.log(2.0)));
+
+        return params;
+    }
+
+    /**
+     * Finds index of point in specified points with the smallest Y.
+     *
+     * @param points points to search
+     *
+     * @return index in specified points array
+     */
+    private int findMinY(WeightedObservedPoint[] points) {
+        int minYIdx = 0;
+        for (int i = 1; i < points.length; i++) {
+            if (points[i].getY() < points[minYIdx].getY()) {
+                minYIdx = i;
+            }
+        }
+        return minYIdx;
+    }
+
+    /**
+     * Finds index of point in specified points with the largest Y.
+     *
+     * @param points points to search
+     *
+     * @return index in specified points array
+     */
+    private int findMaxY(WeightedObservedPoint[] points) {
+        int maxYIdx = 0;
+        for (int i = 1; i < points.length; i++) {
+            if (points[i].getY() > points[maxYIdx].getY()) {
+                maxYIdx = i;
+            }
+        }
+        return maxYIdx;
+    }
+
+    /**
+     * Interpolates using the specified points to determine X at the specified
+     * Y.
+     *
+     * @param points points to use for interpolation
+     * @param startIdx index within points from which to start search for
+     *        interpolation bounds points
+     * @param idxStep index step for search for interpolation bounds points
+     * @param y Y value for which X should be determined
+     *
+     * @return value of X at the specified Y
+     *
+     * @throws IllegalArgumentException if idxStep is 0
+     * @throws OutOfRangeException if specified <code>y</code> is not within the
+     *         range of the specified <code>points</code>
+     */
+    private double interpolateXAtY(WeightedObservedPoint[] points,
+                                   int startIdx, int idxStep, double y) throws OutOfRangeException {
+        if (idxStep == 0) {
+            throw new ZeroException();
+        }
+        WeightedObservedPoint[] twoPoints = getInterpolationPointsForY(points, startIdx, idxStep, y);
+        WeightedObservedPoint pointA = twoPoints[0];
+        WeightedObservedPoint pointB = twoPoints[1];
+        if (pointA.getY() == y) {
+            return pointA.getX();
+        }
+        if (pointB.getY() == y) {
+            return pointB.getX();
+        }
+        return pointA.getX() +
+               (((y - pointA.getY()) * (pointB.getX() - pointA.getX())) / (pointB.getY() - pointA.getY()));
+    }
+
+    /**
+     * Gets the two bounding interpolation points from the specified points
+     * suitable for determining X at the specified Y.
+     *
+     * @param points points to use for interpolation
+     * @param startIdx index within points from which to start search for
+     *        interpolation bounds points
+     * @param idxStep index step for search for interpolation bounds points
+     * @param y Y value for which X should be determined
+     *
+     * @return array containing two points suitable for determining X at the
+     *         specified Y
+     *
+     * @throws IllegalArgumentException if idxStep is 0
+     * @throws OutOfRangeException if specified <code>y</code> is not within the
+     *         range of the specified <code>points</code>
+     */
+    private WeightedObservedPoint[] getInterpolationPointsForY(WeightedObservedPoint[] points,
+                                                               int startIdx, int idxStep, double y)
+        throws OutOfRangeException {
+        if (idxStep == 0) {
+            throw new ZeroException();
+        }
+        for (int i = startIdx;
+             (idxStep < 0) ? (i + idxStep >= 0) : (i + idxStep < points.length);
+             i += idxStep) {
+            if (isBetween(y, points[i].getY(), points[i + idxStep].getY())) {
+                return (idxStep < 0) ?
+                       new WeightedObservedPoint[] { points[i + idxStep], points[i] } :
+                       new WeightedObservedPoint[] { points[i], points[i + idxStep] };
+            }
+        }
+
+        double minY = Double.POSITIVE_INFINITY;
+        double maxY = Double.NEGATIVE_INFINITY;
+        for (final WeightedObservedPoint point : points) {
+            minY = Math.min(minY, point.getY());
+            maxY = Math.max(maxY, point.getY());
+        }
+        throw new OutOfRangeException(y, minY, maxY);
+
+    }
+
+    /**
+     * Determines whether a value is between two other values.
+     *
+     * @param value value to determine whether is between <code>boundary1</code>
+     *        and <code>boundary2</code>
+     * @param boundary1 one end of the range
+     * @param boundary2 other end of the range
+     *
+     * @return true if <code>value</code> is between <code>boundary1</code> and
+     *         <code>boundary2</code> (inclusive); false otherwise
+     */
+    private boolean isBetween(double value, double boundary1, double boundary2) {
+        return (value >= boundary1 && value <= boundary2) ||
+               (value >= boundary2 && value <= boundary1);
+    }
+
+    /**
+     * Factory method creating <code>Comparator</code> for comparing
+     * <code>WeightedObservedPoint</code> instances.
+     *
+     * @return new <code>Comparator</code> instance
+     */
+    private Comparator<WeightedObservedPoint> createWeightedObservedPointComparator() {
+        return new Comparator<WeightedObservedPoint>() {
+            public int compare(WeightedObservedPoint p1, WeightedObservedPoint p2) {
+                if (p1 == null && p2 == null) {
+                    return 0;
+                }
+                if (p1 == null) {
+                    return -1;
+                }
+                if (p2 == null) {
+                    return 1;
+                }
+                if (p1.getX() < p2.getX()) {
+                    return -1;
+                }
+                if (p1.getX() > p2.getX()) {
+                    return 1;
+                }
+                if (p1.getY() < p2.getY()) {
+                    return -1;
+                }
+                if (p1.getY() > p2.getY()) {
+                    return 1;
+                }
+                if (p1.getWeight() < p2.getWeight()) {
+                    return -1;
+                }
+                if (p1.getWeight() > p2.getWeight()) {
+                    return 1;
+                }
+                return 0;
+            }
+        };
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicCoefficientsGuesser.java b/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicCoefficientsGuesser.java
new file mode 100644
index 0000000..0796f67
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicCoefficientsGuesser.java
@@ -0,0 +1,300 @@
+/*
+ * 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.optimization.fitting;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.util.FastMath;
+
+/** This class guesses harmonic coefficients from a sample.
+
+ * <p>The algorithm used to guess the coefficients is as follows:</p>
+
+ * <p>We know f (t) at some sampling points t<sub>i</sub> and want to find a,
+ * &omega; and &phi; such that f (t) = a cos (&omega; t + &phi;).
+ * </p>
+ *
+ * <p>From the analytical expression, we can compute two primitives :
+ * <pre>
+ *     If2  (t) = &int; f<sup>2</sup>  = a<sup>2</sup> &times; [t + S (t)] / 2
+ *     If'2 (t) = &int; f'<sup>2</sup> = a<sup>2</sup> &omega;<sup>2</sup> &times; [t - S (t)] / 2
+ *     where S (t) = sin (2 (&omega; t + &phi;)) / (2 &omega;)
+ * </pre>
+ * </p>
+ *
+ * <p>We can remove S between these expressions :
+ * <pre>
+ *     If'2 (t) = a<sup>2</sup> &omega;<sup>2</sup> t - &omega;<sup>2</sup> If2 (t)
+ * </pre>
+ * </p>
+ *
+ * <p>The preceding expression shows that If'2 (t) is a linear
+ * combination of both t and If2 (t): If'2 (t) = A &times; t + B &times; If2 (t)
+ * </p>
+ *
+ * <p>From the primitive, we can deduce the same form for definite
+ * integrals between t<sub>1</sub> and t<sub>i</sub> for each t<sub>i</sub> :
+ * <pre>
+ *   If2 (t<sub>i</sub>) - If2 (t<sub>1</sub>) = A &times; (t<sub>i</sub> - t<sub>1</sub>) + B &times; (If2 (t<sub>i</sub>) - If2 (t<sub>1</sub>))
+ * </pre>
+ * </p>
+ *
+ * <p>We can find the coefficients A and B that best fit the sample
+ * to this linear expression by computing the definite integrals for
+ * each sample points.
+ * </p>
+ *
+ * <p>For a bilinear expression z (x<sub>i</sub>, y<sub>i</sub>) = A &times; x<sub>i</sub> + B &times; y<sub>i</sub>, the
+ * coefficients A and B that minimize a least square criterion
+ * &sum; (z<sub>i</sub> - z (x<sub>i</sub>, y<sub>i</sub>))<sup>2</sup> are given by these expressions:</p>
+ * <pre>
+ *
+ *         &sum;y<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+ *     A = ------------------------
+ *         &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>y<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>y<sub>i</sub>
+ *
+ *         &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub>
+ *     B = ------------------------
+ *         &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>y<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>y<sub>i</sub>
+ * </pre>
+ * </p>
+ *
+ *
+ * <p>In fact, we can assume both a and &omega; are positive and
+ * compute them directly, knowing that A = a<sup>2</sup> &omega;<sup>2</sup> and that
+ * B = - &omega;<sup>2</sup>. The complete algorithm is therefore:</p>
+ * <pre>
+ *
+ * for each t<sub>i</sub> from t<sub>1</sub> to t<sub>n-1</sub>, compute:
+ *   f  (t<sub>i</sub>)
+ *   f' (t<sub>i</sub>) = (f (t<sub>i+1</sub>) - f(t<sub>i-1</sub>)) / (t<sub>i+1</sub> - t<sub>i-1</sub>)
+ *   x<sub>i</sub> = t<sub>i</sub> - t<sub>1</sub>
+ *   y<sub>i</sub> = &int; f<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub>
+ *   z<sub>i</sub> = &int; f'<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub>
+ *   update the sums &sum;x<sub>i</sub>x<sub>i</sub>, &sum;y<sub>i</sub>y<sub>i</sub>, &sum;x<sub>i</sub>y<sub>i</sub>, &sum;x<sub>i</sub>z<sub>i</sub> and &sum;y<sub>i</sub>z<sub>i</sub>
+ * end for
+ *
+ *            |--------------------------
+ *         \  | &sum;y<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+ * a     =  \ | ------------------------
+ *           \| &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+ *
+ *
+ *            |--------------------------
+ *         \  | &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>z<sub>i</sub> - &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>z<sub>i</sub>
+ * &omega;     =  \ | ------------------------
+ *           \| &sum;x<sub>i</sub>x<sub>i</sub> &sum;y<sub>i</sub>y<sub>i</sub> - &sum;x<sub>i</sub>y<sub>i</sub> &sum;x<sub>i</sub>y<sub>i</sub>
+ *
+ * </pre>
+ * </p>
+
+ * <p>Once we know &omega;, we can compute:
+ * <pre>
+ *    fc = &omega; f (t) cos (&omega; t) - f' (t) sin (&omega; t)
+ *    fs = &omega; f (t) sin (&omega; t) + f' (t) cos (&omega; t)
+ * </pre>
+ * </p>
+
+ * <p>It appears that <code>fc = a &omega; cos (&phi;)</code> and
+ * <code>fs = -a &omega; sin (&phi;)</code>, so we can use these
+ * expressions to compute &phi;. The best estimate over the sample is
+ * given by averaging these expressions.
+ * </p>
+
+ * <p>Since integrals and means are involved in the preceding
+ * estimations, these operations run in O(n) time, where n is the
+ * number of measurements.</p>
+
+ * @version $Revision: 1056034 $ $Date: 2011-01-06 20:41:43 +0100 (jeu. 06 janv. 2011) $
+ * @since 2.0
+
+ */
+public class HarmonicCoefficientsGuesser {
+
+    /** Sampled observations. */
+    private final WeightedObservedPoint[] observations;
+
+    /** Guessed amplitude. */
+    private double a;
+
+    /** Guessed pulsation &omega;. */
+    private double omega;
+
+    /** Guessed phase &phi;. */
+    private double phi;
+
+    /** Simple constructor.
+     * @param observations sampled observations
+     */
+    public HarmonicCoefficientsGuesser(WeightedObservedPoint[] observations) {
+        this.observations = observations.clone();
+        a                 = Double.NaN;
+        omega             = Double.NaN;
+    }
+
+    /** Estimate a first guess of the coefficients.
+     * @exception OptimizationException if the sample is too short or if
+     * the first guess cannot be computed (when the elements under the
+     * square roots are negative).
+     * */
+    public void guess() throws OptimizationException {
+        sortObservations();
+        guessAOmega();
+        guessPhi();
+    }
+
+    /** Sort the observations with respect to the abscissa.
+     */
+    private void sortObservations() {
+
+        // Since the samples are almost always already sorted, this
+        // method is implemented as an insertion sort that reorders the
+        // elements in place. Insertion sort is very efficient in this case.
+        WeightedObservedPoint curr = observations[0];
+        for (int j = 1; j < observations.length; ++j) {
+            WeightedObservedPoint prec = curr;
+            curr = observations[j];
+            if (curr.getX() < prec.getX()) {
+                // the current element should be inserted closer to the beginning
+                int i = j - 1;
+                WeightedObservedPoint mI = observations[i];
+                while ((i >= 0) && (curr.getX() < mI.getX())) {
+                    observations[i + 1] = mI;
+                    if (i-- != 0) {
+                        mI = observations[i];
+                    }
+                }
+                observations[i + 1] = curr;
+                curr = observations[j];
+            }
+        }
+
+    }
+
+    /** Estimate a first guess of the a and &omega; coefficients.
+     * @exception OptimizationException if the sample is too short or if
+     * the first guess cannot be computed (when the elements under the
+     * square roots are negative).
+     */
+    private void guessAOmega() throws OptimizationException {
+
+        // initialize the sums for the linear model between the two integrals
+        double sx2 = 0.0;
+        double sy2 = 0.0;
+        double sxy = 0.0;
+        double sxz = 0.0;
+        double syz = 0.0;
+
+        double currentX        = observations[0].getX();
+        double currentY        = observations[0].getY();
+        double f2Integral      = 0;
+        double fPrime2Integral = 0;
+        final double startX = currentX;
+        for (int i = 1; i < observations.length; ++i) {
+
+            // one step forward
+            final double previousX = currentX;
+            final double previousY = currentY;
+            currentX = observations[i].getX();
+            currentY = observations[i].getY();
+
+            // update the integrals of f<sup>2</sup> and f'<sup>2</sup>
+            // considering a linear model for f (and therefore constant f')
+            final double dx = currentX - previousX;
+            final double dy = currentY - previousY;
+            final double f2StepIntegral =
+                dx * (previousY * previousY + previousY * currentY + currentY * currentY) / 3;
+            final double fPrime2StepIntegral = dy * dy / dx;
+
+            final double x   = currentX - startX;
+            f2Integral      += f2StepIntegral;
+            fPrime2Integral += fPrime2StepIntegral;
+
+            sx2 += x * x;
+            sy2 += f2Integral * f2Integral;
+            sxy += x * f2Integral;
+            sxz += x * fPrime2Integral;
+            syz += f2Integral * fPrime2Integral;
+
+        }
+
+        // compute the amplitude and pulsation coefficients
+        double c1 = sy2 * sxz - sxy * syz;
+        double c2 = sxy * sxz - sx2 * syz;
+        double c3 = sx2 * sy2 - sxy * sxy;
+        if ((c1 / c2 < 0.0) || (c2 / c3 < 0.0)) {
+            throw new OptimizationException(LocalizedFormats.UNABLE_TO_FIRST_GUESS_HARMONIC_COEFFICIENTS);
+        }
+        a     = FastMath.sqrt(c1 / c2);
+        omega = FastMath.sqrt(c2 / c3);
+
+    }
+
+    /** Estimate a first guess of the &phi; coefficient.
+     */
+    private void guessPhi() {
+
+        // initialize the means
+        double fcMean = 0.0;
+        double fsMean = 0.0;
+
+        double currentX = observations[0].getX();
+        double currentY = observations[0].getY();
+        for (int i = 1; i < observations.length; ++i) {
+
+            // one step forward
+            final double previousX = currentX;
+            final double previousY = currentY;
+            currentX = observations[i].getX();
+            currentY = observations[i].getY();
+            final double currentYPrime = (currentY - previousY) / (currentX - previousX);
+
+            double   omegaX = omega * currentX;
+            double   cosine = FastMath.cos(omegaX);
+            double   sine   = FastMath.sin(omegaX);
+            fcMean += omega * currentY * cosine - currentYPrime *   sine;
+            fsMean += omega * currentY *   sine + currentYPrime * cosine;
+
+        }
+
+        phi = FastMath.atan2(-fsMean, fcMean);
+
+    }
+
+    /** Get the guessed amplitude a.
+     * @return guessed amplitude a;
+     */
+    public double getGuessedAmplitude() {
+        return a;
+    }
+
+    /** Get the guessed pulsation &omega;.
+     * @return guessed pulsation &omega;
+     */
+    public double getGuessedPulsation() {
+        return omega;
+    }
+
+    /** Get the guessed phase &phi;.
+     * @return guessed phase &phi;
+     */
+    public double getGuessedPhase() {
+        return phi;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java b/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java
new file mode 100644
index 0000000..ef019c9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFitter.java
@@ -0,0 +1,133 @@
+/*
+ * 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.optimization.fitting;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.util.FastMath;
+
+/** This class implements a curve fitting specialized for sinusoids.
+ * <p>Harmonic fitting is a very simple case of curve fitting. The
+ * estimated coefficients are the amplitude a, the pulsation &omega; and
+ * the phase &phi;: <code>f (t) = a cos (&omega; t + &phi;)</code>. They are
+ * searched by a least square estimator initialized with a rough guess
+ * based on integrals.</p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public class HarmonicFitter {
+
+    /** Fitter for the coefficients. */
+    private final CurveFitter fitter;
+
+    /** Values for amplitude, pulsation &omega; and phase &phi;. */
+    private double[] parameters;
+
+    /** Simple constructor.
+     * @param optimizer optimizer to use for the fitting
+     */
+    public HarmonicFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) {
+        this.fitter = new CurveFitter(optimizer);
+        parameters  = null;
+    }
+
+    /** Simple constructor.
+     * <p>This constructor can be used when a first guess of the
+     * coefficients is already known.</p>
+     * @param optimizer optimizer to use for the fitting
+     * @param initialGuess guessed values for amplitude (index 0),
+     * pulsation &omega; (index 1) and phase &phi; (index 2)
+     */
+    public HarmonicFitter(final DifferentiableMultivariateVectorialOptimizer optimizer,
+                          final double[] initialGuess) {
+        this.fitter     = new CurveFitter(optimizer);
+        this.parameters = initialGuess.clone();
+    }
+
+    /** Add an observed weighted (x,y) point to the sample.
+     * @param weight weight of the observed point in the fit
+     * @param x abscissa of the point
+     * @param y observed value of the point at x, after fitting we should
+     * have P(x) as close as possible to this value
+     */
+    public void addObservedPoint(double weight, double x, double y) {
+        fitter.addObservedPoint(weight, x, y);
+    }
+
+    /** Fit an harmonic function to the observed points.
+     * @return harmonic function best fitting the observed points
+     * @throws OptimizationException if the sample is too short or if
+     * the first guess cannot be computed
+     */
+    public HarmonicFunction fit() throws OptimizationException {
+
+        // shall we compute the first guess of the parameters ourselves ?
+        if (parameters == null) {
+            final WeightedObservedPoint[] observations = fitter.getObservations();
+            if (observations.length < 4) {
+                throw new OptimizationException(LocalizedFormats.INSUFFICIENT_OBSERVED_POINTS_IN_SAMPLE,
+                                                observations.length, 4);
+            }
+
+            HarmonicCoefficientsGuesser guesser = new HarmonicCoefficientsGuesser(observations);
+            guesser.guess();
+            parameters = new double[] {
+                guesser.getGuessedAmplitude(),
+                guesser.getGuessedPulsation(),
+                guesser.getGuessedPhase()
+            };
+
+        }
+
+        try {
+            double[] fitted = fitter.fit(new ParametricHarmonicFunction(), parameters);
+            return new HarmonicFunction(fitted[0], fitted[1], fitted[2]);
+        } catch (FunctionEvaluationException fee) {
+            // should never happen
+            throw new RuntimeException(fee);
+        }
+
+    }
+
+    /** Parametric harmonic function. */
+    private static class ParametricHarmonicFunction implements ParametricRealFunction {
+
+        /** {@inheritDoc} */
+        public double value(double x, double[] parameters) {
+            final double a     = parameters[0];
+            final double omega = parameters[1];
+            final double phi   = parameters[2];
+            return a * FastMath.cos(omega * x + phi);
+        }
+
+        /** {@inheritDoc} */
+        public double[] gradient(double x, double[] parameters) {
+            final double a     = parameters[0];
+            final double omega = parameters[1];
+            final double phi   = parameters[2];
+            final double alpha = omega * x + phi;
+            final double cosAlpha = FastMath.cos(alpha);
+            final double sinAlpha = FastMath.sin(alpha);
+            return new double[] { cosAlpha, -a * x * sinAlpha, -a * sinAlpha };
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFunction.java b/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFunction.java
new file mode 100644
index 0000000..cce3533
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/HarmonicFunction.java
@@ -0,0 +1,80 @@
+/*
+ * 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.optimization.fitting;
+
+import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
+import org.apache.commons.math.util.FastMath;
+
+/** Harmonic function of the form <code>f (t) = a cos (&omega; t + &phi;)</code>.
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class HarmonicFunction implements DifferentiableUnivariateRealFunction {
+
+    /** Amplitude a. */
+    private final double a;
+
+    /** Pulsation &omega;. */
+    private final double omega;
+
+    /** Phase &phi;. */
+    private final double phi;
+
+    /** Simple constructor.
+     * @param a amplitude
+     * @param omega pulsation
+     * @param phi phase
+     */
+    public HarmonicFunction(double a, double omega, double phi) {
+        this.a     = a;
+        this.omega = omega;
+        this.phi   = phi;
+    }
+
+    /** {@inheritDoc} */
+    public double value(double x) {
+        return a * FastMath.cos(omega * x + phi);
+    }
+
+    /** {@inheritDoc} */
+    public HarmonicFunction derivative() {
+        return new HarmonicFunction(a * omega, omega, phi + FastMath.PI / 2);
+    }
+
+    /** Get the amplitude a.
+     * @return amplitude a;
+     */
+    public double getAmplitude() {
+        return a;
+    }
+
+    /** Get the pulsation &omega;.
+     * @return pulsation &omega;
+     */
+    public double getPulsation() {
+        return omega;
+    }
+
+    /** Get the phase &phi;.
+     * @return phase &phi;
+     */
+    public double getPhase() {
+        return phi;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java b/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java
new file mode 100644
index 0000000..9deb731
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/ParametricGaussianFunction.java
@@ -0,0 +1,165 @@
+/*
+ * 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.optimization.fitting;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.ZeroException;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.optimization.fitting.ParametricRealFunction;
+
+/**
+ * A Gaussian function.  Specifically:
+ * <p>
+ * <tt>f(x) = a + b*exp(-((x - c)^2 / (2*d^2)))</tt>
+ * <p>
+ * The parameters have the following meaning:
+ * <ul>
+ * <li><tt>a</tt> is a constant offset that shifts <tt>f(x)</tt> up or down
+ * <li><tt>b</tt> is the height of the peak
+ * <li><tt>c</tt> is the position of the center of the peak
+ * <li><tt>d</tt> is related to the FWHM by <tt>FWHM = 2*sqrt(2*ln(2))*d</tt>
+ * </ul>
+ * Notation key:
+ * <ul>
+ * <li><tt>x^n</tt>: <tt>x</tt> raised to the power of <tt>n</tt>
+ * <li><tt>exp(x)</tt>: <i>e</i><tt>^x</tt>
+ * <li><tt>sqrt(x)</tt>: the square root of <tt>x</tt>
+ * <li><tt>ln(x)</tt>: the natural logarithm of <tt>x</tt>
+ * </ul>
+ * References:
+ * <ul>
+ * <li><a href="http://en.wikipedia.org/wiki/Gaussian_function">Wikipedia:
+ *   Gaussian function</a>
+ * </ul>
+ *
+ * @since 2.2
+ * @version $Revision: 1037327 $ $Date: 2010-11-20 21:57:37 +0100 (sam. 20 nov. 2010) $
+ */
+public class ParametricGaussianFunction implements ParametricRealFunction, Serializable {
+
+    /** Serializable version Id. */
+    private static final long serialVersionUID = -3875578602503903233L;
+
+    /**
+     * Constructs an instance.
+     */
+    public ParametricGaussianFunction() {
+    }
+
+    /**
+     * Computes value of function <tt>f(x)</tt> for the specified <tt>x</tt> and
+     * parameters <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and <tt>d</tt>.
+     *
+     * @param x <tt>x</tt> value
+     * @param parameters values of <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and
+     *        <tt>d</tt>
+     *
+     * @return value of <tt>f(x)</tt> evaluated at <tt>x</tt> with the specified
+     *         parameters
+     *
+     * @throws IllegalArgumentException if <code>parameters</code> is invalid as
+     *         determined by {@link #validateParameters(double[])}
+     * @throws ZeroException if <code>parameters</code> values are
+     *         invalid as determined by {@link #validateParameters(double[])}
+     */
+    public double value(double x, double[] parameters) throws ZeroException {
+        validateParameters(parameters);
+        final double a = parameters[0];
+        final double b = parameters[1];
+        final double c = parameters[2];
+        final double d = parameters[3];
+        final double xMc = x - c;
+        return a + b * Math.exp(-xMc * xMc / (2.0 * (d * d)));
+    }
+
+    /**
+     * Computes the gradient vector for a four variable version of the function
+     * where the parameters, <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and <tt>d</tt>,
+     * are considered the variables, not <tt>x</tt>.  That is, instead of
+     * computing the gradient vector for the function <tt>f(x)</tt> (which would
+     * just be the derivative of <tt>f(x)</tt> with respect to <tt>x</tt> since
+     * it's a one-dimensional function), computes the gradient vector for the
+     * function <tt>f(a, b, c, d) = a + b*exp(-((x - c)^2 / (2*d^2)))</tt>
+     * treating the specified <tt>x</tt> as a constant.
+     * <p>
+     * The components of the computed gradient vector are the partial
+     * derivatives of <tt>f(a, b, c, d)</tt> with respect to each variable.
+     * That is, the partial derivative of <tt>f(a, b, c, d)</tt> with respect to
+     * <tt>a</tt>, the partial derivative of <tt>f(a, b, c, d)</tt> with respect
+     * to <tt>b</tt>, the partial derivative of <tt>f(a, b, c, d)</tt> with
+     * respect to <tt>c</tt>, and the partial derivative of <tt>f(a, b, c,
+     * d)</tt> with respect to <tt>d</tt>.
+     *
+     * @param x <tt>x</tt> value to be used as constant in <tt>f(a, b, c,
+     *        d)</tt>
+     * @param parameters values of <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and
+     *        <tt>d</tt> for computation of gradient vector of <tt>f(a, b, c,
+     *        d)</tt>
+     *
+     * @return gradient vector of <tt>f(a, b, c, d)</tt>
+     *
+     * @throws IllegalArgumentException if <code>parameters</code> is invalid as
+     *         determined by {@link #validateParameters(double[])}
+     * @throws ZeroException if <code>parameters</code> values are
+     *         invalid as determined by {@link #validateParameters(double[])}
+     */
+    public double[] gradient(double x, double[] parameters) throws ZeroException {
+
+        validateParameters(parameters);
+        final double b = parameters[1];
+        final double c = parameters[2];
+        final double d = parameters[3];
+
+        final double xMc  = x - c;
+        final double d2   = d * d;
+        final double exp  = Math.exp(-xMc * xMc / (2 * d2));
+        final double f    = b * exp * xMc / d2;
+
+        return new double[] { 1.0, exp, f, f * xMc / d };
+
+    }
+
+    /**
+     * Validates parameters to ensure they are appropriate for the evaluation of
+     * the <code>value</code> and <code>gradient</code> methods.
+     *
+     * @param parameters values of <tt>a</tt>, <tt>b</tt>, <tt>c</tt>, and
+     *        <tt>d</tt>
+     *
+     * @throws IllegalArgumentException if <code>parameters</code> is
+     *         <code>null</code> or if <code>parameters</code> does not have
+     *         length == 4
+     * @throws ZeroException if <code>parameters[3]</code>
+     *         (<tt>d</tt>) is 0
+     */
+    private void validateParameters(double[] parameters) throws ZeroException {
+        if (parameters == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        if (parameters.length != 4) {
+            throw new DimensionMismatchException(4, parameters.length);
+        }
+        if (parameters[3] == 0.0) {
+            throw new ZeroException();
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/ParametricRealFunction.java b/src/main/java/org/apache/commons/math/optimization/fitting/ParametricRealFunction.java
new file mode 100644
index 0000000..0c2843e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/ParametricRealFunction.java
@@ -0,0 +1,50 @@
+/*
+ * 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.optimization.fitting;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * An interface representing a real function that depends on one independent
+ * variable plus some extra parameters.
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ */
+public interface ParametricRealFunction {
+
+    /**
+     * Compute the value of the function.
+     * @param x the point for which the function value should be computed
+     * @param parameters function parameters
+     * @return the value
+     * @throws FunctionEvaluationException if the function evaluation fails
+     */
+    double value(double x, double[] parameters)
+        throws FunctionEvaluationException;
+
+    /**
+     * Compute the gradient of the function with respect to its parameters.
+     * @param x the point for which the function value should be computed
+     * @param parameters function parameters
+     * @return the value
+     * @throws FunctionEvaluationException if the function evaluation fails
+     */
+    double[] gradient(double x, double[] parameters)
+        throws FunctionEvaluationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/PolynomialFitter.java b/src/main/java/org/apache/commons/math/optimization/fitting/PolynomialFitter.java
new file mode 100644
index 0000000..3e8e62a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/PolynomialFitter.java
@@ -0,0 +1,108 @@
+/*
+ * 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.optimization.fitting;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
+import org.apache.commons.math.optimization.OptimizationException;
+
+/** This class implements a curve fitting specialized for polynomials.
+ * <p>Polynomial fitting is a very simple case of curve fitting. The
+ * estimated coefficients are the polynomial coefficients. They are
+ * searched by a least square estimator.</p>
+ * @version $Revision: 1073270 $ $Date: 2011-02-22 10:19:27 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+
+public class PolynomialFitter {
+
+    /** Fitter for the coefficients. */
+    private final CurveFitter fitter;
+
+    /** Polynomial degree. */
+    private final int degree;
+
+    /** Simple constructor.
+     * <p>The polynomial fitter built this way are complete polynomials,
+     * ie. a n-degree polynomial has n+1 coefficients.</p>
+     * @param degree maximal degree of the polynomial
+     * @param optimizer optimizer to use for the fitting
+     */
+    public PolynomialFitter(int degree, final DifferentiableMultivariateVectorialOptimizer optimizer) {
+        this.fitter = new CurveFitter(optimizer);
+        this.degree = degree;
+    }
+
+    /** Add an observed weighted (x,y) point to the sample.
+     * @param weight weight of the observed point in the fit
+     * @param x abscissa of the point
+     * @param y observed value of the point at x, after fitting we should
+     * have P(x) as close as possible to this value
+     */
+    public void addObservedPoint(double weight, double x, double y) {
+        fitter.addObservedPoint(weight, x, y);
+    }
+
+    /**
+     * Remove all observations.
+     * @since 2.2
+     */
+    public void clearObservations() {
+        fitter.clearObservations();
+    }
+
+    /** Get the polynomial fitting the weighted (x, y) points.
+     * @return polynomial function best fitting the observed points
+     * @exception OptimizationException if the algorithm failed to converge
+     */
+    public PolynomialFunction fit() throws OptimizationException {
+        try {
+            return new PolynomialFunction(fitter.fit(new ParametricPolynomial(), new double[degree + 1]));
+        } catch (FunctionEvaluationException fee) {
+            // should never happen
+            throw new RuntimeException(fee);
+        }
+    }
+
+    /** Dedicated parametric polynomial class. */
+    private static class ParametricPolynomial implements ParametricRealFunction {
+
+        /** {@inheritDoc} */
+        public double[] gradient(double x, double[] parameters) {
+            final double[] gradient = new double[parameters.length];
+            double xn = 1.0;
+            for (int i = 0; i < parameters.length; ++i) {
+                gradient[i] = xn;
+                xn *= x;
+            }
+            return gradient;
+        }
+
+        /** {@inheritDoc} */
+        public double value(final double x, final double[] parameters) {
+            double y = 0;
+            for (int i = parameters.length - 1; i >= 0; --i) {
+                y = y * x + parameters[i];
+            }
+            return y;
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/WeightedObservedPoint.java b/src/main/java/org/apache/commons/math/optimization/fitting/WeightedObservedPoint.java
new file mode 100644
index 0000000..8153190
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/WeightedObservedPoint.java
@@ -0,0 +1,75 @@
+/*
+ * 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.optimization.fitting;
+
+import java.io.Serializable;
+
+/** This class is a simple container for weighted observed point in
+ * {@link CurveFitter curve fitting}.
+ * <p>Instances of this class are guaranteed to be immutable.</p>
+ * @version $Revision: 786479 $ $Date: 2009-06-19 14:36:16 +0200 (ven. 19 juin 2009) $
+ * @since 2.0
+ */
+public class WeightedObservedPoint implements Serializable {
+
+    /** Serializable version id. */
+    private static final long serialVersionUID = 5306874947404636157L;
+
+    /** Weight of the measurement in the fitting process. */
+    private final double weight;
+
+    /** Abscissa of the point. */
+    private final double x;
+
+    /** Observed value of the function at x. */
+    private final double y;
+
+    /** Simple constructor.
+     * @param weight weight of the measurement in the fitting process
+     * @param x abscissa of the measurement
+     * @param y ordinate of the measurement
+     */
+    public WeightedObservedPoint(final double weight, final double x, final double y) {
+        this.weight = weight;
+        this.x      = x;
+        this.y      = y;
+    }
+
+    /** Get the weight of the measurement in the fitting process.
+     * @return weight of the measurement in the fitting process
+     */
+    public double getWeight() {
+        return weight;
+    }
+
+    /** Get the abscissa of the point.
+     * @return abscissa of the point
+     */
+    public double getX() {
+        return x;
+    }
+
+    /** Get the observed value of the function at x.
+     * @return observed value of the function at x
+     */
+    public double getY() {
+        return y;
+    }
+
+}
+
diff --git a/src/main/java/org/apache/commons/math/optimization/fitting/package.html b/src/main/java/org/apache/commons/math/optimization/fitting/package.html
new file mode 100644
index 0000000..9f9fa06
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/fitting/package.html
@@ -0,0 +1,30 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision$ -->
+<body>
+This package provides classes to perform curve fitting.
+
+<p>Curve fitting is a special case of a least squares problem
+were the parameters are the coefficients of a function <code>f</code>
+whose graph <code>y=f(x)</code> should pass through sample points, and
+were the objective function is the squared sum of residuals
+<code>f(x<sub>i</sub>)-y<sub>i</sub></code> for observed points
+(x<sub>i</sub>, y<sub>i</sub>).</p>
+
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java b/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java
new file mode 100644
index 0000000..6271f53
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.java
@@ -0,0 +1,374 @@
+/*
+ * 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.optimization.general;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
+import org.apache.commons.math.analysis.MultivariateMatrixFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.InvalidMatrixException;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.SimpleVectorialValueChecker;
+import org.apache.commons.math.optimization.VectorialConvergenceChecker;
+import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
+import org.apache.commons.math.optimization.VectorialPointValuePair;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Base class for implementing least squares optimizers.
+ * <p>This base class handles the boilerplate methods associated to thresholds
+ * settings, jacobian and error estimation.</p>
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 1.2
+ *
+ */
+public abstract class AbstractLeastSquaresOptimizer implements DifferentiableMultivariateVectorialOptimizer {
+
+    /** Default maximal number of iterations allowed. */
+    public static final int DEFAULT_MAX_ITERATIONS = 100;
+
+    /** Convergence checker. */
+    protected VectorialConvergenceChecker checker;
+
+    /**
+     * Jacobian matrix.
+     * <p>This matrix is in canonical form just after the calls to
+     * {@link #updateJacobian()}, but may be modified by the solver
+     * in the derived class (the {@link LevenbergMarquardtOptimizer
+     * Levenberg-Marquardt optimizer} does this).</p>
+     */
+    protected double[][] jacobian;
+
+    /** Number of columns of the jacobian matrix. */
+    protected int cols;
+
+    /** Number of rows of the jacobian matrix. */
+    protected int rows;
+
+    /**
+     * Target value for the objective functions at optimum.
+     * @since 2.1
+     */
+    protected double[] targetValues;
+
+    /**
+     * Weight for the least squares cost computation.
+     * @since 2.1
+     */
+    protected double[] residualsWeights;
+
+    /** Current point. */
+    protected double[] point;
+
+    /** Current objective function value. */
+    protected double[] objective;
+
+    /** Current residuals. */
+    protected double[] residuals;
+
+    /** Weighted Jacobian */
+    protected double[][] wjacobian;
+
+    /** Weighted residuals */
+    protected double[] wresiduals;
+
+    /** Cost value (square root of the sum of the residuals). */
+    protected double cost;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Number of iterations already performed. */
+    private int iterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed. */
+    private int objectiveEvaluations;
+
+    /** Number of jacobian evaluations. */
+    private int jacobianEvaluations;
+
+    /** Objective function. */
+    private DifferentiableMultivariateVectorialFunction function;
+
+    /** Objective function derivatives. */
+    private MultivariateMatrixFunction jF;
+
+    /** Simple constructor with default settings.
+     * <p>The convergence check is set to a {@link SimpleVectorialValueChecker}
+     * and the maximal number of evaluation is set to its default value.</p>
+     */
+    protected AbstractLeastSquaresOptimizer() {
+        setConvergenceChecker(new SimpleVectorialValueChecker());
+        setMaxIterations(DEFAULT_MAX_ITERATIONS);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return iterations;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return objectiveEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getJacobianEvaluations() {
+        return jacobianEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setConvergenceChecker(VectorialConvergenceChecker convergenceChecker) {
+        this.checker = convergenceChecker;
+    }
+
+    /** {@inheritDoc} */
+    public VectorialConvergenceChecker getConvergenceChecker() {
+        return checker;
+    }
+
+    /** Increment the iterations counter by 1.
+     * @exception OptimizationException if the maximal number
+     * of iterations is exceeded
+     */
+    protected void incrementIterationsCounter()
+        throws OptimizationException {
+        if (++iterations > maxIterations) {
+            throw new OptimizationException(new MaxIterationsExceededException(maxIterations));
+        }
+    }
+
+    /**
+     * Update the jacobian matrix.
+     * @exception FunctionEvaluationException if the function jacobian
+     * cannot be evaluated or its dimension doesn't match problem dimension
+     */
+    protected void updateJacobian() throws FunctionEvaluationException {
+        ++jacobianEvaluations;
+        jacobian = jF.value(point);
+        if (jacobian.length != rows) {
+            throw new FunctionEvaluationException(point, LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                                                  jacobian.length, rows);
+        }
+        for (int i = 0; i < rows; i++) {
+            final double[] ji = jacobian[i];
+            double wi = FastMath.sqrt(residualsWeights[i]);
+            for (int j = 0; j < cols; ++j) {
+                ji[j] *=  -1.0;
+                wjacobian[i][j] = ji[j]*wi;
+            }
+        }
+    }
+
+    /**
+     * Update the residuals array and cost function value.
+     * @exception FunctionEvaluationException if the function cannot be evaluated
+     * or its dimension doesn't match problem dimension or maximal number of
+     * of evaluations is exceeded
+     */
+    protected void updateResidualsAndCost()
+        throws FunctionEvaluationException {
+
+        if (++objectiveEvaluations > maxEvaluations) {
+            throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations),
+                                                  point);
+        }
+        objective = function.value(point);
+        if (objective.length != rows) {
+            throw new FunctionEvaluationException(point, LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                                                  objective.length, rows);
+        }
+        cost = 0;
+        int index = 0;
+        for (int i = 0; i < rows; i++) {
+            final double residual = targetValues[i] - objective[i];
+            residuals[i] = residual;
+            wresiduals[i]= residual*FastMath.sqrt(residualsWeights[i]);
+            cost += residualsWeights[i] * residual * residual;
+            index += cols;
+        }
+        cost = FastMath.sqrt(cost);
+
+    }
+
+    /**
+     * Get the Root Mean Square value.
+     * Get the Root Mean Square value, i.e. the root of the arithmetic
+     * mean of the square of all weighted residuals. This is related to the
+     * criterion that is minimized by the optimizer as follows: if
+     * <em>c</em> if the criterion, and <em>n</em> is the number of
+     * measurements, then the RMS is <em>sqrt (c/n)</em>.
+     *
+     * @return RMS value
+     */
+    public double getRMS() {
+        return FastMath.sqrt(getChiSquare() / rows);
+    }
+
+    /**
+     * Get a Chi-Square-like value assuming the N residuals follow N
+     * distinct normal distributions centered on 0 and whose variances are
+     * the reciprocal of the weights.
+     * @return chi-square value
+     */
+    public double getChiSquare() {
+        return cost*cost;
+    }
+
+    /**
+     * Get the covariance matrix of optimized parameters.
+     * @return covariance matrix
+     * @exception FunctionEvaluationException if the function jacobian cannot
+     * be evaluated
+     * @exception OptimizationException if the covariance matrix
+     * cannot be computed (singular problem)
+     */
+    public double[][] getCovariances()
+        throws FunctionEvaluationException, OptimizationException {
+
+        // set up the jacobian
+        updateJacobian();
+
+        // compute transpose(J).J, avoiding building big intermediate matrices
+        double[][] jTj = new double[cols][cols];
+        for (int i = 0; i < cols; ++i) {
+            for (int j = i; j < cols; ++j) {
+                double sum = 0;
+                for (int k = 0; k < rows; ++k) {
+                    sum += wjacobian[k][i] * wjacobian[k][j];
+                }
+                jTj[i][j] = sum;
+                jTj[j][i] = sum;
+            }
+        }
+
+        try {
+            // compute the covariance matrix
+            RealMatrix inverse =
+                new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse();
+            return inverse.getData();
+        } catch (InvalidMatrixException ime) {
+            throw new OptimizationException(LocalizedFormats.UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM);
+        }
+
+    }
+
+    /**
+     * Guess the errors in optimized parameters.
+     * <p>Guessing is covariance-based, it only gives rough order of magnitude.</p>
+     * @return errors in optimized parameters
+     * @exception FunctionEvaluationException if the function jacobian cannot b evaluated
+     * @exception OptimizationException if the covariances matrix cannot be computed
+     * or the number of degrees of freedom is not positive (number of measurements
+     * lesser or equal to number of parameters)
+     */
+    public double[] guessParametersErrors()
+        throws FunctionEvaluationException, OptimizationException {
+        if (rows <= cols) {
+            throw new OptimizationException(
+                    LocalizedFormats.NO_DEGREES_OF_FREEDOM,
+                    rows, cols);
+        }
+        double[] errors = new double[cols];
+        final double c = FastMath.sqrt(getChiSquare() / (rows - cols));
+        double[][] covar = getCovariances();
+        for (int i = 0; i < errors.length; ++i) {
+            errors[i] = FastMath.sqrt(covar[i][i]) * c;
+        }
+        return errors;
+    }
+
+    /** {@inheritDoc} */
+    public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f,
+                                            final double[] target, final double[] weights,
+                                            final double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        if (target.length != weights.length) {
+            throw new OptimizationException(LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                                            target.length, weights.length);
+        }
+
+        // reset counters
+        iterations           = 0;
+        objectiveEvaluations = 0;
+        jacobianEvaluations  = 0;
+
+        // store least squares problem characteristics
+        function         = f;
+        jF               = f.jacobian();
+        targetValues     = target.clone();
+        residualsWeights = weights.clone();
+        this.point       = startPoint.clone();
+        this.residuals   = new double[target.length];
+
+        // arrays shared with the other private methods
+        rows      = target.length;
+        cols      = point.length;
+        jacobian  = new double[rows][cols];
+
+        wjacobian = new double[rows][cols];
+        wresiduals = new double[rows];
+
+        cost = Double.POSITIVE_INFINITY;
+
+        return doOptimize();
+
+    }
+
+    /** Perform the bulk of optimization algorithm.
+     * @return the point/value pair giving the optimal value for objective function
+     * @exception FunctionEvaluationException if the objective function throws one during
+     * the search
+     * @exception OptimizationException if the algorithm failed to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    protected abstract VectorialPointValuePair doOptimize()
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/AbstractScalarDifferentiableOptimizer.java b/src/main/java/org/apache/commons/math/optimization/general/AbstractScalarDifferentiableOptimizer.java
new file mode 100644
index 0000000..70f0a23
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/AbstractScalarDifferentiableOptimizer.java
@@ -0,0 +1,207 @@
+/*
+ * 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.optimization.general;
+
+import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
+import org.apache.commons.math.analysis.MultivariateVectorialFunction;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealConvergenceChecker;
+import org.apache.commons.math.optimization.RealPointValuePair;
+import org.apache.commons.math.optimization.SimpleScalarValueChecker;
+
+/**
+ * Base class for implementing optimizers for multivariate scalar functions.
+ * <p>This base class handles the boilerplate methods associated to thresholds
+ * settings, iterations and evaluations counting.</p>
+ * @version $Revision: 1069567 $ $Date: 2011-02-10 22:07:26 +0100 (jeu. 10 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AbstractScalarDifferentiableOptimizer
+    implements DifferentiableMultivariateRealOptimizer {
+
+    /** Default maximal number of iterations allowed. */
+    public static final int DEFAULT_MAX_ITERATIONS = 100;
+
+    /** Convergence checker. */
+    @Deprecated
+    protected RealConvergenceChecker checker;
+
+    /**
+     * Type of optimization.
+     * @since 2.1
+     */
+    @Deprecated
+    protected GoalType goal;
+
+    /** Current point set. */
+    @Deprecated
+    protected double[] point;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Number of iterations already performed. */
+    private int iterations;
+
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+
+    /** Number of evaluations already performed. */
+    private int evaluations;
+
+    /** Number of gradient evaluations. */
+    private int gradientEvaluations;
+
+    /** Objective function. */
+    private DifferentiableMultivariateRealFunction function;
+
+    /** Objective function gradient. */
+    private MultivariateVectorialFunction gradient;
+
+    /** Simple constructor with default settings.
+     * <p>The convergence check is set to a {@link SimpleScalarValueChecker}
+     * and the maximal number of evaluation is set to its default value.</p>
+     */
+    protected AbstractScalarDifferentiableOptimizer() {
+        setConvergenceChecker(new SimpleScalarValueChecker());
+        setMaxIterations(DEFAULT_MAX_ITERATIONS);
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return iterations;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return evaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getGradientEvaluations() {
+        return gradientEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) {
+        this.checker = convergenceChecker;
+    }
+
+    /** {@inheritDoc} */
+    public RealConvergenceChecker getConvergenceChecker() {
+        return checker;
+    }
+
+    /** Increment the iterations counter by 1.
+     * @exception OptimizationException if the maximal number
+     * of iterations is exceeded
+     */
+    protected void incrementIterationsCounter()
+        throws OptimizationException {
+        if (++iterations > maxIterations) {
+            throw new OptimizationException(new MaxIterationsExceededException(maxIterations));
+        }
+    }
+
+    /**
+     * Compute the gradient vector.
+     * @param evaluationPoint point at which the gradient must be evaluated
+     * @return gradient at the specified point
+     * @exception FunctionEvaluationException if the function gradient
+     */
+    protected double[] computeObjectiveGradient(final double[] evaluationPoint)
+        throws FunctionEvaluationException {
+        ++gradientEvaluations;
+        return gradient.value(evaluationPoint);
+    }
+
+    /**
+     * Compute the objective function value.
+     * @param evaluationPoint point at which the objective function must be evaluated
+     * @return objective function value at specified point
+     * @exception FunctionEvaluationException if the function cannot be evaluated
+     * or its dimension doesn't match problem dimension or the maximal number
+     * of iterations is exceeded
+     */
+    protected double computeObjectiveValue(final double[] evaluationPoint)
+        throws FunctionEvaluationException {
+        if (++evaluations > maxEvaluations) {
+            throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations),
+                                                  evaluationPoint);
+        }
+        return function.value(evaluationPoint);
+    }
+
+    /** {@inheritDoc} */
+    public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f,
+                                         final GoalType goalType,
+                                         final double[] startPoint)
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        // reset counters
+        iterations          = 0;
+        evaluations         = 0;
+        gradientEvaluations = 0;
+
+        // store optimization problem characteristics
+        function = f;
+        gradient = f.gradient();
+        goal     = goalType;
+        point    = startPoint.clone();
+
+        return doOptimize();
+
+    }
+
+    /** Perform the bulk of optimization algorithm.
+     * @return the point/value pair giving the optimal value for objective function
+     * @exception FunctionEvaluationException if the objective function throws one during
+     * the search
+     * @exception OptimizationException if the algorithm failed to converge
+     * @exception IllegalArgumentException if the start point dimension is wrong
+     */
+    protected abstract RealPointValuePair doOptimize()
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/ConjugateGradientFormula.java b/src/main/java/org/apache/commons/math/optimization/general/ConjugateGradientFormula.java
new file mode 100644
index 0000000..8a0fde3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/ConjugateGradientFormula.java
@@ -0,0 +1,49 @@
+/*
+ * 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.optimization.general;
+
+/**
+ * Available choices of update formulas for the &beta; parameter
+ * in {@link NonLinearConjugateGradientOptimizer}.
+ * <p>
+ * The &beta; parameter is used to compute the successive conjugate
+ * search directions. For non-linear conjugate gradients, there are
+ * two formulas to compute &beta;:
+ * <ul>
+ *   <li>Fletcher-Reeves formula</li>
+ *   <li>Polak-Ribi&egrave;re formula</li>
+ * </ul>
+ * On the one hand, the Fletcher-Reeves formula is guaranteed to converge
+ * if the start point is close enough of the optimum whether the
+ * Polak-Ribi&egrave;re formula may not converge in rare cases. On the
+ * other hand, the Polak-Ribi&egrave;re formula is often faster when it
+ * does converge. Polak-Ribi&egrave;re is often used.
+ * <p>
+ * @see NonLinearConjugateGradientOptimizer
+ * @version $Revision: 758059 $ $Date: 2009-03-24 23:16:21 +0100 (mar. 24 mars 2009) $
+ * @since 2.0
+ */
+public enum ConjugateGradientFormula {
+
+    /** Fletcher-Reeves formula. */
+    FLETCHER_REEVES,
+
+    /** Polak-Ribi&egrave;re formula. */
+    POLAK_RIBIERE
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java b/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java
new file mode 100644
index 0000000..e7ba606
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.java
@@ -0,0 +1,135 @@
+/*
+ * 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.optimization.general;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.BlockRealMatrix;
+import org.apache.commons.math.linear.DecompositionSolver;
+import org.apache.commons.math.linear.InvalidMatrixException;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.QRDecompositionImpl;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.VectorialPointValuePair;
+
+/**
+ * Gauss-Newton least-squares solver.
+ * <p>
+ * This class solve a least-square problem by solving the normal equations
+ * of the linearized problem at each iteration. Either LU decomposition or
+ * QR decomposition can be used to solve the normal equations. LU decomposition
+ * is faster but QR decomposition is more robust for difficult problems.
+ * </p>
+ *
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ *
+ */
+
+public class GaussNewtonOptimizer extends AbstractLeastSquaresOptimizer {
+
+    /** Indicator for using LU decomposition. */
+    private final boolean useLU;
+
+    /** Simple constructor with default settings.
+     * <p>The convergence check is set to a {@link
+     * org.apache.commons.math.optimization.SimpleVectorialValueChecker}
+     * and the maximal number of evaluation is set to
+     * {@link AbstractLeastSquaresOptimizer#DEFAULT_MAX_ITERATIONS}.
+     * @param useLU if true, the normal equations will be solved using LU
+     * decomposition, otherwise they will be solved using QR decomposition
+     */
+    public GaussNewtonOptimizer(final boolean useLU) {
+        this.useLU = useLU;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public VectorialPointValuePair doOptimize()
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        // iterate until convergence is reached
+        VectorialPointValuePair current = null;
+        for (boolean converged = false; !converged;) {
+
+            incrementIterationsCounter();
+
+            // evaluate the objective function and its jacobian
+            VectorialPointValuePair previous = current;
+            updateResidualsAndCost();
+            updateJacobian();
+            current = new VectorialPointValuePair(point, objective);
+
+            // build the linear problem
+            final double[]   b = new double[cols];
+            final double[][] a = new double[cols][cols];
+            for (int i = 0; i < rows; ++i) {
+
+                final double[] grad   = jacobian[i];
+                final double weight   = residualsWeights[i];
+                final double residual = objective[i] - targetValues[i];
+
+                // compute the normal equation
+                final double wr = weight * residual;
+                for (int j = 0; j < cols; ++j) {
+                    b[j] += wr * grad[j];
+                }
+
+                // build the contribution matrix for measurement i
+                for (int k = 0; k < cols; ++k) {
+                    double[] ak = a[k];
+                    double wgk = weight * grad[k];
+                    for (int l = 0; l < cols; ++l) {
+                        ak[l] += wgk * grad[l];
+                    }
+                }
+
+            }
+
+            try {
+
+                // solve the linearized least squares problem
+                RealMatrix mA = new BlockRealMatrix(a);
+                DecompositionSolver solver = useLU ?
+                        new LUDecompositionImpl(mA).getSolver() :
+                        new QRDecompositionImpl(mA).getSolver();
+                final double[] dX = solver.solve(b);
+
+                // update the estimated parameters
+                for (int i = 0; i < cols; ++i) {
+                    point[i] += dX[i];
+                }
+
+            } catch(InvalidMatrixException e) {
+                throw new OptimizationException(LocalizedFormats.UNABLE_TO_SOLVE_SINGULAR_PROBLEM);
+            }
+
+            // check convergence
+            if (previous != null) {
+                converged = checker.converged(getIterations(), previous, current);
+            }
+
+        }
+
+        // we have converged
+        return current;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java b/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java
new file mode 100644
index 0000000..ea9bc03
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.java
@@ -0,0 +1,888 @@
+/*
+ * 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.optimization.general;
+
+import java.util.Arrays;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.VectorialPointValuePair;
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+
+/**
+ * This class solves a least squares problem using the Levenberg-Marquardt algorithm.
+ *
+ * <p>This implementation <em>should</em> work even for over-determined systems
+ * (i.e. systems having more point than equations). Over-determined systems
+ * are solved by ignoring the point which have the smallest impact according
+ * to their jacobian column norm. Only the rank of the matrix and some loop bounds
+ * are changed to implement this.</p>
+ *
+ * <p>The resolution engine is a simple translation of the MINPACK <a
+ * href="http://www.netlib.org/minpack/lmder.f">lmder</a> routine with minor
+ * changes. The changes include the over-determined resolution, the use of
+ * inherited convergence checker and the Q.R. decomposition which has been
+ * rewritten following the algorithm described in the
+ * P. Lascaux and R. Theodor book <i>Analyse num&eacute;rique matricielle
+ * appliqu&eacute;e &agrave; l'art de l'ing&eacute;nieur</i>, Masson 1986.</p>
+ * <p>The authors of the original fortran version are:
+ * <ul>
+ * <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+ * <li>Burton S. Garbow</li>
+ * <li>Kenneth E. Hillstrom</li>
+ * <li>Jorge J. More</li>
+ * </ul>
+ * The redistribution policy for MINPACK is available <a
+ * href="http://www.netlib.org/minpack/disclaimer">here</a>, for convenience, it
+ * is reproduced below.</p>
+ *
+ * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+ * <tr><td>
+ *    Minpack Copyright Notice (1999) University of Chicago.
+ *    All rights reserved
+ * </td></tr>
+ * <tr><td>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * <ol>
+ *  <li>Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.</li>
+ * <li>Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.</li>
+ * <li>The end-user documentation included with the redistribution, if any,
+ *     must include the following acknowledgment:
+ *     <code>This product includes software developed by the University of
+ *           Chicago, as Operator of Argonne National Laboratory.</code>
+ *     Alternately, this acknowledgment may appear in the software itself,
+ *     if and wherever such third-party acknowledgments normally appear.</li>
+ * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
+ *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
+ *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
+ *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
+ *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
+ *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
+ *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
+ *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
+ *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
+ *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
+ *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
+ *     BE CORRECTED.</strong></li>
+ * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
+ *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
+ *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
+ *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
+ *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
+ *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
+ *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
+ *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
+ *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
+ *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
+ * <ol></td></tr>
+ * </table>
+ * @version $Revision: 1073272 $ $Date: 2011-02-22 10:22:25 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ *
+ */
+public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer {
+
+    /** Number of solved point. */
+    private int solvedCols;
+
+    /** Diagonal elements of the R matrix in the Q.R. decomposition. */
+    private double[] diagR;
+
+    /** Norms of the columns of the jacobian matrix. */
+    private double[] jacNorm;
+
+    /** Coefficients of the Householder transforms vectors. */
+    private double[] beta;
+
+    /** Columns permutation array. */
+    private int[] permutation;
+
+    /** Rank of the jacobian matrix. */
+    private int rank;
+
+    /** Levenberg-Marquardt parameter. */
+    private double lmPar;
+
+    /** Parameters evolution direction associated with lmPar. */
+    private double[] lmDir;
+
+    /** Positive input variable used in determining the initial step bound. */
+    private double initialStepBoundFactor;
+
+    /** Desired relative error in the sum of squares. */
+    private double costRelativeTolerance;
+
+    /**  Desired relative error in the approximate solution parameters. */
+    private double parRelativeTolerance;
+
+    /** Desired max cosine on the orthogonality between the function vector
+     * and the columns of the jacobian. */
+    private double orthoTolerance;
+
+    /** Threshold for QR ranking. */
+    private double qrRankingThreshold;
+
+    /**
+     * Build an optimizer for least squares problems.
+     * <p>The default values for the algorithm settings are:
+     *   <ul>
+     *    <li>{@link #setConvergenceChecker(VectorialConvergenceChecker) vectorial convergence checker}: null</li>
+     *    <li>{@link #setInitialStepBoundFactor(double) initial step bound factor}: 100.0</li>
+     *    <li>{@link #setMaxIterations(int) maximal iterations}: 1000</li>
+     *    <li>{@link #setCostRelativeTolerance(double) cost relative tolerance}: 1.0e-10</li>
+     *    <li>{@link #setParRelativeTolerance(double) parameters relative tolerance}: 1.0e-10</li>
+     *    <li>{@link #setOrthoTolerance(double) orthogonality tolerance}: 1.0e-10</li>
+     *    <li>{@link #setQRRankingThreshold(double) QR ranking threshold}: {@link MathUtils#SAFE_MIN}</li>
+     *   </ul>
+     * </p>
+     * <p>These default values may be overridden after construction. If the {@link
+     * #setConvergenceChecker vectorial convergence checker} is set to a non-null value, it
+     * will be used instead of the {@link #setCostRelativeTolerance cost relative tolerance}
+     * and {@link #setParRelativeTolerance parameters relative tolerance} settings.
+     */
+    public LevenbergMarquardtOptimizer() {
+
+        // set up the superclass with a default  max cost evaluations setting
+        setMaxIterations(1000);
+
+        // default values for the tuning parameters
+        setConvergenceChecker(null);
+        setInitialStepBoundFactor(100.0);
+        setCostRelativeTolerance(1.0e-10);
+        setParRelativeTolerance(1.0e-10);
+        setOrthoTolerance(1.0e-10);
+        setQRRankingThreshold(MathUtils.SAFE_MIN);
+
+    }
+
+    /**
+     * Set the positive input variable used in determining the initial step bound.
+     * This bound is set to the product of initialStepBoundFactor and the euclidean
+     * norm of diag*x if nonzero, or else to initialStepBoundFactor itself. In most
+     * cases factor should lie in the interval (0.1, 100.0). 100.0 is a generally
+     * recommended value.
+     *
+     * @param initialStepBoundFactor initial step bound factor
+     */
+    public void setInitialStepBoundFactor(double initialStepBoundFactor) {
+        this.initialStepBoundFactor = initialStepBoundFactor;
+    }
+
+    /**
+     * Set the desired relative error in the sum of squares.
+     * <p>This setting is used only if the {@link #setConvergenceChecker vectorial
+     * convergence checker} is set to null.</p>
+     * @param costRelativeTolerance desired relative error in the sum of squares
+     */
+    public void setCostRelativeTolerance(double costRelativeTolerance) {
+        this.costRelativeTolerance = costRelativeTolerance;
+    }
+
+    /**
+     * Set the desired relative error in the approximate solution parameters.
+     * <p>This setting is used only if the {@link #setConvergenceChecker vectorial
+     * convergence checker} is set to null.</p>
+     * @param parRelativeTolerance desired relative error
+     * in the approximate solution parameters
+     */
+    public void setParRelativeTolerance(double parRelativeTolerance) {
+        this.parRelativeTolerance = parRelativeTolerance;
+    }
+
+    /**
+     * Set the desired max cosine on the orthogonality.
+     * <p>This setting is always used, regardless of the {@link #setConvergenceChecker
+     * vectorial convergence checker} being null or non-null.</p>
+     * @param orthoTolerance desired max cosine on the orthogonality
+     * between the function vector and the columns of the jacobian
+     */
+    public void setOrthoTolerance(double orthoTolerance) {
+        this.orthoTolerance = orthoTolerance;
+    }
+
+    /**
+     * Set the desired threshold for QR ranking.
+     * <p>
+     * If the squared norm of a column vector is smaller or equal to this threshold
+     * during QR decomposition, it is considered to be a zero vector and hence the
+     * rank of the matrix is reduced.
+     * </p>
+     * @param threshold threshold for QR ranking
+     * @since 2.2
+     */
+    public void setQRRankingThreshold(final double threshold) {
+        this.qrRankingThreshold = threshold;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected VectorialPointValuePair doOptimize()
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+
+        // arrays shared with the other private methods
+        solvedCols  = Math.min(rows, cols);
+        diagR       = new double[cols];
+        jacNorm     = new double[cols];
+        beta        = new double[cols];
+        permutation = new int[cols];
+        lmDir       = new double[cols];
+
+        // local point
+        double   delta   = 0;
+        double   xNorm   = 0;
+        double[] diag    = new double[cols];
+        double[] oldX    = new double[cols];
+        double[] oldRes  = new double[rows];
+        double[] oldObj  = new double[rows];
+        double[] qtf     = new double[rows];
+        double[] work1   = new double[cols];
+        double[] work2   = new double[cols];
+        double[] work3   = new double[cols];
+
+        // evaluate the function at the starting point and calculate its norm
+        updateResidualsAndCost();
+
+        // outer loop
+        lmPar = 0;
+        boolean firstIteration = true;
+        VectorialPointValuePair current = new VectorialPointValuePair(point, objective);
+        while (true) {
+            for (int i=0;i<rows;i++) {
+                qtf[i]=wresiduals[i];
+            }
+            incrementIterationsCounter();
+
+            // compute the Q.R. decomposition of the jacobian matrix
+            VectorialPointValuePair previous = current;
+            updateJacobian();
+            qrDecomposition();
+
+            // compute Qt.res
+            qTy(qtf);
+            // now we don't need Q anymore,
+            // so let jacobian contain the R matrix with its diagonal elements
+            for (int k = 0; k < solvedCols; ++k) {
+                int pk = permutation[k];
+                wjacobian[k][pk] = diagR[pk];
+            }
+
+            if (firstIteration) {
+
+                // scale the point according to the norms of the columns
+                // of the initial jacobian
+                xNorm = 0;
+                for (int k = 0; k < cols; ++k) {
+                    double dk = jacNorm[k];
+                    if (dk == 0) {
+                        dk = 1.0;
+                    }
+                    double xk = dk * point[k];
+                    xNorm  += xk * xk;
+                    diag[k] = dk;
+                }
+                xNorm = FastMath.sqrt(xNorm);
+
+                // initialize the step bound delta
+                delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm);
+
+            }
+
+            // check orthogonality between function vector and jacobian columns
+            double maxCosine = 0;
+            if (cost != 0) {
+                for (int j = 0; j < solvedCols; ++j) {
+                    int    pj = permutation[j];
+                    double s  = jacNorm[pj];
+                    if (s != 0) {
+                        double sum = 0;
+                        for (int i = 0; i <= j; ++i) {
+                            sum += wjacobian[i][pj] * qtf[i];
+                        }
+                        maxCosine = FastMath.max(maxCosine, FastMath.abs(sum) / (s * cost));
+                    }
+                }
+            }
+            if (maxCosine <= orthoTolerance) {
+                // convergence has been reached
+                updateResidualsAndCost();
+                current = new VectorialPointValuePair(point, objective);
+                return current;
+            }
+
+            // rescale if necessary
+            for (int j = 0; j < cols; ++j) {
+                diag[j] = FastMath.max(diag[j], jacNorm[j]);
+            }
+
+            // inner loop
+            for (double ratio = 0; ratio < 1.0e-4;) {
+
+                // save the state
+                for (int j = 0; j < solvedCols; ++j) {
+                    int pj = permutation[j];
+                    oldX[pj] = point[pj];
+                }
+                double previousCost = cost;
+                double[] tmpVec = residuals;
+                residuals = oldRes;
+                oldRes    = tmpVec;
+                tmpVec    = objective;
+                objective = oldObj;
+                oldObj    = tmpVec;
+
+                // determine the Levenberg-Marquardt parameter
+                determineLMParameter(qtf, delta, diag, work1, work2, work3);
+
+                // compute the new point and the norm of the evolution direction
+                double lmNorm = 0;
+                for (int j = 0; j < solvedCols; ++j) {
+                    int pj = permutation[j];
+                    lmDir[pj] = -lmDir[pj];
+                    point[pj] = oldX[pj] + lmDir[pj];
+                    double s = diag[pj] * lmDir[pj];
+                    lmNorm  += s * s;
+                }
+                lmNorm = FastMath.sqrt(lmNorm);
+                // on the first iteration, adjust the initial step bound.
+                if (firstIteration) {
+                    delta = FastMath.min(delta, lmNorm);
+                }
+
+                // evaluate the function at x + p and calculate its norm
+                updateResidualsAndCost();
+
+                // compute the scaled actual reduction
+                double actRed = -1.0;
+                if (0.1 * cost < previousCost) {
+                    double r = cost / previousCost;
+                    actRed = 1.0 - r * r;
+                }
+
+                // compute the scaled predicted reduction
+                // and the scaled directional derivative
+                for (int j = 0; j < solvedCols; ++j) {
+                    int pj = permutation[j];
+                    double dirJ = lmDir[pj];
+                    work1[j] = 0;
+                    for (int i = 0; i <= j; ++i) {
+                        work1[i] += wjacobian[i][pj] * dirJ;
+                    }
+                }
+                double coeff1 = 0;
+                for (int j = 0; j < solvedCols; ++j) {
+                    coeff1 += work1[j] * work1[j];
+                }
+                double pc2 = previousCost * previousCost;
+                coeff1 = coeff1 / pc2;
+                double coeff2 = lmPar * lmNorm * lmNorm / pc2;
+                double preRed = coeff1 + 2 * coeff2;
+                double dirDer = -(coeff1 + coeff2);
+
+                // ratio of the actual to the predicted reduction
+                ratio = (preRed == 0) ? 0 : (actRed / preRed);
+
+                // update the step bound
+                if (ratio <= 0.25) {
+                    double tmp =
+                        (actRed < 0) ? (0.5 * dirDer / (dirDer + 0.5 * actRed)) : 0.5;
+                        if ((0.1 * cost >= previousCost) || (tmp < 0.1)) {
+                            tmp = 0.1;
+                        }
+                        delta = tmp * FastMath.min(delta, 10.0 * lmNorm);
+                        lmPar /= tmp;
+                } else if ((lmPar == 0) || (ratio >= 0.75)) {
+                    delta = 2 * lmNorm;
+                    lmPar *= 0.5;
+                }
+
+                // test for successful iteration.
+                if (ratio >= 1.0e-4) {
+                    // successful iteration, update the norm
+                    firstIteration = false;
+                    xNorm = 0;
+                    for (int k = 0; k < cols; ++k) {
+                        double xK = diag[k] * point[k];
+                        xNorm    += xK * xK;
+                    }
+                    xNorm = FastMath.sqrt(xNorm);
+                    current = new VectorialPointValuePair(point, objective);
+
+                    // tests for convergence.
+                    if (checker != null) {
+                    // we use the vectorial convergence checker
+                        if (checker.converged(getIterations(), previous, current)) {
+                            return current;
+                        }
+                    }
+                } else {
+                    // failed iteration, reset the previous values
+                    cost = previousCost;
+                    for (int j = 0; j < solvedCols; ++j) {
+                        int pj = permutation[j];
+                        point[pj] = oldX[pj];
+                    }
+                    tmpVec    = residuals;
+                    residuals = oldRes;
+                    oldRes    = tmpVec;
+                    tmpVec    = objective;
+                    objective = oldObj;
+                    oldObj    = tmpVec;
+                }
+                if (checker==null) {
+                    if (((FastMath.abs(actRed) <= costRelativeTolerance) &&
+                        (preRed <= costRelativeTolerance) &&
+                        (ratio <= 2.0)) ||
+                       (delta <= parRelativeTolerance * xNorm)) {
+                       return current;
+                   }
+                }
+                // tests for termination and stringent tolerances
+                // (2.2204e-16 is the machine epsilon for IEEE754)
+                if ((FastMath.abs(actRed) <= 2.2204e-16) && (preRed <= 2.2204e-16) && (ratio <= 2.0)) {
+                    throw new OptimizationException(LocalizedFormats.TOO_SMALL_COST_RELATIVE_TOLERANCE,
+                            costRelativeTolerance);
+                } else if (delta <= 2.2204e-16 * xNorm) {
+                    throw new OptimizationException(LocalizedFormats.TOO_SMALL_PARAMETERS_RELATIVE_TOLERANCE,
+                            parRelativeTolerance);
+                } else if (maxCosine <= 2.2204e-16)  {
+                    throw new OptimizationException(LocalizedFormats.TOO_SMALL_ORTHOGONALITY_TOLERANCE,
+                            orthoTolerance);
+                }
+
+            }
+
+        }
+
+    }
+
+    /**
+     * Determine the Levenberg-Marquardt parameter.
+     * <p>This implementation is a translation in Java of the MINPACK
+     * <a href="http://www.netlib.org/minpack/lmpar.f">lmpar</a>
+     * routine.</p>
+     * <p>This method sets the lmPar and lmDir attributes.</p>
+     * <p>The authors of the original fortran function are:</p>
+     * <ul>
+     *   <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+     *   <li>Burton  S. Garbow</li>
+     *   <li>Kenneth E. Hillstrom</li>
+     *   <li>Jorge   J. More</li>
+     * </ul>
+     * <p>Luc Maisonobe did the Java translation.</p>
+     *
+     * @param qy array containing qTy
+     * @param delta upper bound on the euclidean norm of diagR * lmDir
+     * @param diag diagonal matrix
+     * @param work1 work array
+     * @param work2 work array
+     * @param work3 work array
+     */
+    private void determineLMParameter(double[] qy, double delta, double[] diag,
+            double[] work1, double[] work2, double[] work3) {
+
+        // compute and store in x the gauss-newton direction, if the
+        // jacobian is rank-deficient, obtain a least squares solution
+        for (int j = 0; j < rank; ++j) {
+            lmDir[permutation[j]] = qy[j];
+        }
+        for (int j = rank; j < cols; ++j) {
+            lmDir[permutation[j]] = 0;
+        }
+        for (int k = rank - 1; k >= 0; --k) {
+            int pk = permutation[k];
+            double ypk = lmDir[pk] / diagR[pk];
+            for (int i = 0; i < k; ++i) {
+                lmDir[permutation[i]] -= ypk * wjacobian[i][pk];
+            }
+            lmDir[pk] = ypk;
+        }
+
+        // evaluate the function at the origin, and test
+        // for acceptance of the Gauss-Newton direction
+        double dxNorm = 0;
+        for (int j = 0; j < solvedCols; ++j) {
+            int pj = permutation[j];
+            double s = diag[pj] * lmDir[pj];
+            work1[pj] = s;
+            dxNorm += s * s;
+        }
+        dxNorm = FastMath.sqrt(dxNorm);
+        double fp = dxNorm - delta;
+        if (fp <= 0.1 * delta) {
+            lmPar = 0;
+            return;
+        }
+
+        // if the jacobian is not rank deficient, the Newton step provides
+        // a lower bound, parl, for the zero of the function,
+        // otherwise set this bound to zero
+        double sum2;
+        double parl = 0;
+        if (rank == solvedCols) {
+            for (int j = 0; j < solvedCols; ++j) {
+                int pj = permutation[j];
+                work1[pj] *= diag[pj] / dxNorm;
+            }
+            sum2 = 0;
+            for (int j = 0; j < solvedCols; ++j) {
+                int pj = permutation[j];
+                double sum = 0;
+                for (int i = 0; i < j; ++i) {
+                    sum += wjacobian[i][pj] * work1[permutation[i]];
+                }
+                double s = (work1[pj] - sum) / diagR[pj];
+                work1[pj] = s;
+                sum2 += s * s;
+            }
+            parl = fp / (delta * sum2);
+        }
+
+        // calculate an upper bound, paru, for the zero of the function
+        sum2 = 0;
+        for (int j = 0; j < solvedCols; ++j) {
+            int pj = permutation[j];
+            double sum = 0;
+            for (int i = 0; i <= j; ++i) {
+                sum += wjacobian[i][pj] * qy[i];
+            }
+            sum /= diag[pj];
+            sum2 += sum * sum;
+        }
+        double gNorm = FastMath.sqrt(sum2);
+        double paru = gNorm / delta;
+        if (paru == 0) {
+            // 2.2251e-308 is the smallest positive real for IEE754
+            paru = 2.2251e-308 / FastMath.min(delta, 0.1);
+        }
+
+        // if the input par lies outside of the interval (parl,paru),
+        // set par to the closer endpoint
+        lmPar = FastMath.min(paru, FastMath.max(lmPar, parl));
+        if (lmPar == 0) {
+            lmPar = gNorm / dxNorm;
+        }
+
+        for (int countdown = 10; countdown >= 0; --countdown) {
+
+            // evaluate the function at the current value of lmPar
+            if (lmPar == 0) {
+                lmPar = FastMath.max(2.2251e-308, 0.001 * paru);
+            }
+            double sPar = FastMath.sqrt(lmPar);
+            for (int j = 0; j < solvedCols; ++j) {
+                int pj = permutation[j];
+                work1[pj] = sPar * diag[pj];
+            }
+            determineLMDirection(qy, work1, work2, work3);
+
+            dxNorm = 0;
+            for (int j = 0; j < solvedCols; ++j) {
+                int pj = permutation[j];
+                double s = diag[pj] * lmDir[pj];
+                work3[pj] = s;
+                dxNorm += s * s;
+            }
+            dxNorm = FastMath.sqrt(dxNorm);
+            double previousFP = fp;
+            fp = dxNorm - delta;
+
+            // if the function is small enough, accept the current value
+            // of lmPar, also test for the exceptional cases where parl is zero
+            if ((FastMath.abs(fp) <= 0.1 * delta) ||
+                    ((parl == 0) && (fp <= previousFP) && (previousFP < 0))) {
+                return;
+            }
+
+            // compute the Newton correction
+            for (int j = 0; j < solvedCols; ++j) {
+                int pj = permutation[j];
+                work1[pj] = work3[pj] * diag[pj] / dxNorm;
+            }
+            for (int j = 0; j < solvedCols; ++j) {
+                int pj = permutation[j];
+                work1[pj] /= work2[j];
+                double tmp = work1[pj];
+                for (int i = j + 1; i < solvedCols; ++i) {
+                    work1[permutation[i]] -= wjacobian[i][pj] * tmp;
+                }
+            }
+            sum2 = 0;
+            for (int j = 0; j < solvedCols; ++j) {
+                double s = work1[permutation[j]];
+                sum2 += s * s;
+            }
+            double correction = fp / (delta * sum2);
+
+            // depending on the sign of the function, update parl or paru.
+            if (fp > 0) {
+                parl = FastMath.max(parl, lmPar);
+            } else if (fp < 0) {
+                paru = FastMath.min(paru, lmPar);
+            }
+
+            // compute an improved estimate for lmPar
+            lmPar = FastMath.max(parl, lmPar + correction);
+
+        }
+    }
+
+    /**
+     * Solve a*x = b and d*x = 0 in the least squares sense.
+     * <p>This implementation is a translation in Java of the MINPACK
+     * <a href="http://www.netlib.org/minpack/qrsolv.f">qrsolv</a>
+     * routine.</p>
+     * <p>This method sets the lmDir and lmDiag attributes.</p>
+     * <p>The authors of the original fortran function are:</p>
+     * <ul>
+     *   <li>Argonne National Laboratory. MINPACK project. March 1980</li>
+     *   <li>Burton  S. Garbow</li>
+     *   <li>Kenneth E. Hillstrom</li>
+     *   <li>Jorge   J. More</li>
+     * </ul>
+     * <p>Luc Maisonobe did the Java translation.</p>
+     *
+     * @param qy array containing qTy
+     * @param diag diagonal matrix
+     * @param lmDiag diagonal elements associated with lmDir
+     * @param work work array
+     */
+    private void determineLMDirection(double[] qy, double[] diag,
+            double[] lmDiag, double[] work) {
+
+        // copy R and Qty to preserve input and initialize s
+        //  in particular, save the diagonal elements of R in lmDir
+        for (int j = 0; j < solvedCols; ++j) {
+            int pj = permutation[j];
+            for (int i = j + 1; i < solvedCols; ++i) {
+                wjacobian[i][pj] = wjacobian[j][permutation[i]];
+            }
+            lmDir[j] = diagR[pj];
+            work[j]  = qy[j];
+        }
+
+        // eliminate the diagonal matrix d using a Givens rotation
+        for (int j = 0; j < solvedCols; ++j) {
+
+            // prepare the row of d to be eliminated, locating the
+            // diagonal element using p from the Q.R. factorization
+            int pj = permutation[j];
+            double dpj = diag[pj];
+            if (dpj != 0) {
+                Arrays.fill(lmDiag, j + 1, lmDiag.length, 0);
+            }
+            lmDiag[j] = dpj;
+
+            //  the transformations to eliminate the row of d
+            // modify only a single element of Qty
+            // beyond the first n, which is initially zero.
+            double qtbpj = 0;
+            for (int k = j; k < solvedCols; ++k) {
+                int pk = permutation[k];
+
+                // determine a Givens rotation which eliminates the
+                // appropriate element in the current row of d
+                if (lmDiag[k] != 0) {
+
+                    final double sin;
+                    final double cos;
+                    double rkk = wjacobian[k][pk];
+                    if (FastMath.abs(rkk) < FastMath.abs(lmDiag[k])) {
+                        final double cotan = rkk / lmDiag[k];
+                        sin   = 1.0 / FastMath.sqrt(1.0 + cotan * cotan);
+                        cos   = sin * cotan;
+                    } else {
+                        final double tan = lmDiag[k] / rkk;
+                        cos = 1.0 / FastMath.sqrt(1.0 + tan * tan);
+                        sin = cos * tan;
+                    }
+
+                    // compute the modified diagonal element of R and
+                    // the modified element of (Qty,0)
+                    wjacobian[k][pk] = cos * rkk + sin * lmDiag[k];
+                    final double temp = cos * work[k] + sin * qtbpj;
+                    qtbpj = -sin * work[k] + cos * qtbpj;
+                    work[k] = temp;
+
+                    // accumulate the tranformation in the row of s
+                    for (int i = k + 1; i < solvedCols; ++i) {
+                        double rik = wjacobian[i][pk];
+                        final double temp2 = cos * rik + sin * lmDiag[i];
+                        lmDiag[i] = -sin * rik + cos * lmDiag[i];
+                        wjacobian[i][pk] = temp2;
+                    }
+
+                }
+            }
+
+            // store the diagonal element of s and restore
+            // the corresponding diagonal element of R
+            lmDiag[j] = wjacobian[j][permutation[j]];
+            wjacobian[j][permutation[j]] = lmDir[j];
+
+        }
+
+        // solve the triangular system for z, if the system is
+        // singular, then obtain a least squares solution
+        int nSing = solvedCols;
+        for (int j = 0; j < solvedCols; ++j) {
+            if ((lmDiag[j] == 0) && (nSing == solvedCols)) {
+                nSing = j;
+            }
+            if (nSing < solvedCols) {
+                work[j] = 0;
+            }
+        }
+        if (nSing > 0) {
+            for (int j = nSing - 1; j >= 0; --j) {
+                int pj = permutation[j];
+                double sum = 0;
+                for (int i = j + 1; i < nSing; ++i) {
+                    sum += wjacobian[i][pj] * work[i];
+                }
+                work[j] = (work[j] - sum) / lmDiag[j];
+            }
+        }
+
+        // permute the components of z back to components of lmDir
+        for (int j = 0; j < lmDir.length; ++j) {
+            lmDir[permutation[j]] = work[j];
+        }
+
+    }
+
+    /**
+     * Decompose a matrix A as A.P = Q.R using Householder transforms.
+     * <p>As suggested in the P. Lascaux and R. Theodor book
+     * <i>Analyse num&eacute;rique matricielle appliqu&eacute;e &agrave;
+     * l'art de l'ing&eacute;nieur</i> (Masson, 1986), instead of representing
+     * the Householder transforms with u<sub>k</sub> unit vectors such that:
+     * <pre>
+     * H<sub>k</sub> = I - 2u<sub>k</sub>.u<sub>k</sub><sup>t</sup>
+     * </pre>
+     * we use <sub>k</sub> non-unit vectors such that:
+     * <pre>
+     * H<sub>k</sub> = I - beta<sub>k</sub>v<sub>k</sub>.v<sub>k</sub><sup>t</sup>
+     * </pre>
+     * where v<sub>k</sub> = a<sub>k</sub> - alpha<sub>k</sub> e<sub>k</sub>.
+     * The beta<sub>k</sub> coefficients are provided upon exit as recomputing
+     * them from the v<sub>k</sub> vectors would be costly.</p>
+     * <p>This decomposition handles rank deficient cases since the tranformations
+     * are performed in non-increasing columns norms order thanks to columns
+     * pivoting. The diagonal elements of the R matrix are therefore also in
+     * non-increasing absolute values order.</p>
+     * @exception OptimizationException if the decomposition cannot be performed
+     */
+    private void qrDecomposition() throws OptimizationException {
+
+        // initializations
+        for (int k = 0; k < cols; ++k) {
+            permutation[k] = k;
+            double norm2 = 0;
+            for (int i = 0; i < wjacobian.length; ++i) {
+                double akk = wjacobian[i][k];
+                norm2 += akk * akk;
+            }
+            jacNorm[k] = FastMath.sqrt(norm2);
+        }
+
+        // transform the matrix column after column
+        for (int k = 0; k < cols; ++k) {
+
+            // select the column with the greatest norm on active components
+            int nextColumn = -1;
+            double ak2 = Double.NEGATIVE_INFINITY;
+            for (int i = k; i < cols; ++i) {
+                double norm2 = 0;
+                for (int j = k; j < wjacobian.length; ++j) {
+                    double aki = wjacobian[j][permutation[i]];
+                    norm2 += aki * aki;
+                }
+                if (Double.isInfinite(norm2) || Double.isNaN(norm2)) {
+                    throw new OptimizationException(LocalizedFormats.UNABLE_TO_PERFORM_QR_DECOMPOSITION_ON_JACOBIAN,
+                            rows, cols);
+                }
+                if (norm2 > ak2) {
+                    nextColumn = i;
+                    ak2        = norm2;
+                }
+            }
+            if (ak2 <= qrRankingThreshold) {
+                rank = k;
+                return;
+            }
+            int pk                  = permutation[nextColumn];
+            permutation[nextColumn] = permutation[k];
+            permutation[k]          = pk;
+
+            // choose alpha such that Hk.u = alpha ek
+            double akk   = wjacobian[k][pk];
+            double alpha = (akk > 0) ? -FastMath.sqrt(ak2) : FastMath.sqrt(ak2);
+            double betak = 1.0 / (ak2 - akk * alpha);
+            beta[pk]     = betak;
+
+            // transform the current column
+            diagR[pk]        = alpha;
+            wjacobian[k][pk] -= alpha;
+
+            // transform the remaining columns
+            for (int dk = cols - 1 - k; dk > 0; --dk) {
+                double gamma = 0;
+                for (int j = k; j < wjacobian.length; ++j) {
+                    gamma += wjacobian[j][pk] * wjacobian[j][permutation[k + dk]];
+                }
+                gamma *= betak;
+                for (int j = k; j < wjacobian.length; ++j) {
+                    wjacobian[j][permutation[k + dk]] -= gamma * wjacobian[j][pk];
+                }
+            }
+
+        }
+
+        rank = solvedCols;
+
+    }
+
+    /**
+     * Compute the product Qt.y for some Q.R. decomposition.
+     *
+     * @param y vector to multiply (will be overwritten with the result)
+     */
+    private void qTy(double[] y) {
+        for (int k = 0; k < cols; ++k) {
+            int pk = permutation[k];
+            double gamma = 0;
+            for (int i = k; i < rows; ++i) {
+                gamma += wjacobian[i][pk] * y[i];
+            }
+            gamma *= beta[pk];
+            for (int i = k; i < rows; ++i) {
+                y[i] -= gamma * wjacobian[i][pk];
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java b/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java
new file mode 100644
index 0000000..17f1d8b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.java
@@ -0,0 +1,294 @@
+/*
+ * 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.optimization.general;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.solvers.BrentSolver;
+import org.apache.commons.math.analysis.solvers.UnivariateRealSolver;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealPointValuePair;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Non-linear conjugate gradient optimizer.
+ * <p>
+ * This class supports both the Fletcher-Reeves and the Polak-Ribi&egrave;re
+ * update formulas for the conjugate search directions. It also supports
+ * optional preconditioning.
+ * </p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ *
+ */
+
+public class NonLinearConjugateGradientOptimizer
+    extends AbstractScalarDifferentiableOptimizer {
+
+    /** Update formula for the beta parameter. */
+    private final ConjugateGradientFormula updateFormula;
+
+    /** Preconditioner (may be null). */
+    private Preconditioner preconditioner;
+
+    /** solver to use in the line search (may be null). */
+    private UnivariateRealSolver solver;
+
+    /** Initial step used to bracket the optimum in line search. */
+    private double initialStep;
+
+    /** Simple constructor with default settings.
+     * <p>The convergence check is set to a {@link
+     * org.apache.commons.math.optimization.SimpleVectorialValueChecker}
+     * and the maximal number of iterations is set to
+     * {@link AbstractScalarDifferentiableOptimizer#DEFAULT_MAX_ITERATIONS}.
+     * @param updateFormula formula to use for updating the &beta; parameter,
+     * must be one of {@link ConjugateGradientFormula#FLETCHER_REEVES} or {@link
+     * ConjugateGradientFormula#POLAK_RIBIERE}
+     */
+    public NonLinearConjugateGradientOptimizer(final ConjugateGradientFormula updateFormula) {
+        this.updateFormula = updateFormula;
+        preconditioner     = null;
+        solver             = null;
+        initialStep        = 1.0;
+    }
+
+    /**
+     * Set the preconditioner.
+     * @param preconditioner preconditioner to use for next optimization,
+     * may be null to remove an already registered preconditioner
+     */
+    public void setPreconditioner(final Preconditioner preconditioner) {
+        this.preconditioner = preconditioner;
+    }
+
+    /**
+     * Set the solver to use during line search.
+     * @param lineSearchSolver solver to use during line search, may be null
+     * to remove an already registered solver and fall back to the
+     * default {@link BrentSolver Brent solver}.
+     */
+    public void setLineSearchSolver(final UnivariateRealSolver lineSearchSolver) {
+        this.solver = lineSearchSolver;
+    }
+
+    /**
+     * Set the initial step used to bracket the optimum in line search.
+     * <p>
+     * The initial step is a factor with respect to the search direction,
+     * which itself is roughly related to the gradient of the function
+     * </p>
+     * @param initialStep initial step used to bracket the optimum in line search,
+     * if a non-positive value is used, the initial step is reset to its
+     * default value of 1.0
+     */
+    public void setInitialStep(final double initialStep) {
+        if (initialStep <= 0) {
+            this.initialStep = 1.0;
+        } else {
+            this.initialStep = initialStep;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected RealPointValuePair doOptimize()
+        throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
+        try {
+
+            // initialization
+            if (preconditioner == null) {
+                preconditioner = new IdentityPreconditioner();
+            }
+            if (solver == null) {
+                solver = new BrentSolver();
+            }
+            final int n = point.length;
+            double[] r = computeObjectiveGradient(point);
+            if (goal == GoalType.MINIMIZE) {
+                for (int i = 0; i < n; ++i) {
+                    r[i] = -r[i];
+                }
+            }
+
+            // initial search direction
+            double[] steepestDescent = preconditioner.precondition(point, r);
+            double[] searchDirection = steepestDescent.clone();
+
+            double delta = 0;
+            for (int i = 0; i < n; ++i) {
+                delta += r[i] * searchDirection[i];
+            }
+
+            RealPointValuePair current = null;
+            while (true) {
+
+                final double objective = computeObjectiveValue(point);
+                RealPointValuePair previous = current;
+                current = new RealPointValuePair(point, objective);
+                if (previous != null) {
+                    if (checker.converged(getIterations(), previous, current)) {
+                        // we have found an optimum
+                        return current;
+                    }
+                }
+
+                incrementIterationsCounter();
+
+                double dTd = 0;
+                for (final double di : searchDirection) {
+                    dTd += di * di;
+                }
+
+                // find the optimal step in the search direction
+                final UnivariateRealFunction lsf = new LineSearchFunction(searchDirection);
+                final double step = solver.solve(lsf, 0, findUpperBound(lsf, 0, initialStep));
+
+                // validate new point
+                for (int i = 0; i < point.length; ++i) {
+                    point[i] += step * searchDirection[i];
+                }
+                r = computeObjectiveGradient(point);
+                if (goal == GoalType.MINIMIZE) {
+                    for (int i = 0; i < n; ++i) {
+                        r[i] = -r[i];
+                    }
+                }
+
+                // compute beta
+                final double deltaOld = delta;
+                final double[] newSteepestDescent = preconditioner.precondition(point, r);
+                delta = 0;
+                for (int i = 0; i < n; ++i) {
+                    delta += r[i] * newSteepestDescent[i];
+                }
+
+                final double beta;
+                if (updateFormula == ConjugateGradientFormula.FLETCHER_REEVES) {
+                    beta = delta / deltaOld;
+                } else {
+                    double deltaMid = 0;
+                    for (int i = 0; i < r.length; ++i) {
+                        deltaMid += r[i] * steepestDescent[i];
+                    }
+                    beta = (delta - deltaMid) / deltaOld;
+                }
+                steepestDescent = newSteepestDescent;
+
+                // compute conjugate search direction
+                if ((getIterations() % n == 0) || (beta < 0)) {
+                    // break conjugation: reset search direction
+                    searchDirection = steepestDescent.clone();
+                } else {
+                    // compute new conjugate search direction
+                    for (int i = 0; i < n; ++i) {
+                        searchDirection[i] = steepestDescent[i] + beta * searchDirection[i];
+                    }
+                }
+
+            }
+
+        } catch (ConvergenceException ce) {
+            throw new OptimizationException(ce);
+        }
+    }
+
+    /**
+     * Find the upper bound b ensuring bracketing of a root between a and b
+     * @param f function whose root must be bracketed
+     * @param a lower bound of the interval
+     * @param h initial step to try
+     * @return b such that f(a) and f(b) have opposite signs
+     * @exception FunctionEvaluationException if the function cannot be computed
+     * @exception OptimizationException if no bracket can be found
+     */
+    private double findUpperBound(final UnivariateRealFunction f,
+                                  final double a, final double h)
+        throws FunctionEvaluationException, OptimizationException {
+        final double yA = f.value(a);
+        double yB = yA;
+        for (double step = h; step < Double.MAX_VALUE; step *= FastMath.max(2, yA / yB)) {
+            final double b = a + step;
+            yB = f.value(b);
+            if (yA * yB <= 0) {
+                return b;
+            }
+        }
+        throw new OptimizationException(LocalizedFormats.UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH);
+    }
+
+    /** Default identity preconditioner. */
+    private static class IdentityPreconditioner implements Preconditioner {
+
+        /** {@inheritDoc} */
+        public double[] precondition(double[] variables, double[] r) {
+            return r.clone();
+        }
+
+    }
+
+    /** Internal class for line search.
+     * <p>
+     * The function represented by this class is the dot product of
+     * the objective function gradient and the search direction. Its
+     * value is zero when the gradient is orthogonal to the search
+     * direction, i.e. when the objective function value is a local
+     * extremum along the search direction.
+     * </p>
+     */
+    private class LineSearchFunction implements UnivariateRealFunction {
+        /** Search direction. */
+        private final double[] searchDirection;
+
+        /** Simple constructor.
+         * @param searchDirection search direction
+         */
+        public LineSearchFunction(final double[] searchDirection) {
+            this.searchDirection = searchDirection;
+        }
+
+        /** {@inheritDoc} */
+        public double value(double x) throws FunctionEvaluationException {
+
+            // current point in the search direction
+            final double[] shiftedPoint = point.clone();
+            for (int i = 0; i < shiftedPoint.length; ++i) {
+                shiftedPoint[i] += x * searchDirection[i];
+            }
+
+            // gradient of the objective function
+            final double[] gradient;
+            gradient = computeObjectiveGradient(shiftedPoint);
+
+            // dot product with the search direction
+            double dotProduct = 0;
+            for (int i = 0; i < gradient.length; ++i) {
+                dotProduct += gradient[i] * searchDirection[i];
+            }
+
+            return dotProduct;
+
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/Preconditioner.java b/src/main/java/org/apache/commons/math/optimization/general/Preconditioner.java
new file mode 100644
index 0000000..7bdde75
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/Preconditioner.java
@@ -0,0 +1,52 @@
+/*
+ * 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.optimization.general;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+/**
+ * This interface represents a preconditioner for differentiable scalar
+ * objective function optimizers.
+ * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
+ * @since 2.0
+ */
+public interface Preconditioner {
+
+    /**
+     * Precondition a search direction.
+     * <p>
+     * The returned preconditioned search direction must be computed fast or
+     * the algorithm performances will drop drastically. A classical approach
+     * is to compute only the diagonal elements of the hessian and to divide
+     * the raw search direction by these elements if they are all positive.
+     * If at least one of them is negative, it is safer to return a clone of
+     * the raw search direction as if the hessian was the identity matrix. The
+     * rationale for this simplified choice is that a negative diagonal element
+     * means the current point is far from the optimum and preconditioning will
+     * not be efficient anyway in this case.
+     * </p>
+     * @param point current point at which the search direction was computed
+     * @param r raw search direction (i.e. opposite of the gradient)
+     * @return approximation of H<sup>-1</sup>r where H is the objective function hessian
+     * @exception FunctionEvaluationException if no cost can be computed for the parameters
+     * @exception IllegalArgumentException if point dimension is wrong
+     */
+    double[] precondition(double[] point, double[] r)
+        throws FunctionEvaluationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/general/package.html b/src/main/java/org/apache/commons/math/optimization/general/package.html
new file mode 100644
index 0000000..51ccf95
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/general/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 799857 $ -->
+<body>
+This package provides optimization algorithms that require derivatives.
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/AbstractLinearOptimizer.java b/src/main/java/org/apache/commons/math/optimization/linear/AbstractLinearOptimizer.java
new file mode 100644
index 0000000..b8b2390
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/AbstractLinearOptimizer.java
@@ -0,0 +1,130 @@
+/*
+ * 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.optimization.linear;
+
+import java.util.Collection;
+
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealPointValuePair;
+
+/**
+ * Base class for implementing linear optimizers.
+ * <p>This base class handles the boilerplate methods associated to thresholds
+ * settings and iterations counters.</p>
+ * @version $Revision: 925812 $ $Date: 2010-03-21 16:49:31 +0100 (dim. 21 mars 2010) $
+ * @since 2.0
+ *
+ */
+public abstract class AbstractLinearOptimizer implements LinearOptimizer {
+
+    /** Default maximal number of iterations allowed. */
+    public static final int DEFAULT_MAX_ITERATIONS = 100;
+
+    /**
+     * Linear objective function.
+     * @since 2.1
+     */
+    protected LinearObjectiveFunction function;
+
+    /**
+     * Linear constraints.
+     * @since 2.1
+     */
+    protected Collection<LinearConstraint> linearConstraints;
+
+    /**
+     * Type of optimization goal: either {@link GoalType#MAXIMIZE} or {@link GoalType#MINIMIZE}.
+     * @since 2.1
+     */
+    protected GoalType goal;
+
+    /**
+     * Whether to restrict the variables to non-negative values.
+     * @since 2.1
+     */
+    protected boolean nonNegative;
+
+    /** Maximal number of iterations allowed. */
+    private int maxIterations;
+
+    /** Number of iterations already performed. */
+    private int iterations;
+
+    /** Simple constructor with default settings.
+     * <p>The maximal number of evaluation is set to its default value.</p>
+     */
+    protected AbstractLinearOptimizer() {
+        setMaxIterations(DEFAULT_MAX_ITERATIONS);
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxIterations(int maxIterations) {
+        this.maxIterations = maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxIterations() {
+        return maxIterations;
+    }
+
+    /** {@inheritDoc} */
+    public int getIterations() {
+        return iterations;
+    }
+
+    /** Increment the iterations counter by 1.
+     * @exception OptimizationException if the maximal number
+     * of iterations is exceeded
+     */
+    protected void incrementIterationsCounter()
+        throws OptimizationException {
+        if (++iterations > maxIterations) {
+            throw new OptimizationException(new MaxIterationsExceededException(maxIterations));
+        }
+    }
+
+    /** {@inheritDoc} */
+    public RealPointValuePair optimize(final LinearObjectiveFunction f,
+                                       final Collection<LinearConstraint> constraints,
+                                       final GoalType goalType, final boolean restrictToNonNegative)
+         throws OptimizationException {
+
+        // store linear problem characteristics
+        this.function          = f;
+        this.linearConstraints = constraints;
+        this.goal              = goalType;
+        this.nonNegative       = restrictToNonNegative;
+
+        iterations  = 0;
+
+        // solve the problem
+        return doOptimize();
+
+    }
+
+    /** Perform the bulk of optimization algorithm.
+     * @return the point/value pair giving the optimal value for objective function
+     * @exception OptimizationException if no solution fulfilling the constraints
+     * can be found in the allowed number of iterations
+     */
+    protected abstract RealPointValuePair doOptimize()
+        throws OptimizationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/LinearConstraint.java b/src/main/java/org/apache/commons/math/optimization/linear/LinearConstraint.java
new file mode 100644
index 0000000..85d6251
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/LinearConstraint.java
@@ -0,0 +1,233 @@
+/*
+ * 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.optimization.linear;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.linear.ArrayRealVector;
+
+
+/**
+ * A linear constraint for a linear optimization problem.
+ * <p>
+ * A linear constraint has one of the forms:
+ * <ul>
+ *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
+ *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
+ *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
+ *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
+ *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+ *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
+ *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+ *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
+ *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+ * </ul>
+ * The c<sub>i</sub>, l<sub>i</sub> or r<sub>i</sub> are the coefficients of the constraints, the x<sub>i</sub>
+ * are the coordinates of the current point and v is the value of the constraint.
+ * </p>
+ * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $
+ * @since 2.0
+ */
+public class LinearConstraint implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -764632794033034092L;
+
+    /** Coefficients of the constraint (left hand side). */
+    private final transient RealVector coefficients;
+
+    /** Relationship between left and right hand sides (=, &lt;=, >=). */
+    private final Relationship relationship;
+
+    /** Value of the constraint (right hand side). */
+    private final double value;
+
+    /**
+     * Build a constraint involving a single linear equation.
+     * <p>
+     * A linear constraint with a single linear equation has one of the forms:
+     * <ul>
+     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
+     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
+     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
+     * </ul>
+     * </p>
+     * @param coefficients The coefficients of the constraint (left hand side)
+     * @param relationship The type of (in)equality used in the constraint
+     * @param value The value of the constraint (right hand side)
+     */
+    public LinearConstraint(final double[] coefficients, final Relationship relationship,
+                            final double value) {
+        this(new ArrayRealVector(coefficients), relationship, value);
+    }
+
+    /**
+     * Build a constraint involving a single linear equation.
+     * <p>
+     * A linear constraint with a single linear equation has one of the forms:
+     * <ul>
+     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
+     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
+     *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
+     * </ul>
+     * </p>
+     * @param coefficients The coefficients of the constraint (left hand side)
+     * @param relationship The type of (in)equality used in the constraint
+     * @param value The value of the constraint (right hand side)
+     */
+    public LinearConstraint(final RealVector coefficients, final Relationship relationship,
+                            final double value) {
+        this.coefficients = coefficients;
+        this.relationship = relationship;
+        this.value        = value;
+    }
+
+    /**
+     * Build a constraint involving two linear equations.
+     * <p>
+     * A linear constraint with two linear equation has one of the forms:
+     * <ul>
+     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
+     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
+     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
+     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+     * </ul>
+     * </p>
+     * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
+     * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
+     * @param relationship The type of (in)equality used in the constraint
+     * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
+     * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
+     */
+    public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant,
+                            final Relationship relationship,
+                            final double[] rhsCoefficients, final double rhsConstant) {
+        double[] sub = new double[lhsCoefficients.length];
+        for (int i = 0; i < sub.length; ++i) {
+            sub[i] = lhsCoefficients[i] - rhsCoefficients[i];
+        }
+        this.coefficients = new ArrayRealVector(sub, false);
+        this.relationship = relationship;
+        this.value        = rhsConstant - lhsConstant;
+    }
+
+    /**
+     * Build a constraint involving two linear equations.
+     * <p>
+     * A linear constraint with two linear equation has one of the forms:
+     * <ul>
+     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
+     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
+     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+     *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
+     *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+     * </ul>
+     * </p>
+     * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint
+     * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint
+     * @param relationship The type of (in)equality used in the constraint
+     * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint
+     * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint
+     */
+    public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant,
+                            final Relationship relationship,
+                            final RealVector rhsCoefficients, final double rhsConstant) {
+        this.coefficients = lhsCoefficients.subtract(rhsCoefficients);
+        this.relationship = relationship;
+        this.value        = rhsConstant - lhsConstant;
+    }
+
+    /**
+     * Get the coefficients of the constraint (left hand side).
+     * @return coefficients of the constraint (left hand side)
+     */
+    public RealVector getCoefficients() {
+        return coefficients;
+    }
+
+    /**
+     * Get the relationship between left and right hand sides.
+     * @return relationship between left and right hand sides
+     */
+    public Relationship getRelationship() {
+        return relationship;
+    }
+
+    /**
+     * Get the value of the constraint (right hand side).
+     * @return value of the constraint (right hand side)
+     */
+    public double getValue() {
+        return value;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+
+      if (this == other) {
+        return true;
+      }
+
+      if (other instanceof LinearConstraint) {
+          LinearConstraint rhs = (LinearConstraint) other;
+          return (relationship == rhs.relationship) &&
+                 (value        == rhs.value) &&
+                 coefficients.equals(rhs.coefficients);
+      }
+      return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return relationship.hashCode() ^
+               Double.valueOf(value).hashCode() ^
+               coefficients.hashCode();
+    }
+
+    /** Serialize the instance.
+     * @param oos stream where object should be written
+     * @throws IOException if object cannot be written to stream
+     */
+    private void writeObject(ObjectOutputStream oos)
+        throws IOException {
+        oos.defaultWriteObject();
+        MatrixUtils.serializeRealVector(coefficients, oos);
+    }
+
+    /** Deserialize the instance.
+     * @param ois stream from which the object should be read
+     * @throws ClassNotFoundException if a class in the stream cannot be found
+     * @throws IOException if object cannot be read from the stream
+     */
+    private void readObject(ObjectInputStream ois)
+      throws ClassNotFoundException, IOException {
+        ois.defaultReadObject();
+        MatrixUtils.deserializeRealVector(this, "coefficients", ois);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.java b/src/main/java/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.java
new file mode 100644
index 0000000..b3c3eb8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.java
@@ -0,0 +1,147 @@
+/*
+ * 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.optimization.linear;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.linear.ArrayRealVector;
+
+/**
+ * An objective function for a linear optimization problem.
+ * <p>
+ * A linear objective function has one the form:
+ * <pre>
+ * c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> + d
+ * </pre>
+ * The c<sub>i</sub> and d are the coefficients of the equation,
+ * the x<sub>i</sub> are the coordinates of the current point.
+ * </p>
+ * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $
+ * @since 2.0
+ */
+public class LinearObjectiveFunction implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -4531815507568396090L;
+
+    /** Coefficients of the constraint (c<sub>i</sub>). */
+    private final transient RealVector coefficients;
+
+    /** Constant term of the linear equation. */
+    private final double constantTerm;
+
+    /**
+     * @param coefficients The coefficients for the linear equation being optimized
+     * @param constantTerm The constant term of the linear equation
+     */
+    public LinearObjectiveFunction(double[] coefficients, double constantTerm) {
+        this(new ArrayRealVector(coefficients), constantTerm);
+    }
+
+    /**
+     * @param coefficients The coefficients for the linear equation being optimized
+     * @param constantTerm The constant term of the linear equation
+     */
+    public LinearObjectiveFunction(RealVector coefficients, double constantTerm) {
+        this.coefficients = coefficients;
+        this.constantTerm = constantTerm;
+    }
+
+    /**
+     * Get the coefficients of the linear equation being optimized.
+     * @return coefficients of the linear equation being optimized
+     */
+    public RealVector getCoefficients() {
+        return coefficients;
+    }
+
+    /**
+     * Get the constant of the linear equation being optimized.
+     * @return constant of the linear equation being optimized
+     */
+    public double getConstantTerm() {
+        return constantTerm;
+    }
+
+    /**
+     * Compute the value of the linear equation at the current point
+     * @param point point at which linear equation must be evaluated
+     * @return value of the linear equation at the current point
+     */
+    public double getValue(final double[] point) {
+        return coefficients.dotProduct(point) + constantTerm;
+    }
+
+    /**
+     * Compute the value of the linear equation at the current point
+     * @param point point at which linear equation must be evaluated
+     * @return value of the linear equation at the current point
+     */
+    public double getValue(final RealVector point) {
+        return coefficients.dotProduct(point) + constantTerm;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+
+      if (this == other) {
+        return true;
+      }
+
+      if (other instanceof LinearObjectiveFunction) {
+          LinearObjectiveFunction rhs = (LinearObjectiveFunction) other;
+          return (constantTerm == rhs.constantTerm) && coefficients.equals(rhs.coefficients);
+      }
+
+      return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return Double.valueOf(constantTerm).hashCode() ^ coefficients.hashCode();
+    }
+
+    /** Serialize the instance.
+     * @param oos stream where object should be written
+     * @throws IOException if object cannot be written to stream
+     */
+    private void writeObject(ObjectOutputStream oos)
+        throws IOException {
+        oos.defaultWriteObject();
+        MatrixUtils.serializeRealVector(coefficients, oos);
+    }
+
+    /** Deserialize the instance.
+     * @param ois stream from which the object should be read
+     * @throws ClassNotFoundException if a class in the stream cannot be found
+     * @throws IOException if object cannot be read from the stream
+     */
+    private void readObject(ObjectInputStream ois)
+      throws ClassNotFoundException, IOException {
+        ois.defaultReadObject();
+        MatrixUtils.deserializeRealVector(this, "coefficients", ois);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/LinearOptimizer.java b/src/main/java/org/apache/commons/math/optimization/linear/LinearOptimizer.java
new file mode 100644
index 0000000..41fccd9
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/LinearOptimizer.java
@@ -0,0 +1,89 @@
+/*
+ * 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.optimization.linear;
+
+import java.util.Collection;
+
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealPointValuePair;
+
+/**
+ * This interface represents an optimization algorithm for linear problems.
+ * <p>Optimization algorithms find the input point set that either {@link GoalType
+ * maximize or minimize} an objective function. In the linear case the form of
+ * the function is restricted to
+ * <pre>
+ * c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v
+ * </pre>
+ * and there may be linear constraints too, of one of the forms:
+ * <ul>
+ *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li>
+ *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> &lt;= v</li>
+ *   <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li>
+ *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> =
+ *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+ *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> &lt;=
+ *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+ *   <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >=
+ *       r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li>
+ * </ul>
+ * where the c<sub>i</sub>, l<sub>i</sub> or r<sub>i</sub> are the coefficients of
+ * the constraints, the x<sub>i</sub> are the coordinates of the current point and
+ * v is the value of the constraint.
+ * </p>
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface LinearOptimizer {
+
+    /** Set the maximal number of iterations of the algorithm.
+     * @param maxIterations maximal number of function calls
+     */
+    void setMaxIterations(int maxIterations);
+
+    /** Get the maximal number of iterations of the algorithm.
+     * @return maximal number of iterations
+     */
+    int getMaxIterations();
+
+    /** Get the number of iterations realized by the algorithm.
+     * <p>
+     * The number of evaluations corresponds to the last call to the
+     * {@link #optimize(LinearObjectiveFunction, Collection, GoalType, boolean) optimize}
+     * method. It is 0 if the method has not been called yet.
+     * </p>
+     * @return number of iterations
+     */
+    int getIterations();
+
+    /** Optimizes an objective function.
+     * @param f linear objective function
+     * @param constraints linear constraints
+     * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE}
+     * or {@link GoalType#MINIMIZE}
+     * @param restrictToNonNegative whether to restrict the variables to non-negative values
+     * @return point/value pair giving the optimal value for objective function
+     * @exception OptimizationException if no solution fulfilling the constraints
+     * can be found in the allowed number of iterations
+     */
+   RealPointValuePair optimize(LinearObjectiveFunction f, Collection<LinearConstraint> constraints,
+                               GoalType goalType, boolean restrictToNonNegative)
+        throws OptimizationException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/NoFeasibleSolutionException.java b/src/main/java/org/apache/commons/math/optimization/linear/NoFeasibleSolutionException.java
new file mode 100644
index 0000000..b145dd4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/NoFeasibleSolutionException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.optimization.linear;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.OptimizationException;
+
+/**
+ * This class represents exceptions thrown by optimizers when no solution
+ * fulfills the constraints.
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class NoFeasibleSolutionException extends OptimizationException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -3044253632189082760L;
+
+    /**
+     * Simple constructor using a default message.
+     */
+    public NoFeasibleSolutionException() {
+        super(LocalizedFormats.NO_FEASIBLE_SOLUTION);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/Relationship.java b/src/main/java/org/apache/commons/math/optimization/linear/Relationship.java
new file mode 100644
index 0000000..500dcc1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/Relationship.java
@@ -0,0 +1,67 @@
+/*
+ * 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.optimization.linear;
+
+/**
+ * Types of relationships between two cells in a Solver {@link LinearConstraint}.
+ * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $
+ * @since 2.0
+ */
+public enum Relationship {
+
+    /** Equality relationship. */
+    EQ("="),
+
+    /** Lesser than or equal relationship. */
+    LEQ("<="),
+
+    /** Greater than or equal relationship. */
+    GEQ(">=");
+
+    /** Display string for the relationship. */
+    private final String stringValue;
+
+    /** Simple constructor.
+     * @param stringValue display string for the relationship
+     */
+    private Relationship(String stringValue) {
+        this.stringValue = stringValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return stringValue;
+    }
+
+    /**
+     * Get the relationship obtained when multiplying all coefficients by -1.
+     * @return relationship obtained when multiplying all coefficients by -1
+     */
+    public Relationship oppositeRelationship() {
+        switch (this) {
+        case LEQ :
+            return GEQ;
+        case GEQ :
+            return LEQ;
+        default :
+            return EQ;
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/SimplexSolver.java b/src/main/java/org/apache/commons/math/optimization/linear/SimplexSolver.java
new file mode 100644
index 0000000..830f65c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/SimplexSolver.java
@@ -0,0 +1,185 @@
+/*
+ * 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.optimization.linear;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.optimization.OptimizationException;
+import org.apache.commons.math.optimization.RealPointValuePair;
+import org.apache.commons.math.util.MathUtils;
+
+
+/**
+ * Solves a linear problem using the Two-Phase Simplex Method.
+ * @version $Revision: 812831 $ $Date: 2009-09-09 10:48:03 +0200 (mer. 09 sept. 2009) $
+ * @since 2.0
+ */
+public class SimplexSolver extends AbstractLinearOptimizer {
+
+    /** Default amount of error to accept in floating point comparisons. */
+    private static final double DEFAULT_EPSILON = 1.0e-6;
+
+    /** Amount of error to accept in floating point comparisons. */
+    protected final double epsilon;
+
+    /**
+     * Build a simplex solver with default settings.
+     */
+    public SimplexSolver() {
+        this(DEFAULT_EPSILON);
+    }
+
+    /**
+     * Build a simplex solver with a specified accepted amount of error
+     * @param epsilon the amount of error to accept in floating point comparisons
+     */
+    public SimplexSolver(final double epsilon) {
+        this.epsilon = epsilon;
+    }
+
+    /**
+     * Returns the column with the most negative coefficient in the objective function row.
+     * @param tableau simple tableau for the problem
+     * @return column with the most negative coefficient
+     */
+    private Integer getPivotColumn(SimplexTableau tableau) {
+        double minValue = 0;
+        Integer minPos = null;
+        for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getWidth() - 1; i++) {
+            if (MathUtils.compareTo(tableau.getEntry(0, i), minValue, epsilon) < 0) {
+                minValue = tableau.getEntry(0, i);
+                minPos = i;
+            }
+        }
+        return minPos;
+    }
+
+    /**
+     * Returns the row with the minimum ratio as given by the minimum ratio test (MRT).
+     * @param tableau simple tableau for the problem
+     * @param col the column to test the ratio of.  See {@link #getPivotColumn(SimplexTableau)}
+     * @return row with the minimum ratio
+     */
+    private Integer getPivotRow(SimplexTableau tableau, final int col) {
+        // create a list of all the rows that tie for the lowest score in the minimum ratio test
+        List<Integer> minRatioPositions = new ArrayList<Integer>();
+        double minRatio = Double.MAX_VALUE;
+        for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getHeight(); i++) {
+            final double rhs = tableau.getEntry(i, tableau.getWidth() - 1);
+            final double entry = tableau.getEntry(i, col);
+            if (MathUtils.compareTo(entry, 0, epsilon) > 0) {
+                final double ratio = rhs / entry;
+                if (MathUtils.equals(ratio, minRatio, epsilon)) {
+                    minRatioPositions.add(i);
+                } else if (ratio < minRatio) {
+                    minRatio = ratio;
+                    minRatioPositions = new ArrayList<Integer>();
+                    minRatioPositions.add(i);
+                }
+            }
+        }
+
+        if (minRatioPositions.size() == 0) {
+          return null;
+        } else if (minRatioPositions.size() > 1) {
+          // there's a degeneracy as indicated by a tie in the minimum ratio test
+          // check if there's an artificial variable that can be forced out of the basis
+          for (Integer row : minRatioPositions) {
+            for (int i = 0; i < tableau.getNumArtificialVariables(); i++) {
+              int column = i + tableau.getArtificialVariableOffset();
+              if (MathUtils.equals(tableau.getEntry(row, column), 1, epsilon) &&
+                  row.equals(tableau.getBasicRow(column))) {
+                return row;
+              }
+            }
+          }
+        }
+        return minRatioPositions.get(0);
+    }
+
+    /**
+     * Runs one iteration of the Simplex method on the given model.
+     * @param tableau simple tableau for the problem
+     * @throws OptimizationException if the maximal iteration count has been
+     * exceeded or if the model is found not to have a bounded solution
+     */
+    protected void doIteration(final SimplexTableau tableau)
+        throws OptimizationException {
+
+        incrementIterationsCounter();
+
+        Integer pivotCol = getPivotColumn(tableau);
+        Integer pivotRow = getPivotRow(tableau, pivotCol);
+        if (pivotRow == null) {
+            throw new UnboundedSolutionException();
+        }
+
+        // set the pivot element to 1
+        double pivotVal = tableau.getEntry(pivotRow, pivotCol);
+        tableau.divideRow(pivotRow, pivotVal);
+
+        // set the rest of the pivot column to 0
+        for (int i = 0; i < tableau.getHeight(); i++) {
+            if (i != pivotRow) {
+                double multiplier = tableau.getEntry(i, pivotCol);
+                tableau.subtractRow(i, pivotRow, multiplier);
+            }
+        }
+    }
+
+    /**
+     * Solves Phase 1 of the Simplex method.
+     * @param tableau simple tableau for the problem
+     * @exception OptimizationException if the maximal number of iterations is
+     * exceeded, or if the problem is found not to have a bounded solution, or
+     * if there is no feasible solution
+     */
+    protected void solvePhase1(final SimplexTableau tableau) throws OptimizationException {
+
+        // make sure we're in Phase 1
+        if (tableau.getNumArtificialVariables() == 0) {
+            return;
+        }
+
+        while (!tableau.isOptimal()) {
+            doIteration(tableau);
+        }
+
+        // if W is not zero then we have no feasible solution
+        if (!MathUtils.equals(tableau.getEntry(0, tableau.getRhsOffset()), 0, epsilon)) {
+            throw new NoFeasibleSolutionException();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public RealPointValuePair doOptimize() throws OptimizationException {
+        final SimplexTableau tableau =
+            new SimplexTableau(function, linearConstraints, goal, nonNegative, epsilon);
+
+        solvePhase1(tableau);
+        tableau.dropPhase1Objective();
+
+        while (!tableau.isOptimal()) {
+            doIteration(tableau);
+        }
+        return tableau.getSolution();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/SimplexTableau.java b/src/main/java/org/apache/commons/math/optimization/linear/SimplexTableau.java
new file mode 100644
index 0000000..c25619a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/SimplexTableau.java
@@ -0,0 +1,589 @@
+/*
+ * 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.optimization.linear;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.RealPointValuePair;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * A tableau for use in the Simplex method.
+ *
+ * <p>
+ * Example:
+ * <pre>
+ *   W |  Z |  x1 |  x2 |  x- | s1 |  s2 |  a1 |  RHS
+ * ---------------------------------------------------
+ *  -1    0    0     0     0     0     0     1     0   &lt;= phase 1 objective
+ *   0    1   -15   -10    0     0     0     0     0   &lt;= phase 2 objective
+ *   0    0    1     0     0     1     0     0     2   &lt;= constraint 1
+ *   0    0    0     1     0     0     1     0     3   &lt;= constraint 2
+ *   0    0    1     1     0     0     0     1     4   &lt;= constraint 3
+ * </pre>
+ * W: Phase 1 objective function</br>
+ * Z: Phase 2 objective function</br>
+ * x1 &amp; x2: Decision variables</br>
+ * x-: Extra decision variable to allow for negative values</br>
+ * s1 &amp; s2: Slack/Surplus variables</br>
+ * a1: Artificial variable</br>
+ * RHS: Right hand side</br>
+ * </p>
+ * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $
+ * @since 2.0
+ */
+class SimplexTableau implements Serializable {
+
+    /** Column label for negative vars. */
+    private static final String NEGATIVE_VAR_COLUMN_LABEL = "x-";
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -1369660067587938365L;
+
+    /** Linear objective function. */
+    private final LinearObjectiveFunction f;
+
+    /** Linear constraints. */
+    private final List<LinearConstraint> constraints;
+
+    /** Whether to restrict the variables to non-negative values. */
+    private final boolean restrictToNonNegative;
+
+    /** The variables each column represents */
+    private final List<String> columnLabels = new ArrayList<String>();
+
+    /** Simple tableau. */
+    private transient RealMatrix tableau;
+
+    /** Number of decision variables. */
+    private final int numDecisionVariables;
+
+    /** Number of slack variables. */
+    private final int numSlackVariables;
+
+    /** Number of artificial variables. */
+    private int numArtificialVariables;
+
+    /** Amount of error to accept in floating point comparisons. */
+    private final double epsilon;
+
+    /**
+     * Build a tableau for a linear problem.
+     * @param f linear objective function
+     * @param constraints linear constraints
+     * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE}
+     * or {@link GoalType#MINIMIZE}
+     * @param restrictToNonNegative whether to restrict the variables to non-negative values
+     * @param epsilon amount of error to accept in floating point comparisons
+     */
+    SimplexTableau(final LinearObjectiveFunction f,
+                   final Collection<LinearConstraint> constraints,
+                   final GoalType goalType, final boolean restrictToNonNegative,
+                   final double epsilon) {
+        this.f                      = f;
+        this.constraints            = normalizeConstraints(constraints);
+        this.restrictToNonNegative  = restrictToNonNegative;
+        this.epsilon                = epsilon;
+        this.numDecisionVariables   = f.getCoefficients().getDimension() +
+                                      (restrictToNonNegative ? 0 : 1);
+        this.numSlackVariables      = getConstraintTypeCounts(Relationship.LEQ) +
+                                      getConstraintTypeCounts(Relationship.GEQ);
+        this.numArtificialVariables = getConstraintTypeCounts(Relationship.EQ) +
+                                      getConstraintTypeCounts(Relationship.GEQ);
+        this.tableau = createTableau(goalType == GoalType.MAXIMIZE);
+        initializeColumnLabels();
+    }
+
+    /**
+     * Initialize the labels for the columns.
+     */
+    protected void initializeColumnLabels() {
+      if (getNumObjectiveFunctions() == 2) {
+        columnLabels.add("W");
+      }
+      columnLabels.add("Z");
+      for (int i = 0; i < getOriginalNumDecisionVariables(); i++) {
+        columnLabels.add("x" + i);
+      }
+      if (!restrictToNonNegative) {
+        columnLabels.add(NEGATIVE_VAR_COLUMN_LABEL);
+      }
+      for (int i = 0; i < getNumSlackVariables(); i++) {
+        columnLabels.add("s" + i);
+      }
+      for (int i = 0; i < getNumArtificialVariables(); i++) {
+        columnLabels.add("a" + i);
+      }
+      columnLabels.add("RHS");
+    }
+
+    /**
+     * Create the tableau by itself.
+     * @param maximize if true, goal is to maximize the objective function
+     * @return created tableau
+     */
+    protected RealMatrix createTableau(final boolean maximize) {
+
+        // create a matrix of the correct size
+        int width = numDecisionVariables + numSlackVariables +
+        numArtificialVariables + getNumObjectiveFunctions() + 1; // + 1 is for RHS
+        int height = constraints.size() + getNumObjectiveFunctions();
+        Array2DRowRealMatrix matrix = new Array2DRowRealMatrix(height, width);
+
+        // initialize the objective function rows
+        if (getNumObjectiveFunctions() == 2) {
+            matrix.setEntry(0, 0, -1);
+        }
+        int zIndex = (getNumObjectiveFunctions() == 1) ? 0 : 1;
+        matrix.setEntry(zIndex, zIndex, maximize ? 1 : -1);
+        RealVector objectiveCoefficients =
+            maximize ? f.getCoefficients().mapMultiply(-1) : f.getCoefficients();
+        copyArray(objectiveCoefficients.getData(), matrix.getDataRef()[zIndex]);
+        matrix.setEntry(zIndex, width - 1,
+            maximize ? f.getConstantTerm() : -1 * f.getConstantTerm());
+
+        if (!restrictToNonNegative) {
+            matrix.setEntry(zIndex, getSlackVariableOffset() - 1,
+                getInvertedCoeffiecientSum(objectiveCoefficients));
+        }
+
+        // initialize the constraint rows
+        int slackVar = 0;
+        int artificialVar = 0;
+        for (int i = 0; i < constraints.size(); i++) {
+            LinearConstraint constraint = constraints.get(i);
+            int row = getNumObjectiveFunctions() + i;
+
+            // decision variable coefficients
+            copyArray(constraint.getCoefficients().getData(), matrix.getDataRef()[row]);
+
+            // x-
+            if (!restrictToNonNegative) {
+                matrix.setEntry(row, getSlackVariableOffset() - 1,
+                    getInvertedCoeffiecientSum(constraint.getCoefficients()));
+            }
+
+            // RHS
+            matrix.setEntry(row, width - 1, constraint.getValue());
+
+            // slack variables
+            if (constraint.getRelationship() == Relationship.LEQ) {
+                matrix.setEntry(row, getSlackVariableOffset() + slackVar++, 1);  // slack
+            } else if (constraint.getRelationship() == Relationship.GEQ) {
+                matrix.setEntry(row, getSlackVariableOffset() + slackVar++, -1); // excess
+            }
+
+            // artificial variables
+            if ((constraint.getRelationship() == Relationship.EQ) ||
+                    (constraint.getRelationship() == Relationship.GEQ)) {
+                matrix.setEntry(0, getArtificialVariableOffset() + artificialVar, 1);
+                matrix.setEntry(row, getArtificialVariableOffset() + artificialVar++, 1);
+                matrix.setRowVector(0, matrix.getRowVector(0).subtract(matrix.getRowVector(row)));
+            }
+        }
+
+        return matrix;
+    }
+
+    /**
+     * Get new versions of the constraints which have positive right hand sides.
+     * @param originalConstraints original (not normalized) constraints
+     * @return new versions of the constraints
+     */
+    public List<LinearConstraint> normalizeConstraints(Collection<LinearConstraint> originalConstraints) {
+        List<LinearConstraint> normalized = new ArrayList<LinearConstraint>();
+        for (LinearConstraint constraint : originalConstraints) {
+            normalized.add(normalize(constraint));
+        }
+        return normalized;
+    }
+
+    /**
+     * Get a new equation equivalent to this one with a positive right hand side.
+     * @param constraint reference constraint
+     * @return new equation
+     */
+    private LinearConstraint normalize(final LinearConstraint constraint) {
+        if (constraint.getValue() < 0) {
+            return new LinearConstraint(constraint.getCoefficients().mapMultiply(-1),
+                                        constraint.getRelationship().oppositeRelationship(),
+                                        -1 * constraint.getValue());
+        }
+        return new LinearConstraint(constraint.getCoefficients(),
+                                    constraint.getRelationship(), constraint.getValue());
+    }
+
+    /**
+     * Get the number of objective functions in this tableau.
+     * @return 2 for Phase 1.  1 for Phase 2.
+     */
+    protected final int getNumObjectiveFunctions() {
+        return this.numArtificialVariables > 0 ? 2 : 1;
+    }
+
+    /**
+     * Get a count of constraints corresponding to a specified relationship.
+     * @param relationship relationship to count
+     * @return number of constraint with the specified relationship
+     */
+    private int getConstraintTypeCounts(final Relationship relationship) {
+        int count = 0;
+        for (final LinearConstraint constraint : constraints) {
+            if (constraint.getRelationship() == relationship) {
+                ++count;
+            }
+        }
+        return count;
+    }
+
+    /**
+     * Get the -1 times the sum of all coefficients in the given array.
+     * @param coefficients coefficients to sum
+     * @return the -1 times the sum of all coefficients in the given array.
+     */
+    protected static double getInvertedCoeffiecientSum(final RealVector coefficients) {
+        double sum = 0;
+        for (double coefficient : coefficients.getData()) {
+            sum -= coefficient;
+        }
+        return sum;
+    }
+
+    /**
+     * Checks whether the given column is basic.
+     * @param col index of the column to check
+     * @return the row that the variable is basic in.  null if the column is not basic
+     */
+    protected Integer getBasicRow(final int col) {
+        Integer row = null;
+        for (int i = 0; i < getHeight(); i++) {
+            if (MathUtils.equals(getEntry(i, col), 1.0, epsilon) && (row == null)) {
+                row = i;
+            } else if (!MathUtils.equals(getEntry(i, col), 0.0, epsilon)) {
+                return null;
+            }
+        }
+        return row;
+    }
+
+    /**
+     * Removes the phase 1 objective function, positive cost non-artificial variables,
+     * and the non-basic artificial variables from this tableau.
+     */
+    protected void dropPhase1Objective() {
+        if (getNumObjectiveFunctions() == 1) {
+            return;
+        }
+
+        List<Integer> columnsToDrop = new ArrayList<Integer>();
+        columnsToDrop.add(0);
+
+        // positive cost non-artificial variables
+        for (int i = getNumObjectiveFunctions(); i < getArtificialVariableOffset(); i++) {
+          if (MathUtils.compareTo(tableau.getEntry(0, i), 0, epsilon) > 0) {
+            columnsToDrop.add(i);
+          }
+        }
+
+        // non-basic artificial variables
+        for (int i = 0; i < getNumArtificialVariables(); i++) {
+          int col = i + getArtificialVariableOffset();
+          if (getBasicRow(col) == null) {
+            columnsToDrop.add(col);
+          }
+        }
+
+        double[][] matrix = new double[getHeight() - 1][getWidth() - columnsToDrop.size()];
+        for (int i = 1; i < getHeight(); i++) {
+          int col = 0;
+          for (int j = 0; j < getWidth(); j++) {
+            if (!columnsToDrop.contains(j)) {
+              matrix[i - 1][col++] = tableau.getEntry(i, j);
+            }
+          }
+        }
+
+        for (int i = columnsToDrop.size() - 1; i >= 0; i--) {
+          columnLabels.remove((int) columnsToDrop.get(i));
+        }
+
+        this.tableau = new Array2DRowRealMatrix(matrix);
+        this.numArtificialVariables = 0;
+    }
+
+    /**
+     * @param src the source array
+     * @param dest the destination array
+     */
+    private void copyArray(final double[] src, final double[] dest) {
+        System.arraycopy(src, 0, dest, getNumObjectiveFunctions(), src.length);
+    }
+
+    /**
+     * Returns whether the problem is at an optimal state.
+     * @return whether the model has been solved
+     */
+    boolean isOptimal() {
+        for (int i = getNumObjectiveFunctions(); i < getWidth() - 1; i++) {
+            if (MathUtils.compareTo(tableau.getEntry(0, i), 0, epsilon) < 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Get the current solution.
+     *
+     * @return current solution
+     */
+    protected RealPointValuePair getSolution() {
+      int negativeVarColumn = columnLabels.indexOf(NEGATIVE_VAR_COLUMN_LABEL);
+      Integer negativeVarBasicRow = negativeVarColumn > 0 ? getBasicRow(negativeVarColumn) : null;
+      double mostNegative = negativeVarBasicRow == null ? 0 : getEntry(negativeVarBasicRow, getRhsOffset());
+
+      Set<Integer> basicRows = new HashSet<Integer>();
+      double[] coefficients = new double[getOriginalNumDecisionVariables()];
+      for (int i = 0; i < coefficients.length; i++) {
+          int colIndex = columnLabels.indexOf("x" + i);
+          if (colIndex < 0) {
+            coefficients[i] = 0;
+            continue;
+          }
+          Integer basicRow = getBasicRow(colIndex);
+          if (basicRows.contains(basicRow)) {
+              // if multiple variables can take a given value
+              // then we choose the first and set the rest equal to 0
+              coefficients[i] = 0;
+          } else {
+              basicRows.add(basicRow);
+              coefficients[i] =
+                  (basicRow == null ? 0 : getEntry(basicRow, getRhsOffset())) -
+                  (restrictToNonNegative ? 0 : mostNegative);
+          }
+      }
+      return new RealPointValuePair(coefficients, f.getValue(coefficients));
+    }
+
+    /**
+     * Subtracts a multiple of one row from another.
+     * <p>
+     * After application of this operation, the following will hold:
+     *   minuendRow = minuendRow - multiple * subtrahendRow
+     * </p>
+     * @param dividendRow index of the row
+     * @param divisor value of the divisor
+     */
+    protected void divideRow(final int dividendRow, final double divisor) {
+        for (int j = 0; j < getWidth(); j++) {
+            tableau.setEntry(dividendRow, j, tableau.getEntry(dividendRow, j) / divisor);
+        }
+    }
+
+    /**
+     * Subtracts a multiple of one row from another.
+     * <p>
+     * After application of this operation, the following will hold:
+     *   minuendRow = minuendRow - multiple * subtrahendRow
+     * </p>
+     * @param minuendRow row index
+     * @param subtrahendRow row index
+     * @param multiple multiplication factor
+     */
+    protected void subtractRow(final int minuendRow, final int subtrahendRow,
+                               final double multiple) {
+        tableau.setRowVector(minuendRow, tableau.getRowVector(minuendRow)
+            .subtract(tableau.getRowVector(subtrahendRow).mapMultiply(multiple)));
+    }
+
+    /**
+     * Get the width of the tableau.
+     * @return width of the tableau
+     */
+    protected final int getWidth() {
+        return tableau.getColumnDimension();
+    }
+
+    /**
+     * Get the height of the tableau.
+     * @return height of the tableau
+     */
+    protected final int getHeight() {
+        return tableau.getRowDimension();
+    }
+
+    /** Get an entry of the tableau.
+     * @param row row index
+     * @param column column index
+     * @return entry at (row, column)
+     */
+    protected final double getEntry(final int row, final int column) {
+        return tableau.getEntry(row, column);
+    }
+
+    /** Set an entry of the tableau.
+     * @param row row index
+     * @param column column index
+     * @param value for the entry
+     */
+    protected final void setEntry(final int row, final int column,
+                                  final double value) {
+        tableau.setEntry(row, column, value);
+    }
+
+    /**
+     * Get the offset of the first slack variable.
+     * @return offset of the first slack variable
+     */
+    protected final int getSlackVariableOffset() {
+        return getNumObjectiveFunctions() + numDecisionVariables;
+    }
+
+    /**
+     * Get the offset of the first artificial variable.
+     * @return offset of the first artificial variable
+     */
+    protected final int getArtificialVariableOffset() {
+        return getNumObjectiveFunctions() + numDecisionVariables + numSlackVariables;
+    }
+
+    /**
+     * Get the offset of the right hand side.
+     * @return offset of the right hand side
+     */
+    protected final int getRhsOffset() {
+        return getWidth() - 1;
+    }
+
+    /**
+     * Get the number of decision variables.
+     * <p>
+     * If variables are not restricted to positive values, this will include 1
+     * extra decision variable to represent the absolute value of the most
+     * negative variable.
+     * </p>
+     * @return number of decision variables
+     * @see #getOriginalNumDecisionVariables()
+     */
+    protected final int getNumDecisionVariables() {
+        return numDecisionVariables;
+    }
+
+    /**
+     * Get the original number of decision variables.
+     * @return original number of decision variables
+     * @see #getNumDecisionVariables()
+     */
+    protected final int getOriginalNumDecisionVariables() {
+        return f.getCoefficients().getDimension();
+    }
+
+    /**
+     * Get the number of slack variables.
+     * @return number of slack variables
+     */
+    protected final int getNumSlackVariables() {
+        return numSlackVariables;
+    }
+
+    /**
+     * Get the number of artificial variables.
+     * @return number of artificial variables
+     */
+    protected final int getNumArtificialVariables() {
+        return numArtificialVariables;
+    }
+
+    /**
+     * Get the tableau data.
+     * @return tableau data
+     */
+    protected final double[][] getData() {
+        return tableau.getData();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+
+      if (this == other) {
+        return true;
+      }
+
+      if (other instanceof SimplexTableau) {
+          SimplexTableau rhs = (SimplexTableau) other;
+          return (restrictToNonNegative  == rhs.restrictToNonNegative) &&
+                 (numDecisionVariables   == rhs.numDecisionVariables) &&
+                 (numSlackVariables      == rhs.numSlackVariables) &&
+                 (numArtificialVariables == rhs.numArtificialVariables) &&
+                 (epsilon                == rhs.epsilon) &&
+                 f.equals(rhs.f) &&
+                 constraints.equals(rhs.constraints) &&
+                 tableau.equals(rhs.tableau);
+      }
+      return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return Boolean.valueOf(restrictToNonNegative).hashCode() ^
+               numDecisionVariables ^
+               numSlackVariables ^
+               numArtificialVariables ^
+               Double.valueOf(epsilon).hashCode() ^
+               f.hashCode() ^
+               constraints.hashCode() ^
+               tableau.hashCode();
+    }
+
+    /** Serialize the instance.
+     * @param oos stream where object should be written
+     * @throws IOException if object cannot be written to stream
+     */
+    private void writeObject(ObjectOutputStream oos)
+        throws IOException {
+        oos.defaultWriteObject();
+        MatrixUtils.serializeRealMatrix(tableau, oos);
+    }
+
+    /** Deserialize the instance.
+     * @param ois stream from which the object should be read
+     * @throws ClassNotFoundException if a class in the stream cannot be found
+     * @throws IOException if object cannot be read from the stream
+     */
+    private void readObject(ObjectInputStream ois)
+      throws ClassNotFoundException, IOException {
+        ois.defaultReadObject();
+        MatrixUtils.deserializeRealMatrix(this, "tableau", ois);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/UnboundedSolutionException.java b/src/main/java/org/apache/commons/math/optimization/linear/UnboundedSolutionException.java
new file mode 100644
index 0000000..b769c32
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/UnboundedSolutionException.java
@@ -0,0 +1,41 @@
+/*
+ * 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.optimization.linear;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.OptimizationException;
+
+/**
+ * This class represents exceptions thrown by optimizers when a solution
+ * escapes to infinity.
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class UnboundedSolutionException extends OptimizationException {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 940539497277290619L;
+
+    /**
+     * Simple constructor using a default message.
+     */
+    public UnboundedSolutionException() {
+        super(LocalizedFormats.UNBOUNDED_SOLUTION);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/linear/package.html b/src/main/java/org/apache/commons/math/optimization/linear/package.html
new file mode 100644
index 0000000..beb79a1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/linear/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 758920 $ -->
+<body>
+This package provides optimization algorithms for linear constrained problems.
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/optimization/package.html b/src/main/java/org/apache/commons/math/optimization/package.html
new file mode 100644
index 0000000..8550a80
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/package.html
@@ -0,0 +1,72 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 758074 $ -->
+<body>
+<p>
+This package provides common interfaces for the optimization algorithms
+provided in sub-packages. The main interfaces defines optimizers and convergence
+checkers. The functions that are optimized by the algorithms provided by this
+package and its sub-packages are a subset of the one defined in the <code>analysis</code>
+package, namely the real and vector valued functions. These functions are called
+objective function here. When the goal is to minimize, the functions are often called
+cost function, this name is not used in this package.
+</p>
+
+<p>
+Optimizers are the algorithms that will either minimize or maximize, the objective function
+by changing its input variables set until an optimal set is found. There are only four
+interfaces defining the common behavior of optimizers, one for each supported type of objective
+function:
+<ul>
+  <li>{@link org.apache.commons.math.optimization.UnivariateRealOptimizer
+      UnivariateRealOptimizer} for {@link org.apache.commons.math.analysis.UnivariateRealFunction
+      univariate real functions}</li>
+  <li>{@link org.apache.commons.math.optimization.MultivariateRealOptimizer
+      MultivariateRealOptimizer} for {@link org.apache.commons.math.analysis.MultivariateRealFunction
+      multivariate real functions}</li>
+  <li>{@link org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer
+      DifferentiableMultivariateRealOptimizer} for {@link
+      org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction
+      differentiable multivariate real functions}</li>
+  <li>{@link org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer
+      DifferentiableMultivariateVectorialOptimizer} for {@link
+      org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction
+      differentiable multivariate vectorial functions}</li>
+</ul>
+</p>
+
+<p>
+Despite there are only four types of supported optimizers, it is possible to optimize a
+transform a {@link org.apache.commons.math.analysis.MultivariateVectorialFunction
+non-differentiable multivariate vectorial function} by converting it to a {@link
+org.apache.commons.math.analysis.MultivariateRealFunction non-differentiable multivariate
+real function} thanks to the {@link
+org.apache.commons.math.optimization.LeastSquaresConverter LeastSquaresConverter} helper class.
+The transformed function can be optimized using any implementation of the {@link
+org.apache.commons.math.optimization.MultivariateRealOptimizer MultivariateRealOptimizer} interface.
+</p>
+
+<p>
+For each of the four types of supported optimizers, there is a special implementation which
+wraps a classical optimizer in order to add it a multi-start feature. This feature call the
+underlying optimizer several times in sequence with different starting points and returns
+the best optimum found or all optima if desired. This is a classical way to prevent being
+trapped into a local extremum when looking for a global one.
+</p>
+</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/optimization/univariate/AbstractUnivariateRealOptimizer.java b/src/main/java/org/apache/commons/math/optimization/univariate/AbstractUnivariateRealOptimizer.java
new file mode 100644
index 0000000..399a1b2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/univariate/AbstractUnivariateRealOptimizer.java
@@ -0,0 +1,275 @@
+/*
+ * 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.optimization.univariate;
+
+import org.apache.commons.math.ConvergingAlgorithmImpl;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxEvaluationsExceededException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.MathUnsupportedOperationException;
+import org.apache.commons.math.exception.NoDataException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.optimization.UnivariateRealOptimizer;
+
+/**
+ * Provide a default implementation for several functions useful to generic
+ * optimizers.
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AbstractUnivariateRealOptimizer
+    extends ConvergingAlgorithmImpl implements UnivariateRealOptimizer {
+    /** Indicates where a root has been computed. */
+    protected boolean resultComputed;
+    /** The last computed root. */
+    protected double result;
+    /** Value of the function at the last computed result. */
+    protected double functionValue;
+    /** Maximal number of evaluations allowed. */
+    private int maxEvaluations;
+    /** Number of evaluations already performed. */
+    private int evaluations;
+    /** Optimization type */
+    private GoalType optimizationGoal;
+    /** Lower end of search interval. */
+    private double searchMin;
+    /** Higher end of search interval. */
+    private double searchMax;
+    /** Initial guess . */
+    private double searchStart;
+    /** Function to optimize. */
+    private UnivariateRealFunction function;
+
+    /**
+     * Construct a solver with given iteration count and accuracy.
+     * @param defaultAbsoluteAccuracy maximum absolute error
+     * @param defaultMaximalIterationCount maximum number of iterations
+     * @throws IllegalArgumentException if f is null or the
+     * defaultAbsoluteAccuracy is not valid
+     * @deprecated in 2.2. Please use the "setter" methods to assign meaningful
+     * values to the maximum numbers of iterations and evaluations, and to the
+     * absolute and relative accuracy thresholds.
+     */
+    @Deprecated
+    protected AbstractUnivariateRealOptimizer(final int defaultMaximalIterationCount,
+                                              final double defaultAbsoluteAccuracy) {
+        super(defaultMaximalIterationCount, defaultAbsoluteAccuracy);
+        resultComputed = false;
+        setMaxEvaluations(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Default constructor.
+     * To be removed once the single non-default one has been removed.
+     */
+    protected AbstractUnivariateRealOptimizer() {}
+
+    /**
+     * Check whether a result has been computed.
+     * @throws NoDataException if no result has been computed
+     * @deprecated in 2.2 (no alternative).
+     */
+    @Deprecated
+    protected void checkResultComputed() {
+        if (!resultComputed) {
+            throw new NoDataException();
+        }
+    }
+
+    /** {@inheritDoc} */
+    public double getResult() {
+        if (!resultComputed) {
+            throw new NoDataException();
+        }
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    public double getFunctionValue() throws FunctionEvaluationException {
+        if (Double.isNaN(functionValue)) {
+            final double opt = getResult();
+            functionValue = function.value(opt);
+        }
+        return functionValue;
+    }
+
+    /**
+     * Convenience function for implementations.
+     *
+     * @param x the result to set
+     * @param fx the result to set
+     * @param iterationCount the iteration count to set
+     * @deprecated in 2.2 (no alternative).
+     */
+    @Deprecated
+    protected final void setResult(final double x, final double fx,
+                                   final int iterationCount) {
+        this.result         = x;
+        this.functionValue  = fx;
+        this.iterationCount = iterationCount;
+        this.resultComputed = true;
+    }
+
+    /**
+     * Convenience function for implementations.
+     * @deprecated in 2.2 (no alternative).
+     */
+    @Deprecated
+    protected final void clearResult() {
+        this.resultComputed = false;
+    }
+
+    /** {@inheritDoc} */
+    public void setMaxEvaluations(int maxEvaluations) {
+        this.maxEvaluations = maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getMaxEvaluations() {
+        return maxEvaluations;
+    }
+
+    /** {@inheritDoc} */
+    public int getEvaluations() {
+        return evaluations;
+    }
+
+    /**
+     * @return the optimization type.
+     */
+    public GoalType getGoalType() {
+        return optimizationGoal;
+    }
+    /**
+     * @return the lower of the search interval.
+     */
+    public double getMin() {
+        return searchMin;
+    }
+    /**
+     * @return the higher of the search interval.
+     */
+    public double getMax() {
+        return searchMax;
+    }
+    /**
+     * @return the initial guess.
+     */
+    public double getStartValue() {
+        return searchStart;
+    }
+
+    /**
+     * Compute the objective function value.
+     * @param f objective function
+     * @param point point at which the objective function must be evaluated
+     * @return objective function value at specified point
+     * @exception FunctionEvaluationException if the function cannot be evaluated
+     * or the maximal number of iterations is exceeded
+     * @deprecated in 2.2. Use this {@link #computeObjectiveValue(double)
+     * replacement} instead.
+     */
+    @Deprecated
+    protected double computeObjectiveValue(final UnivariateRealFunction f,
+                                           final double point)
+        throws FunctionEvaluationException {
+        if (++evaluations > maxEvaluations) {
+            throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point);
+        }
+        return f.value(point);
+    }
+
+    /**
+     * Compute the objective function value.
+     *
+     * @param point Point at which the objective function must be evaluated.
+     * @return the objective function value at specified point.
+     * @exception FunctionEvaluationException if the function cannot be evaluated
+     * or the maximal number of iterations is exceeded.
+     */
+    protected double computeObjectiveValue(double point)
+        throws FunctionEvaluationException {
+        if (++evaluations > maxEvaluations) {
+            resultComputed = false;
+            throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), point);
+        }
+        return function.value(point);
+    }
+
+    /** {@inheritDoc} */
+    public double optimize(UnivariateRealFunction f, GoalType goal,
+                           double min, double max, double startValue)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        // Initialize.
+        this.searchMin = min;
+        this.searchMax = max;
+        this.searchStart = startValue;
+        this.optimizationGoal = goal;
+        this.function = f;
+
+        // Reset.
+        functionValue = Double.NaN;
+        evaluations = 0;
+        resetIterationsCounter();
+
+        // Perform computation.
+        result = doOptimize();
+        resultComputed = true;
+
+        return result;
+    }
+
+    /**
+     * Set the value at the optimum.
+     *
+     * @param functionValue Value of the objective function at the optimum.
+     */
+    protected void setFunctionValue(double functionValue) {
+        this.functionValue = functionValue;
+    }
+
+    /** {@inheritDoc} */
+    public double optimize(UnivariateRealFunction f, GoalType goal,
+                           double min, double max)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return optimize(f, goal, min, max, min + 0.5 * (max - min));
+    }
+
+    /**
+     * Method for implementing actual optimization algorithms in derived
+     * classes.
+     *
+     * From version 3.0 onwards, this method will be abstract - i.e.
+     * concrete implementations will have to implement it.  If this method
+     * is not implemented, subclasses must override
+     * {@link #optimize(UnivariateRealFunction, GoalType, double, double)}.
+     *
+     * @return the optimum.
+     * @throws MaxIterationsExceededException if the maximum iteration count
+     * is exceeded.
+     * @throws FunctionEvaluationException if an error occurs evaluating
+     * the function.
+     */
+    protected double doOptimize()
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        throw new MathUnsupportedOperationException(LocalizedFormats.NOT_OVERRIDEN);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/univariate/BracketFinder.java b/src/main/java/org/apache/commons/math/optimization/univariate/BracketFinder.java
new file mode 100644
index 0000000..18e7015
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/univariate/BracketFinder.java
@@ -0,0 +1,295 @@
+/*
+ * 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.optimization.univariate;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.optimization.GoalType;
+
+/**
+ * Provide an interval that brackets a local optimum of a function.
+ * This code is based on a Python implementation (from <em>SciPy</em>,
+ * module {@code optimize.py} v0.5).
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class BracketFinder {
+    /** Tolerance to avoid division by zero. */
+    private static final double EPS_MIN = 1e-21;
+    /**
+     * Golden section.
+     */
+    private static final double GOLD = 1.618034;
+    /**
+     * Factor for expanding the interval.
+     */
+    private final double growLimit;
+    /**
+     * Maximum number of iterations.
+     */
+    private final int maxIterations;
+    /**
+     * Number of iterations.
+     */
+    private int iterations;
+    /**
+     * Number of function evaluations.
+     */
+    private int evaluations;
+    /**
+     * Lower bound of the bracket.
+     */
+    private double lo;
+    /**
+     * Higher bound of the bracket.
+     */
+    private double hi;
+    /**
+     * Point inside the bracket.
+     */
+    private double mid;
+    /**
+     * Function value at {@link #lo}.
+     */
+    private double fLo;
+    /**
+     * Function value at {@link #hi}.
+     */
+    private double fHi;
+    /**
+     * Function value at {@link #mid}.
+     */
+    private double fMid;
+
+    /**
+     * Constructor with default values {@code 100, 50} (see the
+     * {@link #BracketFinder(double,int) other constructor}).
+     */
+    public BracketFinder() {
+        this(100, 50);
+    }
+
+    /**
+     * Create a bracketing interval finder.
+     *
+     * @param growLimit Expanding factor.
+     * @param maxIterations Maximum number of iterations allowed for finding
+     * a bracketing interval.
+     */
+    public BracketFinder(double growLimit,
+                         int maxIterations) {
+        if (growLimit <= 0) {
+            throw new NotStrictlyPositiveException(growLimit);
+        }
+        if (maxIterations <= 0) {
+            throw new NotStrictlyPositiveException(maxIterations);
+        }
+
+        this.growLimit = growLimit;
+        this.maxIterations = maxIterations;
+    }
+
+    /**
+     * Search new points that bracket a local optimum of the function.
+     *
+     * @param func Function whose optimum should be bracketted.
+     * @param goal {@link GoalType Goal type}.
+     * @param xA Initial point.
+     * @param xB Initial point.
+     * @throws MaxIterationsExceededException if the maximum iteration count
+     * is exceeded.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function.
+     */
+    public void search(UnivariateRealFunction func,
+                       GoalType goal,
+                       double xA,
+                       double xB)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        reset();
+        final boolean isMinim = goal == GoalType.MINIMIZE;
+
+        double fA = eval(func, xA);
+        double fB = eval(func, xB);
+        if (isMinim ?
+            fA < fB :
+            fA > fB) {
+            double tmp = xA;
+            xA = xB;
+            xB = tmp;
+
+            tmp = fA;
+            fA = fB;
+            fB = tmp;
+        }
+
+        double xC = xB + GOLD * (xB - xA);
+        double fC = eval(func, xC);
+
+        while (isMinim ? fC < fB : fC > fB) {
+            if (++iterations > maxIterations) {
+                throw new MaxIterationsExceededException(maxIterations);
+            }
+
+            double tmp1 = (xB - xA) * (fB - fC);
+            double tmp2 = (xB - xC) * (fB - fA);
+
+            double val = tmp2 - tmp1;
+            double denom = Math.abs(val) < EPS_MIN ? 2 * EPS_MIN : 2 * val;
+
+            double w = xB - ((xB - xC) * tmp2 - (xB -xA) * tmp1) / denom;
+            double wLim = xB + growLimit * (xC - xB);
+
+            double fW;
+            if ((w - xC) * (xB - w) > 0) {
+                fW = eval(func, w);
+                if (isMinim ?
+                    fW < fC :
+                    fW > fC) {
+                    xA = xB;
+                    xB = w;
+                    fA = fB;
+                    fB = fW;
+                    break;
+                } else if (isMinim ?
+                           fW > fB :
+                           fW < fB) {
+                    xC = w;
+                    fC = fW;
+                    break;
+                }
+                w = xC + GOLD * (xC - xB);
+                fW = eval(func, w);
+            } else if ((w - wLim) * (wLim - xC) >= 0) {
+                w = wLim;
+                fW = eval(func, w);
+            } else if ((w - wLim) * (xC - w) > 0) {
+                fW = eval(func, w);
+                if (isMinim ?
+                    fW < fC :
+                    fW > fC) {
+                    xB = xC;
+                    xC = w;
+                    w = xC + GOLD * (xC -xB);
+                    fB = fC;
+                    fC =fW;
+                    fW = eval(func, w);
+                }
+            } else {
+                w = xC + GOLD * (xC - xB);
+                fW = eval(func, w);
+            }
+
+            xA = xB;
+            xB = xC;
+            xC = w;
+            fA = fB;
+            fB = fC;
+            fC = fW;
+        }
+
+        lo = xA;
+        mid = xB;
+        hi = xC;
+        fLo = fA;
+        fMid = fB;
+        fHi = fC;
+    }
+
+    /**
+     * @return the number of iterations.
+     */
+    public int getIterations() {
+        return iterations;
+    }
+    /**
+     * @return the number of evaluations.
+     */
+    public int getEvaluations() {
+        return evaluations;
+    }
+
+    /**
+     * @return the lower bound of the bracket.
+     * @see #getFLow()
+     */
+    public double getLo() {
+        return lo;
+    }
+
+    /**
+     * Get function value at {@link #getLo()}.
+     * @return function value at {@link #getLo()}
+     */
+    public double getFLow() {
+        return fLo;
+    }
+
+    /**
+     * @return the higher bound of the bracket.
+     * @see #getFHi()
+     */
+    public double getHi() {
+        return hi;
+    }
+
+    /**
+     * Get function value at {@link #getHi()}.
+     * @return function value at {@link #getHi()}
+     */
+    public double getFHi() {
+        return fHi;
+    }
+
+    /**
+     * @return a point in the middle of the bracket.
+     * @see #getFMid()
+     */
+    public double getMid() {
+        return mid;
+    }
+
+    /**
+     * Get function value at {@link #getMid()}.
+     * @return function value at {@link #getMid()}
+     */
+    public double getFMid() {
+        return fMid;
+    }
+
+    /**
+     * @param f Function.
+     * @param x Argument.
+     * @return {@code f(x)}
+     * @throws FunctionEvaluationException if function cannot be evaluated at x
+     */
+    private double eval(UnivariateRealFunction f, double x)
+        throws FunctionEvaluationException {
+
+        ++evaluations;
+        return f.value(x);
+    }
+
+    /**
+     * Reset internal state.
+     */
+    private void reset() {
+        iterations = 0;
+        evaluations = 0;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/univariate/BrentOptimizer.java b/src/main/java/org/apache/commons/math/optimization/univariate/BrentOptimizer.java
new file mode 100644
index 0000000..73d1d8c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/univariate/BrentOptimizer.java
@@ -0,0 +1,227 @@
+/*
+ * 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.optimization.univariate;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.optimization.GoalType;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements Richard Brent's algorithm (from his book "Algorithms for
+ * Minimization without Derivatives", p. 79) for finding minima of real
+ * univariate functions. This implementation is an adaptation partly
+ * based on the Python code from SciPy (module "optimize.py" v0.5).
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public class BrentOptimizer extends AbstractUnivariateRealOptimizer {
+    /**
+     * Golden section.
+     */
+    private static final double GOLDEN_SECTION = 0.5 * (3 - FastMath.sqrt(5));
+
+    /**
+     * Construct a solver.
+     */
+    public BrentOptimizer() {
+        setMaxEvaluations(1000);
+        setMaximalIterationCount(100);
+        setAbsoluteAccuracy(1e-11);
+        setRelativeAccuracy(1e-9);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected double doOptimize()
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        return localMin(getGoalType() == GoalType.MINIMIZE,
+                        getMin(), getStartValue(), getMax(),
+                        getRelativeAccuracy(), getAbsoluteAccuracy());
+    }
+
+    /**
+     * Find the minimum of the function within the interval {@code (lo, hi)}.
+     *
+     * If the function is defined on the interval {@code (lo, hi)}, then
+     * this method finds an approximation {@code x} to the point at which
+     * the function attains its minimum.<br/>
+     * {@code t} and {@code eps} define a tolerance {@code tol = eps |x| + t}
+     * and the function is never evaluated at two points closer together than
+     * {@code tol}. {@code eps} should be no smaller than <em>2 macheps</em> and
+     * preferable not much less than <em>sqrt(macheps)</em>, where
+     * <em>macheps</em> is the relative machine precision. {@code t} should be
+     * positive.
+     * @param isMinim {@code true} when minimizing the function.
+     * @param lo Lower bound of the interval.
+     * @param mid Point inside the interval {@code [lo, hi]}.
+     * @param hi Higher bound of the interval.
+     * @param eps Relative accuracy.
+     * @param t Absolute accuracy.
+     * @return the optimum point.
+     * @throws MaxIterationsExceededException if the maximum iteration count
+     * is exceeded.
+     * @throws FunctionEvaluationException if an error occurs evaluating the function.
+     */
+    private double localMin(boolean isMinim,
+                            double lo, double mid, double hi,
+                            double eps, double t)
+        throws MaxIterationsExceededException, FunctionEvaluationException {
+        if (eps <= 0) {
+            throw new NotStrictlyPositiveException(eps);
+        }
+        if (t <= 0) {
+            throw new NotStrictlyPositiveException(t);
+        }
+        double a;
+        double b;
+        if (lo < hi) {
+            a = lo;
+            b = hi;
+        } else {
+            a = hi;
+            b = lo;
+        }
+
+        double x = mid;
+        double v = x;
+        double w = x;
+        double d = 0;
+        double e = 0;
+        double fx = computeObjectiveValue(x);
+        if (!isMinim) {
+            fx = -fx;
+        }
+        double fv = fx;
+        double fw = fx;
+
+        while (true) {
+            double m = 0.5 * (a + b);
+            final double tol1 = eps * FastMath.abs(x) + t;
+            final double tol2 = 2 * tol1;
+
+            // Check stopping criterion.
+            if (FastMath.abs(x - m) > tol2 - 0.5 * (b - a)) {
+                double p = 0;
+                double q = 0;
+                double r = 0;
+                double u = 0;
+
+                if (FastMath.abs(e) > tol1) { // Fit parabola.
+                    r = (x - w) * (fx - fv);
+                    q = (x - v) * (fx - fw);
+                    p = (x - v) * q - (x - w) * r;
+                    q = 2 * (q - r);
+
+                    if (q > 0) {
+                        p = -p;
+                    } else {
+                        q = -q;
+                    }
+
+                    r = e;
+                    e = d;
+
+                    if (p > q * (a - x) &&
+                        p < q * (b - x) &&
+                        FastMath.abs(p) < FastMath.abs(0.5 * q * r)) {
+                        // Parabolic interpolation step.
+                        d = p / q;
+                        u = x + d;
+
+                        // f must not be evaluated too close to a or b.
+                        if (u - a < tol2 || b - u < tol2) {
+                            if (x <= m) {
+                                d = tol1;
+                            } else {
+                                d = -tol1;
+                            }
+                        }
+                    } else {
+                        // Golden section step.
+                        if (x < m) {
+                            e = b - x;
+                        } else {
+                            e = a - x;
+                        }
+                        d = GOLDEN_SECTION * e;
+                    }
+                } else {
+                    // Golden section step.
+                    if (x < m) {
+                        e = b - x;
+                    } else {
+                        e = a - x;
+                    }
+                    d = GOLDEN_SECTION * e;
+                }
+
+                // Update by at least "tol1".
+                if (FastMath.abs(d) < tol1) {
+                    if (d >= 0) {
+                        u = x + tol1;
+                    } else {
+                        u = x - tol1;
+                    }
+                } else {
+                    u = x + d;
+                }
+
+                double fu = computeObjectiveValue(u);
+                if (!isMinim) {
+                    fu = -fu;
+                }
+
+                // Update a, b, v, w and x.
+                if (fu <= fx) {
+                    if (u < x) {
+                        b = x;
+                    } else {
+                        a = x;
+                    }
+                    v = w;
+                    fv = fw;
+                    w = x;
+                    fw = fx;
+                    x = u;
+                    fx = fu;
+                } else {
+                    if (u < x) {
+                        a = u;
+                    } else {
+                        b = u;
+                    }
+                    if (fu <= fw || w == x) {
+                        v = w;
+                        fv = fw;
+                        w = u;
+                        fw = fu;
+                    } else if (fu <= fv || v == x || v == w) {
+                        v = u;
+                        fv = fu;
+                    }
+                }
+            } else { // termination
+                setFunctionValue(isMinim ? fx : -fx);
+                return x;
+            }
+            incrementIterationsCounter();
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/optimization/univariate/package.html b/src/main/java/org/apache/commons/math/optimization/univariate/package.html
new file mode 100644
index 0000000..d792fc0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/optimization/univariate/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+     Univariate real functions minimum finding algorithms.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/package.html b/src/main/java/org/apache/commons/math/package.html
new file mode 100644
index 0000000..bdf939c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Common classes used throughout the commons-math library.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/random/AbstractRandomGenerator.java b/src/main/java/org/apache/commons/math/random/AbstractRandomGenerator.java
new file mode 100644
index 0000000..afec63e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/AbstractRandomGenerator.java
@@ -0,0 +1,272 @@
+/*
+ * 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.random;
+
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Abstract class implementing the {@link  RandomGenerator} interface.
+ * Default implementations for all methods other than {@link #nextDouble()} and
+ * {@link #setSeed(long)} are provided.
+ * <p>
+ * All data generation methods are based on {@code code nextDouble()}.
+ * Concrete implementations <strong>must</strong> override
+ * this method and <strong>should</strong> provide better / more
+ * performant implementations of the other methods if the underlying PRNG
+ * supplies them.</p>
+ *
+ * @since 1.1
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public abstract class AbstractRandomGenerator implements RandomGenerator {
+
+    /**
+     * Cached random normal value.  The default implementation for
+     * {@link #nextGaussian} generates pairs of values and this field caches the
+     * second value so that the full algorithm is not executed for every
+     * activation.  The value {@code Double.NaN} signals that there is
+     * no cached value.  Use {@link #clear} to clear the cached value.
+     */
+    private double cachedNormalDeviate = Double.NaN;
+
+    /**
+     * Construct a RandomGenerator.
+     */
+    public AbstractRandomGenerator() {
+        super();
+
+    }
+
+    /**
+     * Clears the cache used by the default implementation of
+     * {@link #nextGaussian}. Implemementations that do not override the
+     * default implementation of {@code nextGaussian} should call this
+     * method in the implementation of {@link #setSeed(long)}
+     */
+    public void clear() {
+        cachedNormalDeviate = Double.NaN;
+    }
+
+    /** {@inheritDoc} */
+    public void setSeed(int seed) {
+        setSeed((long) seed);
+    }
+
+    /** {@inheritDoc} */
+    public void setSeed(int[] seed) {
+        // the following number is the largest prime that fits in 32 bits (it is 2^32 - 5)
+        final long prime = 4294967291l;
+
+        long combined = 0l;
+        for (int s : seed) {
+            combined = combined * prime + s;
+        }
+        setSeed(combined);
+    }
+
+    /**
+     * Sets the seed of the underyling random number generator using a
+     * {@code long} seed.  Sequences of values generated starting with the
+     * same seeds should be identical.
+     * <p>
+     * Implementations that do not override the default implementation of
+     * {@code nextGaussian} should include a call to {@link #clear} in the
+     * implementation of this method.</p>
+     *
+     * @param seed the seed value
+     */
+    public abstract void setSeed(long seed);
+
+    /**
+     * Generates random bytes and places them into a user-supplied
+     * byte array.  The number of random bytes produced is equal to
+     * the length of the byte array.
+     * <p>
+     * The default implementation fills the array with bytes extracted from
+     * random integers generated using {@link #nextInt}.</p>
+     *
+     * @param bytes the non-null byte array in which to put the
+     * random bytes
+     */
+    public void nextBytes(byte[] bytes) {
+        int bytesOut = 0;
+        while (bytesOut < bytes.length) {
+          int randInt = nextInt();
+          for (int i = 0; i < 3; i++) {
+              if ( i > 0) {
+                  randInt = randInt >> 8;
+              }
+              bytes[bytesOut++] = (byte) randInt;
+              if (bytesOut == bytes.length) {
+                  return;
+              }
+          }
+        }
+    }
+
+     /**
+     * Returns the next pseudorandom, uniformly distributed {@code int}
+     * value from this random number generator's sequence.
+     * All 2<font size="-1"><sup>32</sup></font> possible {@code int} values
+     * should be produced with  (approximately) equal probability.
+     * <p>
+     * The default implementation provided here returns
+     * <pre>
+     * <code>(int) (nextDouble() * Integer.MAX_VALUE)</code>
+     * </pre></p>
+     *
+     * @return the next pseudorandom, uniformly distributed {@code int}
+     *  value from this random number generator's sequence
+     */
+    public int nextInt() {
+        return (int) (nextDouble() * Integer.MAX_VALUE);
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed {@code int} value
+     * between 0 (inclusive) and the specified value (exclusive), drawn from
+     * this random number generator's sequence.
+     * <p>
+     * The default implementation returns
+     * <pre>
+     * <code>(int) (nextDouble() * n</code>
+     * </pre></p>
+     *
+     * @param n the bound on the random number to be returned.  Must be
+     * positive.
+     * @return  a pseudorandom, uniformly distributed {@code int}
+     * value between 0 (inclusive) and n (exclusive).
+     * @throws NotStrictlyPositiveException if {@code n <= 0}.
+     */
+    public int nextInt(int n) {
+        if (n <= 0 ) {
+            throw new NotStrictlyPositiveException(n);
+        }
+        int result = (int) (nextDouble() * n);
+        return result < n ? result : n - 1;
+    }
+
+     /**
+     * Returns the next pseudorandom, uniformly distributed {@code long}
+     * value from this random number generator's sequence.  All
+     * 2<font size="-1"><sup>64</sup></font> possible {@code long} values
+     * should be produced with (approximately) equal probability.
+     * <p>
+     * The default implementation returns
+     * <pre>
+     * <code>(long) (nextDouble() * Long.MAX_VALUE)</code>
+     * </pre></p>
+     *
+     * @return  the next pseudorandom, uniformly distributed {@code long}
+     *value from this random number generator's sequence
+     */
+    public long nextLong() {
+        return (long) (nextDouble() * Long.MAX_VALUE);
+    }
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed
+     * {@code boolean} value from this random number generator's
+     * sequence.
+     * <p>
+     * The default implementation returns
+     * <pre>
+     * <code>nextDouble() <= 0.5</code>
+     * </pre></p>
+     *
+     * @return  the next pseudorandom, uniformly distributed
+     * {@code boolean} value from this random number generator's
+     * sequence
+     */
+    public boolean nextBoolean() {
+        return nextDouble() <= 0.5;
+    }
+
+     /**
+     * Returns the next pseudorandom, uniformly distributed {@code float}
+     * value between {@code 0.0} and {@code 1.0} from this random
+     * number generator's sequence.
+     * <p>
+     * The default implementation returns
+     * <pre>
+     * <code>(float) nextDouble() </code>
+     * </pre></p>
+     *
+     * @return  the next pseudorandom, uniformly distributed {@code float}
+     * value between {@code 0.0} and {@code 1.0} from this
+     * random number generator's sequence
+     */
+    public float nextFloat() {
+        return (float) nextDouble();
+    }
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed
+     * {@code double} value between {@code 0.0} and
+     * {@code 1.0} from this random number generator's sequence.
+     * <p>
+     * This method provides the underlying source of random data used by the
+     * other methods.</p>
+     *
+     * @return  the next pseudorandom, uniformly distributed
+     *  {@code double} value between {@code 0.0} and
+     *  {@code 1.0} from this random number generator's sequence
+     */
+    public abstract double nextDouble();
+
+    /**
+     * Returns the next pseudorandom, Gaussian ("normally") distributed
+     * {@code double} value with mean {@code 0.0} and standard
+     * deviation {@code 1.0} from this random number generator's sequence.
+     * <p>
+     * The default implementation uses the <em>Polar Method</em>
+     * due to G.E.P. Box, M.E. Muller and G. Marsaglia, as described in
+     * D. Knuth, <u>The Art of Computer Programming</u>, 3.4.1C.</p>
+     * <p>
+     * The algorithm generates a pair of independent random values.  One of
+     * these is cached for reuse, so the full algorithm is not executed on each
+     * activation.  Implementations that do not override this method should
+     * make sure to call {@link #clear} to clear the cached value in the
+     * implementation of {@link #setSeed(long)}.</p>
+     *
+     * @return  the next pseudorandom, Gaussian ("normally") distributed
+     * {@code double} value with mean {@code 0.0} and
+     * standard deviation {@code 1.0} from this random number
+     *  generator's sequence
+     */
+    public double nextGaussian() {
+        if (!Double.isNaN(cachedNormalDeviate)) {
+            double dev = cachedNormalDeviate;
+            cachedNormalDeviate = Double.NaN;
+            return dev;
+        }
+        double v1 = 0;
+        double v2 = 0;
+        double s = 1;
+        while (s >=1 ) {
+            v1 = 2 * nextDouble() - 1;
+            v2 = 2 * nextDouble() - 1;
+            s = v1 * v1 + v2 * v2;
+        }
+        if (s != 0) {
+            s = FastMath.sqrt(-2 * FastMath.log(s) / s);
+        }
+        cachedNormalDeviate = v2 * s;
+        return v1 * s;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/random/AbstractWell.java b/src/main/java/org/apache/commons/math/random/AbstractWell.java
new file mode 100644
index 0000000..96e18a2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/AbstractWell.java
@@ -0,0 +1,186 @@
+/*
+ * 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.random;
+
+import java.io.Serializable;
+
+
+/** This abstract class implements the WELL class of pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public abstract class AbstractWell extends BitsStreamGenerator implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -817701723016583596L;
+
+    /** Current index in the bytes pool. */
+    protected int index;
+
+    /** Bytes pool. */
+    protected final int[] v;
+
+    /** Index indirection table giving for each index its predecessor taking table size into account. */
+    protected final int[] iRm1;
+
+    /** Index indirection table giving for each index its second predecessor taking table size into account. */
+    protected final int[] iRm2;
+
+    /** Index indirection table giving for each index the value index + m1 taking table size into account. */
+    protected final int[] i1;
+
+    /** Index indirection table giving for each index the value index + m2 taking table size into account. */
+    protected final int[] i2;
+
+    /** Index indirection table giving for each index the value index + m3 taking table size into account. */
+    protected final int[] i3;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     * @param k number of bits in the pool (not necessarily a multiple of 32)
+     * @param m1 first parameter of the algorithm
+     * @param m2 second parameter of the algorithm
+     * @param m3 third parameter of the algorithm
+     */
+    protected AbstractWell(final int k, final int m1, final int m2, final int m3) {
+        this(k, m1, m2, m3, System.currentTimeMillis());
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param k number of bits in the pool (not necessarily a multiple of 32)
+     * @param m1 first parameter of the algorithm
+     * @param m2 second parameter of the algorithm
+     * @param m3 third parameter of the algorithm
+     * @param seed the initial seed (32 bits integer)
+     */
+    protected AbstractWell(final int k, final int m1, final int m2, final int m3, final int seed) {
+        this(k, m1, m2, m3, new int[] { seed });
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param k number of bits in the pool (not necessarily a multiple of 32)
+     * @param m1 first parameter of the algorithm
+     * @param m2 second parameter of the algorithm
+     * @param m3 third parameter of the algorithm
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    protected AbstractWell(final int k, final int m1, final int m2, final int m3, final int[] seed) {
+
+        // the bits pool contains k bits, k = r w - p where r is the number
+        // of w bits blocks, w is the block size (always 32 in the original paper)
+        // and p is the number of unused bits in the last block
+        final int w = 32;
+        final int r = (k + w - 1) / w;
+        this.v      = new int[r];
+        this.index  = 0;
+
+        // precompute indirection index tables. These tables are used for optimizing access
+        // they allow saving computations like "(j + r - 2) % r" with costly modulo operations
+        iRm1 = new int[r];
+        iRm2 = new int[r];
+        i1   = new int[r];
+        i2   = new int[r];
+        i3   = new int[r];
+        for (int j = 0; j < r; ++j) {
+            iRm1[j] = (j + r - 1) % r;
+            iRm2[j] = (j + r - 2) % r;
+            i1[j]   = (j + m1)    % r;
+            i2[j]   = (j + m2)    % r;
+            i3[j]   = (j + m3)    % r;
+        }
+
+        // initialize the pool content
+        setSeed(seed);
+
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param k number of bits in the pool (not necessarily a multiple of 32)
+     * @param m1 first parameter of the algorithm
+     * @param m2 second parameter of the algorithm
+     * @param m3 third parameter of the algorithm
+     * @param seed the initial seed (64 bits integer)
+     */
+    protected AbstractWell(final int k, final int m1, final int m2, final int m3, final long seed) {
+        this(k, m1, m2, m3, new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) });
+    }
+
+    /** Reinitialize the generator as if just built with the given int seed.
+     * <p>The state of the generator is exactly the same as a new
+     * generator built with the same seed.</p>
+     * @param seed the initial seed (32 bits integer)
+     */
+    @Override
+    public void setSeed(final int seed) {
+        setSeed(new int[] { seed });
+    }
+
+    /** Reinitialize the generator as if just built with the given int array seed.
+     * <p>The state of the generator is exactly the same as a new
+     * generator built with the same seed.</p>
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    @Override
+    public void setSeed(final int[] seed) {
+
+        if (seed == null) {
+            setSeed(System.currentTimeMillis());
+            return;
+        }
+
+        System.arraycopy(seed, 0, v, 0, Math.min(seed.length, v.length));
+
+        if (seed.length < v.length) {
+            for (int i = seed.length; i < v.length; ++i) {
+                final long l = v[i - seed.length];
+                v[i] = (int) ((1812433253l * (l ^ (l >> 30)) + i) & 0xffffffffL);
+            }
+        }
+
+        index = 0;
+
+    }
+
+    /** Reinitialize the generator as if just built with the given long seed.
+     * <p>The state of the generator is exactly the same as a new
+     * generator built with the same seed.</p>
+     * @param seed the initial seed (64 bits integer)
+     */
+    @Override
+    public void setSeed(final long seed) {
+        setSeed(new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) });
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected abstract int next(final int bits);
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/BitsStreamGenerator.java b/src/main/java/org/apache/commons/math/random/BitsStreamGenerator.java
new file mode 100644
index 0000000..8979473
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/BitsStreamGenerator.java
@@ -0,0 +1,153 @@
+/*
+ * 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.random;
+
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.util.FastMath;
+
+/** Base class for random number generators that generates bits streams.
+
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+
+ */
+public abstract class BitsStreamGenerator implements RandomGenerator {
+
+    /** Next gaussian. */
+    private double nextGaussian;
+
+    /** Creates a new random number generator.
+     */
+    public BitsStreamGenerator() {
+        nextGaussian = Double.NaN;
+    }
+
+    /** {@inheritDoc} */
+    public abstract void setSeed(int seed);
+
+    /** {@inheritDoc} */
+    public abstract void setSeed(int[] seed);
+
+    /** {@inheritDoc} */
+    public abstract void setSeed(long seed);
+
+    /** Generate next pseudorandom number.
+     * <p>This method is the core generation algorithm. It is used by all the
+     * public generation methods for the various primitive types {@link
+     * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()},
+     * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()},
+     * {@link #next(int)} and {@link #nextLong()}.</p>
+     * @param bits number of random bits to produce
+     * @return random bits generated
+     */
+    protected abstract int next(int bits);
+
+    /** {@inheritDoc} */
+    public boolean nextBoolean() {
+        return next(1) != 0;
+    }
+
+    /** {@inheritDoc} */
+    public void nextBytes(byte[] bytes) {
+        int i = 0;
+        final int iEnd = bytes.length - 3;
+        while (i < iEnd) {
+            final int random = next(32);
+            bytes[i]     = (byte) (random & 0xff);
+            bytes[i + 1] = (byte) ((random >>  8) & 0xff);
+            bytes[i + 2] = (byte) ((random >> 16) & 0xff);
+            bytes[i + 3] = (byte) ((random >> 24) & 0xff);
+            i += 4;
+        }
+        int random = next(32);
+        while (i < bytes.length) {
+            bytes[i++] = (byte) (random & 0xff);
+            random     = random >> 8;
+        }
+    }
+
+    /** {@inheritDoc} */
+    public double nextDouble() {
+        final long high = ((long) next(26)) << 26;
+        final int  low  = next(26);
+        return (high | low) * 0x1.0p-52d;
+    }
+
+    /** {@inheritDoc} */
+    public float nextFloat() {
+        return next(23) * 0x1.0p-23f;
+    }
+
+    /** {@inheritDoc} */
+    public double nextGaussian() {
+
+        final double random;
+        if (Double.isNaN(nextGaussian)) {
+            // generate a new pair of gaussian numbers
+            final double x = nextDouble();
+            final double y = nextDouble();
+            final double alpha = 2 * FastMath.PI * x;
+            final double r      = FastMath.sqrt(-2 * FastMath.log(y));
+            random       = r * FastMath.cos(alpha);
+            nextGaussian = r * FastMath.sin(alpha);
+        } else {
+            // use the second element of the pair already generated
+            random = nextGaussian;
+            nextGaussian = Double.NaN;
+        }
+
+        return random;
+
+    }
+
+    /** {@inheritDoc} */
+    public int nextInt() {
+        return next(32);
+    }
+
+    /** {@inheritDoc} */
+    public int nextInt(int n) throws IllegalArgumentException {
+
+        if (n < 1) {
+            throw new NotStrictlyPositiveException(n);
+        }
+
+        // find bit mask for n
+        int mask = n;
+        mask |= mask >> 1;
+        mask |= mask >> 2;
+        mask |= mask >> 4;
+        mask |= mask >> 8;
+        mask |= mask >> 16;
+
+        while (true) {
+            final int random = next(32) & mask;
+            if (random < n) {
+                return random;
+            }
+        }
+
+    }
+
+    /** {@inheritDoc} */
+    public long nextLong() {
+        final long high  = ((long) next(32)) << 32;
+        final long  low  = ((long) next(32)) & 0xffffffffL;
+        return high | low;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.java b/src/main/java/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.java
new file mode 100644
index 0000000..f1df51d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.java
@@ -0,0 +1,304 @@
+/*
+ * 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.random;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.NotPositiveDefiniteMatrixException;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * A {@link RandomVectorGenerator} that generates vectors with with
+ * correlated components.
+ * <p>Random vectors with correlated components are built by combining
+ * the uncorrelated components of another random vector in such a way that
+ * the resulting correlations are the ones specified by a positive
+ * definite covariance matrix.</p>
+ * <p>The main use for correlated random vector generation is for Monte-Carlo
+ * simulation of physical problems with several variables, for example to
+ * generate error vectors to be added to a nominal vector. A particularly
+ * interesting case is when the generated vector should be drawn from a <a
+ * href="http://en.wikipedia.org/wiki/Multivariate_normal_distribution">
+ * Multivariate Normal Distribution</a>. The approach using a Cholesky
+ * decomposition is quite usual in this case. However, it can be extended
+ * to other cases as long as the underlying random generator provides
+ * {@link NormalizedRandomGenerator normalized values} like {@link
+ * GaussianRandomGenerator} or {@link UniformRandomGenerator}.</p>
+ * <p>Sometimes, the covariance matrix for a given simulation is not
+ * strictly positive definite. This means that the correlations are
+ * not all independent from each other. In this case, however, the non
+ * strictly positive elements found during the Cholesky decomposition
+ * of the covariance matrix should not be negative either, they
+ * should be null. Another non-conventional extension handling this case
+ * is used here. Rather than computing <code>C = U<sup>T</sup>.U</code>
+ * where <code>C</code> is the covariance matrix and <code>U</code>
+ * is an upper-triangular matrix, we compute <code>C = B.B<sup>T</sup></code>
+ * where <code>B</code> is a rectangular matrix having
+ * more rows than columns. The number of columns of <code>B</code> is
+ * the rank of the covariance matrix, and it is the dimension of the
+ * uncorrelated random vector that is needed to compute the component
+ * of the correlated vector. This class handles this situation
+ * automatically.</p>
+ *
+ * @version $Revision: 1043908 $ $Date: 2010-12-09 12:53:14 +0100 (jeu. 09 déc. 2010) $
+ * @since 1.2
+ */
+
+public class CorrelatedRandomVectorGenerator
+    implements RandomVectorGenerator {
+
+    /** Mean vector. */
+    private final double[] mean;
+
+    /** Underlying generator. */
+    private final NormalizedRandomGenerator generator;
+
+    /** Storage for the normalized vector. */
+    private final double[] normalized;
+
+    /** Permutated Cholesky root of the covariance matrix. */
+    private RealMatrix root;
+
+    /** Rank of the covariance matrix. */
+    private int rank;
+
+    /** Simple constructor.
+     * <p>Build a correlated random vector generator from its mean
+     * vector and covariance matrix.</p>
+     * @param mean expected mean values for all components
+     * @param covariance covariance matrix
+     * @param small diagonal elements threshold under which  column are
+     * considered to be dependent on previous ones and are discarded
+     * @param generator underlying generator for uncorrelated normalized
+     * components
+     * @exception IllegalArgumentException if there is a dimension
+     * mismatch between the mean vector and the covariance matrix
+     * @exception NotPositiveDefiniteMatrixException if the
+     * covariance matrix is not strictly positive definite
+     * @exception DimensionMismatchException if the mean and covariance
+     * arrays dimensions don't match
+     */
+    public CorrelatedRandomVectorGenerator(double[] mean,
+                                           RealMatrix covariance, double small,
+                                           NormalizedRandomGenerator generator)
+    throws NotPositiveDefiniteMatrixException, DimensionMismatchException {
+
+        int order = covariance.getRowDimension();
+        if (mean.length != order) {
+            throw new DimensionMismatchException(mean.length, order);
+        }
+        this.mean = mean.clone();
+
+        decompose(covariance, small);
+
+        this.generator = generator;
+        normalized = new double[rank];
+
+    }
+
+    /** Simple constructor.
+     * <p>Build a null mean random correlated vector generator from its
+     * covariance matrix.</p>
+     * @param covariance covariance matrix
+     * @param small diagonal elements threshold under which  column are
+     * considered to be dependent on previous ones and are discarded
+     * @param generator underlying generator for uncorrelated normalized
+     * components
+     * @exception NotPositiveDefiniteMatrixException if the
+     * covariance matrix is not strictly positive definite
+     */
+    public CorrelatedRandomVectorGenerator(RealMatrix covariance, double small,
+                                           NormalizedRandomGenerator generator)
+    throws NotPositiveDefiniteMatrixException {
+
+        int order = covariance.getRowDimension();
+        mean = new double[order];
+        for (int i = 0; i < order; ++i) {
+            mean[i] = 0;
+        }
+
+        decompose(covariance, small);
+
+        this.generator = generator;
+        normalized = new double[rank];
+
+    }
+
+    /** Get the underlying normalized components generator.
+     * @return underlying uncorrelated components generator
+     */
+    public NormalizedRandomGenerator getGenerator() {
+        return generator;
+    }
+
+    /** Get the root of the covariance matrix.
+     * The root is the rectangular matrix <code>B</code> such that
+     * the covariance matrix is equal to <code>B.B<sup>T</sup></code>
+     * @return root of the square matrix
+     * @see #getRank()
+     */
+    public RealMatrix getRootMatrix() {
+        return root;
+    }
+
+    /** Get the rank of the covariance matrix.
+     * The rank is the number of independent rows in the covariance
+     * matrix, it is also the number of columns of the rectangular
+     * matrix of the decomposition.
+     * @return rank of the square matrix.
+     * @see #getRootMatrix()
+     */
+    public int getRank() {
+        return rank;
+    }
+
+    /** Decompose the original square matrix.
+     * <p>The decomposition is based on a Choleski decomposition
+     * where additional transforms are performed:
+     * <ul>
+     *   <li>the rows of the decomposed matrix are permuted</li>
+     *   <li>columns with the too small diagonal element are discarded</li>
+     *   <li>the matrix is permuted</li>
+     * </ul>
+     * This means that rather than computing M = U<sup>T</sup>.U where U
+     * is an upper triangular matrix, this method computed M=B.B<sup>T</sup>
+     * where B is a rectangular matrix.
+     * @param covariance covariance matrix
+     * @param small diagonal elements threshold under which  column are
+     * considered to be dependent on previous ones and are discarded
+     * @exception NotPositiveDefiniteMatrixException if the
+     * covariance matrix is not strictly positive definite
+     */
+    private void decompose(RealMatrix covariance, double small)
+    throws NotPositiveDefiniteMatrixException {
+
+        int order = covariance.getRowDimension();
+        double[][] c = covariance.getData();
+        double[][] b = new double[order][order];
+
+        int[] swap  = new int[order];
+        int[] index = new int[order];
+        for (int i = 0; i < order; ++i) {
+            index[i] = i;
+        }
+
+        rank = 0;
+        for (boolean loop = true; loop;) {
+
+            // find maximal diagonal element
+            swap[rank] = rank;
+            for (int i = rank + 1; i < order; ++i) {
+                int ii  = index[i];
+                int isi = index[swap[i]];
+                if (c[ii][ii] > c[isi][isi]) {
+                    swap[rank] = i;
+                }
+            }
+
+
+            // swap elements
+            if (swap[rank] != rank) {
+                int tmp = index[rank];
+                index[rank] = index[swap[rank]];
+                index[swap[rank]] = tmp;
+            }
+
+            // check diagonal element
+            int ir = index[rank];
+            if (c[ir][ir] < small) {
+
+                if (rank == 0) {
+                    throw new NotPositiveDefiniteMatrixException();
+                }
+
+                // check remaining diagonal elements
+                for (int i = rank; i < order; ++i) {
+                    if (c[index[i]][index[i]] < -small) {
+                        // there is at least one sufficiently negative diagonal element,
+                        // the covariance matrix is wrong
+                        throw new NotPositiveDefiniteMatrixException();
+                    }
+                }
+
+                // all remaining diagonal elements are close to zero,
+                // we consider we have found the rank of the covariance matrix
+                ++rank;
+                loop = false;
+
+            } else {
+
+                // transform the matrix
+                double sqrt = FastMath.sqrt(c[ir][ir]);
+                b[rank][rank] = sqrt;
+                double inverse = 1 / sqrt;
+                for (int i = rank + 1; i < order; ++i) {
+                    int ii = index[i];
+                    double e = inverse * c[ii][ir];
+                    b[i][rank] = e;
+                    c[ii][ii] -= e * e;
+                    for (int j = rank + 1; j < i; ++j) {
+                        int ij = index[j];
+                        double f = c[ii][ij] - e * b[j][rank];
+                        c[ii][ij] = f;
+                        c[ij][ii] = f;
+                    }
+                }
+
+                // prepare next iteration
+                loop = ++rank < order;
+
+            }
+
+        }
+
+        // build the root matrix
+        root = MatrixUtils.createRealMatrix(order, rank);
+        for (int i = 0; i < order; ++i) {
+            for (int j = 0; j < rank; ++j) {
+                root.setEntry(index[i], j, b[i][j]);
+            }
+        }
+
+    }
+
+    /** Generate a correlated random vector.
+     * @return a random vector as an array of double. The returned array
+     * is created at each call, the caller can do what it wants with it.
+     */
+    public double[] nextVector() {
+
+        // generate uncorrelated vector
+        for (int i = 0; i < rank; ++i) {
+            normalized[i] = generator.nextNormalizedDouble();
+        }
+
+        // compute correlated vector
+        double[] correlated = new double[mean.length];
+        for (int i = 0; i < correlated.length; ++i) {
+            correlated[i] = mean[i];
+            for (int j = 0; j < rank; ++j) {
+                correlated[i] += root.getEntry(i, j) * normalized[j];
+            }
+        }
+
+        return correlated;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/EmpiricalDistribution.java b/src/main/java/org/apache/commons/math/random/EmpiricalDistribution.java
new file mode 100644
index 0000000..7f08a06
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/EmpiricalDistribution.java
@@ -0,0 +1,133 @@
+/*
+ * 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.random;
+
+import java.io.IOException;
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.commons.math.stat.descriptive.StatisticalSummary;
+import org.apache.commons.math.stat.descriptive.SummaryStatistics;
+
+/**
+ * Represents an <a href="http://random.mat.sbg.ac.at/~ste/dipl/node11.html">
+ * empirical probability distribution</a> -- a probability distribution derived
+ * from observed data without making any assumptions about the functional form
+ * of the population distribution that the data come from.<p>
+ * Implementations of this interface maintain data structures, called
+ * <i>distribution digests</i>, that describe empirical distributions and
+ * support the following operations: <ul>
+ * <li>loading the distribution from a file of observed data values</li>
+ * <li>dividing the input data into "bin ranges" and reporting bin frequency
+ *     counts (data for histogram)</li>
+ * <li>reporting univariate statistics describing the full set of data values
+ *     as well as the observations within each bin</li>
+ * <li>generating random values from the distribution</li>
+ * </ul>
+ * Applications can use <code>EmpiricalDistribution</code> implementations to
+ * build grouped frequency histograms representing the input data or to
+ * generate random values "like" those in the input file -- i.e., the values
+ * generated will follow the distribution of the values in the file.</p>
+ *
+ * @version $Revision: 817128 $ $Date: 2009-09-21 03:30:53 +0200 (lun. 21 sept. 2009) $
+ */
+public interface EmpiricalDistribution {
+
+    /**
+     * Computes the empirical distribution from the provided
+     * array of numbers.
+     *
+     * @param dataArray the data array
+     */
+    void load(double[] dataArray);
+
+    /**
+     * Computes the empirical distribution from the input file.
+     *
+     * @param file the input file
+     * @throws IOException if an IO error occurs
+     */
+    void load(File file) throws IOException;
+
+    /**
+     * Computes the empirical distribution using data read from a URL.
+     *
+     * @param url url of the input file
+     * @throws IOException if an IO error occurs
+     */
+    void load(URL url) throws IOException;
+
+    /**
+     * Generates a random value from this distribution.
+     * <strong>Preconditions:</strong><ul>
+     * <li>the distribution must be loaded before invoking this method</li></ul>
+     * @return the random value.
+     *
+     * @throws IllegalStateException if the distribution has not been loaded
+     */
+    double getNextValue() throws IllegalStateException;
+
+
+    /**
+     * Returns a
+     * {@link org.apache.commons.math.stat.descriptive.StatisticalSummary}
+     * describing this distribution.
+     * <strong>Preconditions:</strong><ul>
+     * <li>the distribution must be loaded before invoking this method</li>
+     * </ul>
+     *
+     * @return the sample statistics
+     * @throws IllegalStateException if the distribution has not been loaded
+     */
+    StatisticalSummary getSampleStats() throws IllegalStateException;
+
+    /**
+     * Property indicating whether or not the distribution has been loaded.
+     *
+     * @return true if the distribution has been loaded
+     */
+    boolean isLoaded();
+
+     /**
+     * Returns the number of bins.
+     *
+     * @return the number of bins
+     */
+    int getBinCount();
+
+    /**
+     * Returns a list of
+     * {@link org.apache.commons.math.stat.descriptive.SummaryStatistics}
+     * containing statistics describing the values in each of the bins.  The
+     * List is indexed on the bin number.
+     *
+     * @return List of bin statistics
+     */
+    List<SummaryStatistics> getBinStats();
+
+    /**
+     * Returns the array of upper bounds for the bins.  Bins are: <br/>
+     * [min,upperBounds[0]],(upperBounds[0],upperBounds[1]],...,
+     *  (upperBounds[binCount-2], upperBounds[binCount-1] = max].
+     *
+     * @return array of bin upper bounds
+     */
+    double[] getUpperBounds();
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java b/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
new file mode 100644
index 0000000..a3ae8a7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
@@ -0,0 +1,479 @@
+/*
+ * 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.random;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.StatisticalSummary;
+import org.apache.commons.math.stat.descriptive.SummaryStatistics;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements <code>EmpiricalDistribution</code> interface.  This implementation
+ * uses what amounts to the
+ * <a href="http://nedwww.ipac.caltech.edu/level5/March02/Silverman/Silver2_6.html">
+ * Variable Kernel Method</a> with Gaussian smoothing:<p>
+ * <strong>Digesting the input file</strong>
+ * <ol><li>Pass the file once to compute min and max.</li>
+ * <li>Divide the range from min-max into <code>binCount</code> "bins."</li>
+ * <li>Pass the data file again, computing bin counts and univariate
+ *     statistics (mean, std dev.) for each of the bins </li>
+ * <li>Divide the interval (0,1) into subintervals associated with the bins,
+ *     with the length of a bin's subinterval proportional to its count.</li></ol>
+ * <strong>Generating random values from the distribution</strong><ol>
+ * <li>Generate a uniformly distributed value in (0,1) </li>
+ * <li>Select the subinterval to which the value belongs.
+ * <li>Generate a random Gaussian value with mean = mean of the associated
+ *     bin and std dev = std dev of associated bin.</li></ol></p><p>
+ *<strong>USAGE NOTES:</strong><ul>
+ *<li>The <code>binCount</code> is set by default to 1000.  A good rule of thumb
+ *    is to set the bin count to approximately the length of the input file divided
+ *    by 10. </li>
+ *<li>The input file <i>must</i> be a plain text file containing one valid numeric
+ *    entry per line.</li>
+ * </ul></p>
+ *
+ * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $
+ */
+public class EmpiricalDistributionImpl implements Serializable, EmpiricalDistribution {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 5729073523949762654L;
+
+    /** List of SummaryStatistics objects characterizing the bins */
+    private final List<SummaryStatistics> binStats;
+
+    /** Sample statistics */
+    private SummaryStatistics sampleStats = null;
+
+    /** Max loaded value */
+    private double max = Double.NEGATIVE_INFINITY;
+
+    /** Min loaded value */
+    private double min = Double.POSITIVE_INFINITY;
+
+    /** Grid size */
+    private double delta = 0d;
+
+    /** number of bins */
+    private final int binCount;
+
+    /** is the distribution loaded? */
+    private boolean loaded = false;
+
+    /** upper bounds of subintervals in (0,1) "belonging" to the bins */
+    private double[] upperBounds = null;
+
+    /** RandomData instance to use in repeated calls to getNext() */
+    private final RandomData randomData = new RandomDataImpl();
+
+    /**
+     * Creates a new EmpiricalDistribution with the default bin count.
+     */
+    public EmpiricalDistributionImpl() {
+        binCount = 1000;
+        binStats = new ArrayList<SummaryStatistics>();
+    }
+
+    /**
+     * Creates a new EmpiricalDistribution  with the specified bin count.
+     *
+     * @param binCount number of bins
+     */
+    public EmpiricalDistributionImpl(int binCount) {
+        this.binCount = binCount;
+        binStats = new ArrayList<SummaryStatistics>();
+    }
+
+     /**
+     * Computes the empirical distribution from the provided
+     * array of numbers.
+     *
+     * @param in the input data array
+     */
+    public void load(double[] in) {
+        DataAdapter da = new ArrayDataAdapter(in);
+        try {
+            da.computeStats();
+            fillBinStats(in);
+        } catch (IOException e) {
+            throw new MathRuntimeException(e);
+        }
+        loaded = true;
+
+    }
+
+    /**
+     * Computes the empirical distribution using data read from a URL.
+     * @param url  url of the input file
+     *
+     * @throws IOException if an IO error occurs
+     */
+    public void load(URL url) throws IOException {
+        BufferedReader in =
+            new BufferedReader(new InputStreamReader(url.openStream()));
+        try {
+            DataAdapter da = new StreamDataAdapter(in);
+            da.computeStats();
+            if (sampleStats.getN() == 0) {
+                throw MathRuntimeException.createEOFException(LocalizedFormats.URL_CONTAINS_NO_DATA,
+                                                              url);
+            }
+            in = new BufferedReader(new InputStreamReader(url.openStream()));
+            fillBinStats(in);
+            loaded = true;
+        } finally {
+           try {
+               in.close();
+           } catch (IOException ex) {
+               // ignore
+           }
+        }
+    }
+
+    /**
+     * Computes the empirical distribution from the input file.
+     *
+     * @param file the input file
+     * @throws IOException if an IO error occurs
+     */
+    public void load(File file) throws IOException {
+        BufferedReader in = new BufferedReader(new FileReader(file));
+        try {
+            DataAdapter da = new StreamDataAdapter(in);
+            da.computeStats();
+            in = new BufferedReader(new FileReader(file));
+            fillBinStats(in);
+            loaded = true;
+        } finally {
+            try {
+                in.close();
+            } catch (IOException ex) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Provides methods for computing <code>sampleStats</code> and
+     * <code>beanStats</code> abstracting the source of data.
+     */
+    private abstract class DataAdapter{
+
+        /**
+         * Compute bin stats.
+         *
+         * @throws IOException  if an error occurs computing bin stats
+         */
+        public abstract void computeBinStats() throws IOException;
+
+        /**
+         * Compute sample statistics.
+         *
+         * @throws IOException if an error occurs computing sample stats
+         */
+        public abstract void computeStats() throws IOException;
+
+    }
+
+    /**
+     * Factory of <code>DataAdapter</code> objects. For every supported source
+     * of data (array of doubles, file, etc.) an instance of the proper object
+     * is returned.
+     */
+    private class DataAdapterFactory{
+        /**
+         * Creates a DataAdapter from a data object
+         *
+         * @param in object providing access to the data
+         * @return DataAdapter instance
+         */
+        public DataAdapter getAdapter(Object in) {
+            if (in instanceof BufferedReader) {
+                BufferedReader inputStream = (BufferedReader) in;
+                return new StreamDataAdapter(inputStream);
+            } else if (in instanceof double[]) {
+                double[] inputArray = (double[]) in;
+                return new ArrayDataAdapter(inputArray);
+            } else {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.INPUT_DATA_FROM_UNSUPPORTED_DATASOURCE,
+                      in.getClass().getName(),
+                      BufferedReader.class.getName(), double[].class.getName());
+            }
+        }
+    }
+    /**
+     * <code>DataAdapter</code> for data provided through some input stream
+     */
+    private class StreamDataAdapter extends DataAdapter{
+
+        /** Input stream providing access to the data */
+        private BufferedReader inputStream;
+
+        /**
+         * Create a StreamDataAdapter from a BufferedReader
+         *
+         * @param in BufferedReader input stream
+         */
+        public StreamDataAdapter(BufferedReader in){
+            super();
+            inputStream = in;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void computeBinStats() throws IOException {
+            String str = null;
+            double val = 0.0d;
+            while ((str = inputStream.readLine()) != null) {
+                val = Double.parseDouble(str);
+                SummaryStatistics stats = binStats.get(findBin(val));
+                stats.addValue(val);
+            }
+
+            inputStream.close();
+            inputStream = null;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void computeStats() throws IOException {
+            String str = null;
+            double val = 0.0;
+            sampleStats = new SummaryStatistics();
+            while ((str = inputStream.readLine()) != null) {
+                val = Double.valueOf(str).doubleValue();
+                sampleStats.addValue(val);
+            }
+            inputStream.close();
+            inputStream = null;
+        }
+    }
+
+    /**
+     * <code>DataAdapter</code> for data provided as array of doubles.
+     */
+    private class ArrayDataAdapter extends DataAdapter {
+
+        /** Array of input  data values */
+        private double[] inputArray;
+
+        /**
+         * Construct an ArrayDataAdapter from a double[] array
+         *
+         * @param in double[] array holding the data
+         */
+        public ArrayDataAdapter(double[] in){
+            super();
+            inputArray = in;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void computeStats() throws IOException {
+            sampleStats = new SummaryStatistics();
+            for (int i = 0; i < inputArray.length; i++) {
+                sampleStats.addValue(inputArray[i]);
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void computeBinStats() throws IOException {
+            for (int i = 0; i < inputArray.length; i++) {
+                SummaryStatistics stats =
+                    binStats.get(findBin(inputArray[i]));
+                stats.addValue(inputArray[i]);
+            }
+        }
+    }
+
+    /**
+     * Fills binStats array (second pass through data file).
+     *
+     * @param in object providing access to the data
+     * @throws IOException  if an IO error occurs
+     */
+    private void fillBinStats(Object in) throws IOException {
+        // Set up grid
+        min = sampleStats.getMin();
+        max = sampleStats.getMax();
+        delta = (max - min)/(Double.valueOf(binCount)).doubleValue();
+
+        // Initialize binStats ArrayList
+        if (!binStats.isEmpty()) {
+            binStats.clear();
+        }
+        for (int i = 0; i < binCount; i++) {
+            SummaryStatistics stats = new SummaryStatistics();
+            binStats.add(i,stats);
+        }
+
+        // Filling data in binStats Array
+        DataAdapterFactory aFactory = new DataAdapterFactory();
+        DataAdapter da = aFactory.getAdapter(in);
+        da.computeBinStats();
+
+        // Assign upperBounds based on bin counts
+        upperBounds = new double[binCount];
+        upperBounds[0] =
+        ((double) binStats.get(0).getN()) / (double) sampleStats.getN();
+        for (int i = 1; i < binCount-1; i++) {
+            upperBounds[i] = upperBounds[i-1] +
+            ((double) binStats.get(i).getN()) / (double) sampleStats.getN();
+        }
+        upperBounds[binCount-1] = 1.0d;
+    }
+
+    /**
+     * Returns the index of the bin to which the given value belongs
+     *
+     * @param value  the value whose bin we are trying to find
+     * @return the index of the bin containing the value
+     */
+    private int findBin(double value) {
+        return FastMath.min(
+                FastMath.max((int) FastMath.ceil((value- min) / delta) - 1, 0),
+                binCount - 1);
+        }
+
+    /**
+     * Generates a random value from this distribution.
+     *
+     * @return the random value.
+     * @throws IllegalStateException if the distribution has not been loaded
+     */
+    public double getNextValue() throws IllegalStateException {
+
+        if (!loaded) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.DISTRIBUTION_NOT_LOADED);
+        }
+
+        // Start with a uniformly distributed random number in (0,1)
+        double x = FastMath.random();
+
+        // Use this to select the bin and generate a Gaussian within the bin
+        for (int i = 0; i < binCount; i++) {
+           if (x <= upperBounds[i]) {
+               SummaryStatistics stats = binStats.get(i);
+               if (stats.getN() > 0) {
+                   if (stats.getStandardDeviation() > 0) {  // more than one obs
+                        return randomData.nextGaussian
+                            (stats.getMean(),stats.getStandardDeviation());
+                   } else {
+                       return stats.getMean(); // only one obs in bin
+                   }
+               }
+           }
+        }
+        throw new MathRuntimeException(LocalizedFormats.NO_BIN_SELECTED);
+    }
+
+    /**
+     * Returns a {@link StatisticalSummary} describing this distribution.
+     * <strong>Preconditions:</strong><ul>
+     * <li>the distribution must be loaded before invoking this method</li></ul>
+     *
+     * @return the sample statistics
+     * @throws IllegalStateException if the distribution has not been loaded
+     */
+    public StatisticalSummary getSampleStats() {
+        return sampleStats;
+    }
+
+    /**
+     * Returns the number of bins.
+     *
+     * @return the number of bins.
+     */
+    public int getBinCount() {
+        return binCount;
+    }
+
+    /**
+     * Returns a List of {@link SummaryStatistics} instances containing
+     * statistics describing the values in each of the bins.  The list is
+     * indexed on the bin number.
+     *
+     * @return List of bin statistics.
+     */
+    public List<SummaryStatistics> getBinStats() {
+        return binStats;
+    }
+
+    /**
+     * <p>Returns a fresh copy of the array of upper bounds for the bins.
+     * Bins are: <br/>
+     * [min,upperBounds[0]],(upperBounds[0],upperBounds[1]],...,
+     *  (upperBounds[binCount-2], upperBounds[binCount-1] = max].</p>
+     *
+     * <p>Note: In versions 1.0-2.0 of commons-math, this method
+     * incorrectly returned the array of probability generator upper
+     * bounds now returned by {@link #getGeneratorUpperBounds()}.</p>
+     *
+     * @return array of bin upper bounds
+     * @since 2.1
+     */
+    public double[] getUpperBounds() {
+        double[] binUpperBounds = new double[binCount];
+        binUpperBounds[0] = min + delta;
+        for (int i = 1; i < binCount - 1; i++) {
+            binUpperBounds[i] = binUpperBounds[i-1] + delta;
+        }
+        binUpperBounds[binCount - 1] = max;
+        return binUpperBounds;
+    }
+
+    /**
+     * <p>Returns a fresh copy of the array of upper bounds of the subintervals
+     * of [0,1] used in generating data from the empirical distribution.
+     * Subintervals correspond to bins with lengths proportional to bin counts.</p>
+     *
+     * <p>In versions 1.0-2.0 of commons-math, this array was (incorrectly) returned
+     * by {@link #getUpperBounds()}.</p>
+     *
+     * @since 2.1
+     * @return array of upper bounds of subintervals used in data generation
+     */
+    public double[] getGeneratorUpperBounds() {
+        int len = upperBounds.length;
+        double[] out = new double[len];
+        System.arraycopy(upperBounds, 0, out, 0, len);
+        return out;
+    }
+
+    /**
+     * Property indicating whether or not the distribution has been loaded.
+     *
+     * @return true if the distribution has been loaded
+     */
+    public boolean isLoaded() {
+        return loaded;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/random/GaussianRandomGenerator.java b/src/main/java/org/apache/commons/math/random/GaussianRandomGenerator.java
new file mode 100644
index 0000000..6bd9775
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/GaussianRandomGenerator.java
@@ -0,0 +1,47 @@
+/*
+ * 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.random;
+
+/**
+ * This class is a gaussian normalized random generator for scalars.
+ * <p>This class is a simple wrapper around the {@link
+ * RandomGenerator#nextGaussian} method.</p>
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ */
+
+public class GaussianRandomGenerator implements NormalizedRandomGenerator {
+
+    /** Underlying generator. */
+    private final RandomGenerator generator;
+
+    /** Create a new generator.
+     * @param generator underlying random generator to use
+     */
+    public GaussianRandomGenerator(final RandomGenerator generator) {
+        this.generator = generator;
+    }
+
+    /** Generate a random scalar with null mean and unit standard deviation.
+     * @return a random scalar with null mean and unit standard deviation
+     */
+    public double nextNormalizedDouble() {
+        return generator.nextGaussian();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/JDKRandomGenerator.java b/src/main/java/org/apache/commons/math/random/JDKRandomGenerator.java
new file mode 100644
index 0000000..573ef61
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/JDKRandomGenerator.java
@@ -0,0 +1,50 @@
+/*
+ * 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.random;
+
+import java.util.Random;
+
+/**
+ * Extension of <code>java.util.Random</code> to implement
+ * {@link RandomGenerator}.
+ *
+ * @since 1.1
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class JDKRandomGenerator extends Random implements RandomGenerator {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -7745277476784028798L;
+
+    /** {@inheritDoc} */
+    public void setSeed(int seed) {
+        setSeed((long) seed);
+    }
+
+    /** {@inheritDoc} */
+    public void setSeed(int[] seed) {
+        // the following number is the largest prime that fits in 32 bits (it is 2^32 - 5)
+        final long prime = 4294967291l;
+
+        long combined = 0l;
+        for (int s : seed) {
+            combined = combined * prime + s;
+        }
+        setSeed(combined);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/MersenneTwister.java b/src/main/java/org/apache/commons/math/random/MersenneTwister.java
new file mode 100644
index 0000000..6a6fadd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/MersenneTwister.java
@@ -0,0 +1,259 @@
+/*
+ * 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.random;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/** This class implements a powerful pseudo-random number generator
+ * developed by Makoto Matsumoto and Takuji Nishimura during
+ * 1996-1997.
+
+ * <p>This generator features an extremely long period
+ * (2<sup>19937</sup>-1) and 623-dimensional equidistribution up to 32
+ * bits accuracy. The home page for this generator is located at <a
+ * href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">
+ * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html</a>.</p>
+
+ * <p>This generator is described in a paper by Makoto Matsumoto and
+ * Takuji Nishimura in 1998: <a
+ * href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.pdf">Mersenne
+ * Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random
+ * Number Generator</a>, ACM Transactions on Modeling and Computer
+ * Simulation, Vol. 8, No. 1, January 1998, pp 3--30</p>
+
+ * <p>This class is mainly a Java port of the 2002-01-26 version of
+ * the generator written in C by Makoto Matsumoto and Takuji
+ * Nishimura. Here is their original copyright:</p>
+
+ * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+ * <tr><td>Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ *     All rights reserved.</td></tr>
+
+ * <tr><td>Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * <ol>
+ *   <li>Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.</li>
+ *   <li>Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.</li>
+ *   <li>The names of its contributors may not be used to endorse or promote
+ *       products derived from this software without specific prior written
+ *       permission.</li>
+ * </ol></td></tr>
+
+ * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.</strong></td></tr>
+ * </table>
+
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+
+ */
+public class MersenneTwister extends BitsStreamGenerator implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 8661194735290153518L;
+
+    /** Size of the bytes pool. */
+    private static final int   N     = 624;
+
+    /** Period second parameter. */
+    private static final int   M     = 397;
+
+    /** X * MATRIX_A for X = {0, 1}. */
+    private static final int[] MAG01 = { 0x0, 0x9908b0df };
+
+    /** Bytes pool. */
+    private int[] mt;
+
+    /** Current index in the bytes pool. */
+    private int   mti;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public MersenneTwister() {
+        mt = new int[N];
+        setSeed(System.currentTimeMillis());
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public MersenneTwister(int seed) {
+        mt = new int[N];
+        setSeed(seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public MersenneTwister(int[] seed) {
+        mt = new int[N];
+        setSeed(seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public MersenneTwister(long seed) {
+        mt = new int[N];
+        setSeed(seed);
+    }
+
+    /** Reinitialize the generator as if just built with the given int seed.
+     * <p>The state of the generator is exactly the same as a new
+     * generator built with the same seed.</p>
+     * @param seed the initial seed (32 bits integer)
+     */
+    @Override
+    public void setSeed(int seed) {
+        // we use a long masked by 0xffffffffL as a poor man unsigned int
+        long longMT = seed;
+        mt[0]= (int) longMT;
+        for (mti = 1; mti < N; ++mti) {
+            // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.
+            // initializer from the 2002-01-09 C version by Makoto Matsumoto
+            longMT = (1812433253l * (longMT ^ (longMT >> 30)) + mti) & 0xffffffffL;
+            mt[mti]= (int) longMT;
+        }
+    }
+
+    /** Reinitialize the generator as if just built with the given int array seed.
+     * <p>The state of the generator is exactly the same as a new
+     * generator built with the same seed.</p>
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    @Override
+    public void setSeed(int[] seed) {
+
+        if (seed == null) {
+            setSeed(System.currentTimeMillis());
+            return;
+        }
+
+        setSeed(19650218);
+        int i = 1;
+        int j = 0;
+
+        for (int k = FastMath.max(N, seed.length); k != 0; k--) {
+            long l0 = (mt[i] & 0x7fffffffl)   | ((mt[i]   < 0) ? 0x80000000l : 0x0l);
+            long l1 = (mt[i-1] & 0x7fffffffl) | ((mt[i-1] < 0) ? 0x80000000l : 0x0l);
+            long l  = (l0 ^ ((l1 ^ (l1 >> 30)) * 1664525l)) + seed[j] + j; // non linear
+            mt[i]   = (int) (l & 0xffffffffl);
+            i++; j++;
+            if (i >= N) {
+                mt[0] = mt[N - 1];
+                i = 1;
+            }
+            if (j >= seed.length) {
+                j = 0;
+            }
+        }
+
+        for (int k = N - 1; k != 0; k--) {
+            long l0 = (mt[i] & 0x7fffffffl)   | ((mt[i]   < 0) ? 0x80000000l : 0x0l);
+            long l1 = (mt[i-1] & 0x7fffffffl) | ((mt[i-1] < 0) ? 0x80000000l : 0x0l);
+            long l  = (l0 ^ ((l1 ^ (l1 >> 30)) * 1566083941l)) - i; // non linear
+            mt[i]   = (int) (l & 0xffffffffL);
+            i++;
+            if (i >= N) {
+                mt[0] = mt[N - 1];
+                i = 1;
+            }
+        }
+
+        mt[0] = 0x80000000; // MSB is 1; assuring non-zero initial array
+
+    }
+
+    /** Reinitialize the generator as if just built with the given long seed.
+     * <p>The state of the generator is exactly the same as a new
+     * generator built with the same seed.</p>
+     * @param seed the initial seed (64 bits integer)
+     */
+    @Override
+    public void setSeed(long seed) {
+        setSeed(new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) });
+    }
+
+    /** Generate next pseudorandom number.
+     * <p>This method is the core generation algorithm. It is used by all the
+     * public generation methods for the various primitive types {@link
+     * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()},
+     * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()},
+     * {@link #next(int)} and {@link #nextLong()}.</p>
+     * @param bits number of random bits to produce
+     * @return random bits generated
+     */
+    @Override
+    protected int next(int bits) {
+
+        int y;
+
+        if (mti >= N) { // generate N words at one time
+            int mtNext = mt[0];
+            for (int k = 0; k < N - M; ++k) {
+                int mtCurr = mtNext;
+                mtNext = mt[k + 1];
+                y = (mtCurr & 0x80000000) | (mtNext & 0x7fffffff);
+                mt[k] = mt[k + M] ^ (y >>> 1) ^ MAG01[y & 0x1];
+            }
+            for (int k = N - M; k < N - 1; ++k) {
+                int mtCurr = mtNext;
+                mtNext = mt[k + 1];
+                y = (mtCurr & 0x80000000) | (mtNext & 0x7fffffff);
+                mt[k] = mt[k + (M - N)] ^ (y >>> 1) ^ MAG01[y & 0x1];
+            }
+            y = (mtNext & 0x80000000) | (mt[0] & 0x7fffffff);
+            mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ MAG01[y & 0x1];
+
+            mti = 0;
+        }
+
+        y = mt[mti++];
+
+        // tempering
+        y ^=  y >>> 11;
+        y ^= (y <<   7) & 0x9d2c5680;
+        y ^= (y <<  15) & 0xefc60000;
+        y ^=  y >>> 18;
+
+        return y >>> (32 - bits);
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/NormalizedRandomGenerator.java b/src/main/java/org/apache/commons/math/random/NormalizedRandomGenerator.java
new file mode 100644
index 0000000..0f13b81
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/NormalizedRandomGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.random;
+
+/**
+ * This interface represent a normalized random generator for
+ * scalars.
+ * Normalized generator provide null mean and unit standard deviation scalars.
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ * @since 1.2
+ */
+public interface NormalizedRandomGenerator {
+
+  /** Generate a random scalar with null mean and unit standard deviation.
+   * <p>This method does <strong>not</strong> specify the shape of the
+   * distribution, it is the implementing class that provides it. The
+   * only contract here is to generate numbers with null mean and unit
+   * standard deviation.</p>
+   * @return a random scalar with null mean and unit standard deviation
+   */
+  double nextNormalizedDouble();
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/RandomAdaptor.java b/src/main/java/org/apache/commons/math/random/RandomAdaptor.java
new file mode 100644
index 0000000..8091a48
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/RandomAdaptor.java
@@ -0,0 +1,198 @@
+/*
+ * 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.random;
+
+import java.util.Random;
+
+/**
+ * Extension of <code>java.util.Random</code> wrapping a
+ * {@link RandomGenerator}.
+ *
+ * @since 1.1
+ * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $
+ */
+public class RandomAdaptor extends Random implements RandomGenerator {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 2306581345647615033L;
+
+    /** Wrapped randomGenerator instance */
+    private final RandomGenerator randomGenerator;
+
+    /**
+     * Prevent instantiation without a generator argument
+     */
+    @SuppressWarnings("unused")
+    private RandomAdaptor() { randomGenerator = null; }
+
+    /**
+     * Construct a RandomAdaptor wrapping the supplied RandomGenerator.
+     *
+     * @param randomGenerator  the wrapped generator
+     */
+    public RandomAdaptor(RandomGenerator randomGenerator) {
+        this.randomGenerator = randomGenerator;
+    }
+
+    /**
+     * Factory method to create a <code>Random</code> using the supplied
+     * <code>RandomGenerator</code>.
+     *
+     * @param randomGenerator  wrapped RandomGenerator instance
+     * @return a Random instance wrapping the RandomGenerator
+     */
+    public static Random createAdaptor(RandomGenerator randomGenerator) {
+        return new RandomAdaptor(randomGenerator);
+    }
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed
+     * <code>boolean</code> value from this random number generator's
+     * sequence.
+     *
+     * @return  the next pseudorandom, uniformly distributed
+     * <code>boolean</code> value from this random number generator's
+     * sequence
+     */
+    @Override
+    public boolean nextBoolean() {
+        return randomGenerator.nextBoolean();
+    }
+
+     /**
+     * Generates random bytes and places them into a user-supplied
+     * byte array.  The number of random bytes produced is equal to
+     * the length of the byte array.
+     *
+     * @param bytes the non-null byte array in which to put the
+     * random bytes
+     */
+    @Override
+    public void nextBytes(byte[] bytes) {
+        randomGenerator.nextBytes(bytes);
+    }
+
+     /**
+     * Returns the next pseudorandom, uniformly distributed
+     * <code>double</code> value between <code>0.0</code> and
+     * <code>1.0</code> from this random number generator's sequence.
+     *
+     * @return  the next pseudorandom, uniformly distributed
+     *  <code>double</code> value between <code>0.0</code> and
+     *  <code>1.0</code> from this random number generator's sequence
+     */
+    @Override
+    public double nextDouble() {
+        return randomGenerator.nextDouble();
+    }
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>float</code>
+     * value between <code>0.0</code> and <code>1.0</code> from this random
+     * number generator's sequence.
+     *
+     * @return  the next pseudorandom, uniformly distributed <code>float</code>
+     * value between <code>0.0</code> and <code>1.0</code> from this
+     * random number generator's sequence
+     */
+    @Override
+    public float nextFloat() {
+        return randomGenerator.nextFloat();
+    }
+
+    /**
+     * Returns the next pseudorandom, Gaussian ("normally") distributed
+     * <code>double</code> value with mean <code>0.0</code> and standard
+     * deviation <code>1.0</code> from this random number generator's sequence.
+     *
+     * @return  the next pseudorandom, Gaussian ("normally") distributed
+     * <code>double</code> value with mean <code>0.0</code> and
+     * standard deviation <code>1.0</code> from this random number
+     *  generator's sequence
+     */
+    @Override
+    public double nextGaussian() {
+        return randomGenerator.nextGaussian();
+    }
+
+     /**
+     * Returns the next pseudorandom, uniformly distributed <code>int</code>
+     * value from this random number generator's sequence.
+     * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values
+     * should be produced with  (approximately) equal probability.
+     *
+     * @return the next pseudorandom, uniformly distributed <code>int</code>
+     *  value from this random number generator's sequence
+     */
+    @Override
+    public int nextInt() {
+        return randomGenerator.nextInt();
+    }
+
+    /**
+     * Returns a pseudorandom, uniformly distributed <tt>int</tt> value
+     * between 0 (inclusive) and the specified value (exclusive), drawn from
+     * this random number generator's sequence.
+     *
+     * @param n the bound on the random number to be returned.  Must be
+     * positive.
+     * @return  a pseudorandom, uniformly distributed <tt>int</tt>
+     * value between 0 (inclusive) and n (exclusive).
+     * @throws IllegalArgumentException  if n is not positive.
+     */
+    @Override
+    public int nextInt(int n) {
+        return randomGenerator.nextInt(n);
+    }
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>long</code>
+     * value from this random number generator's sequence.  All
+     * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values
+     * should be produced with (approximately) equal probability.
+     *
+     * @return  the next pseudorandom, uniformly distributed <code>long</code>
+     *value from this random number generator's sequence
+     */
+    @Override
+    public long nextLong() {
+        return randomGenerator.nextLong();
+    }
+
+    /** {@inheritDoc} */
+    public void setSeed(int seed) {
+        if (randomGenerator != null) {  // required to avoid NPE in constructor
+            randomGenerator.setSeed(seed);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void setSeed(int[] seed) {
+        if (randomGenerator != null) {  // required to avoid NPE in constructor
+            randomGenerator.setSeed(seed);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setSeed(long seed) {
+        if (randomGenerator != null) {  // required to avoid NPE in constructor
+            randomGenerator.setSeed(seed);
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/RandomData.java b/src/main/java/org/apache/commons/math/random/RandomData.java
new file mode 100644
index 0000000..0fc5136
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/RandomData.java
@@ -0,0 +1,272 @@
+/*
+ * 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.random;
+import java.util.Collection;
+
+/**
+ * Random data generation utilities.
+ * @version $Revision: 780975 $ $Date: 2009-06-02 11:05:37 +0200 (mar. 02 juin 2009) $
+ */
+public interface RandomData {
+    /**
+     * Generates a random string of hex characters of length
+     * <code>len</code>.
+     * <p>
+     * The generated string will be random, but not cryptographically
+     * secure. To generate cryptographically secure strings, use
+     * <code>nextSecureHexString</code></p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>len > 0</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     *
+     * @param len the length of the string to be generated
+     * @return random string of hex characters of length <code>len</code>
+     */
+    String nextHexString(int len);
+
+    /**
+     * Generates a uniformly distributed random integer between
+     * <code>lower</code> and <code>upper</code> (endpoints included).
+     * <p>
+     * The generated integer will be random, but not cryptographically secure.
+     * To generate cryptographically secure integer sequences, use
+     * <code>nextSecureInt</code>.</p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>lower < upper</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     *
+     * @param lower lower bound for generated integer
+     * @param upper upper bound for generated integer
+     * @return a random integer greater than or equal to <code>lower</code>
+     * and less than or equal to <code>upper</code>.
+     */
+    int nextInt(int lower, int upper);
+
+    /**
+     * Generates a uniformly distributed random long integer between
+     * <code>lower</code> and <code>upper</code> (endpoints included).
+     * <p>
+     * The generated long integer values will be random, but not
+     * cryptographically secure.
+     * To generate cryptographically secure sequences of longs, use
+     * <code>nextSecureLong</code></p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>lower < upper</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     *
+     * @param lower lower bound for generated integer
+     * @param upper upper bound for generated integer
+     * @return a random integer greater than or equal to <code>lower</code>
+     * and less than or equal to <code>upper</code>.
+     */
+    long nextLong(long lower, long upper);
+
+    /**
+     * Generates a random string of hex characters from a secure random
+     * sequence.
+     * <p>
+     * If cryptographic security is not required,
+     * use <code>nextHexString()</code>.</p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>len > 0</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     * @param len length of return string
+     * @return the random hex string
+     */
+    String nextSecureHexString(int len);
+
+    /**
+     * Generates a uniformly distributed random integer between
+     * <code>lower</code> and <code>upper</code> (endpoints included)
+     * from a secure random sequence.
+     * <p>
+     * Sequences of integers generated using this method will be
+     * cryptographically secure. If cryptographic security is not required,
+     * <code>nextInt</code> should be used instead of this method.</p>
+     * <p>
+     * <strong>Definition</strong>:
+     * <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudo-random_number_generator">
+     * Secure Random Sequence</a></p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>lower < upper</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     *
+     * @param lower lower bound for generated integer
+     * @param upper upper bound for generated integer
+     * @return a random integer greater than or equal to <code>lower</code>
+     * and less than or equal to <code>upper</code>.
+     */
+    int nextSecureInt(int lower, int upper);
+
+    /**
+     * Generates a random long integer between <code>lower</code>
+     * and <code>upper</code> (endpoints included).
+     * <p>
+     * Sequences of long values generated using this method will be
+     * cryptographically secure. If cryptographic security is not required,
+     * <code>nextLong</code> should be used instead of this method.</p>
+     * <p>
+     * <strong>Definition</strong>:
+     * <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudo-random_number_generator">
+     * Secure Random Sequence</a></p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>lower < upper</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     *
+     * @param lower lower bound for generated integer
+     * @param upper upper bound for generated integer
+     * @return a long integer greater than or equal to <code>lower</code>
+     * and less than or equal to <code>upper</code>.
+     */
+    long nextSecureLong(long lower, long upper);
+
+    /**
+     * Generates a random value from the Poisson distribution with
+     * the given mean.
+     * <p>
+     * <strong>Definition</strong>:
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda366j.htm">
+     * Poisson Distribution</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The specified mean <i>must</i> be positive (otherwise an
+     *     IllegalArgumentException is thrown.)</li>
+     * </ul></p>
+     * @param mean Mean of the distribution
+     * @return poisson deviate with the specified mean
+     */
+    long nextPoisson(double mean);
+
+    /**
+     * Generates a random value from the
+     * Normal (or Gaussian) distribution with the given mean
+     * and standard deviation.
+     * <p>
+     * <strong>Definition</strong>:
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm">
+     * Normal Distribution</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li><code>sigma > 0</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     * @param mu Mean of the distribution
+     * @param sigma Standard deviation of the distribution
+     * @return random value from Gaussian distribution with mean = mu,
+     * standard deviation = sigma
+     */
+    double nextGaussian(double mu, double sigma);
+
+    /**
+     * Generates a random value from the exponential distribution
+     * with expected value = <code>mean</code>.
+     * <p>
+     * <strong>Definition</strong>:
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3667.htm">
+     * Exponential Distribution</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li><code>mu >= 0</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     * @param mean Mean of the distribution
+     * @return random value from exponential distribution
+     */
+    double nextExponential(double mean);
+
+    /**
+     * Generates a uniformly distributed random value from the open interval
+     * (<code>lower</code>,<code>upper</code>) (i.e., endpoints excluded).
+     * <p>
+     * <strong>Definition</strong>:
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">
+     * Uniform Distribution</a> <code>lower</code> and
+     * <code>upper - lower</code> are the
+     * <a href = "http://www.itl.nist.gov/div898/handbook/eda/section3/eda364.htm">
+     * location and scale parameters</a>, respectively.</p>
+     * <p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>lower < upper</code> (otherwise an IllegalArgumentException
+     *     is thrown.)</li>
+     * </ul></p>
+     *
+     * @param lower lower endpoint of the interval of support
+     * @param upper upper endpoint of the interval of support
+     * @return uniformly distributed random value between lower
+     * and upper (exclusive)
+     */
+    double nextUniform(double lower, double upper);
+
+    /**
+     * Generates an integer array of length <code>k</code> whose entries
+     * are selected randomly, without repetition, from the integers <code>
+     * 0 through n-1</code> (inclusive).
+     * <p>
+     * Generated arrays represent permutations
+     * of <code>n</code> taken <code>k</code> at a time.</p>
+     * <p>
+     * <strong>Preconditions:</strong><ul>
+     * <li> <code>k <= n</code></li>
+     * <li> <code>n > 0</code> </li>
+     * </ul>
+     * If the preconditions are not met, an IllegalArgumentException is
+     * thrown.</p>
+     *
+     * @param n domain of the permutation
+     * @param k size of the permutation
+     * @return random k-permutation of n
+     */
+    int[] nextPermutation(int n, int k);
+
+    /**
+     * Returns an array of <code>k</code> objects selected randomly
+     * from the Collection <code>c</code>.
+     * <p>
+     * Sampling from <code>c</code>
+     * is without replacement; but if <code>c</code> contains identical
+     * objects, the sample may include repeats.  If all elements of <code>
+     * c</code> are distinct, the resulting object array represents a
+     * <a href="http://rkb.home.cern.ch/rkb/AN16pp/node250.html#SECTION0002500000000000000000">
+     * Simple Random Sample</a> of size
+     * <code>k</code> from the elements of <code>c</code>.</p>
+     * <p>
+     * <strong>Preconditions:</strong><ul>
+     * <li> k must be less than or equal to the size of c </li>
+     * <li> c must not be empty </li>
+     * </ul>
+     * If the preconditions are not met, an IllegalArgumentException is
+     * thrown.</p>
+     *
+     * @param c collection to be sampled
+     * @param k size of the sample
+     * @return random sample of k elements from c
+     */
+    Object[] nextSample(Collection<?> c, int k);
+}
diff --git a/src/main/java/org/apache/commons/math/random/RandomDataImpl.java b/src/main/java/org/apache/commons/math/random/RandomDataImpl.java
new file mode 100644
index 0000000..e9ccab7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/RandomDataImpl.java
@@ -0,0 +1,966 @@
+/*
+ * 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.random;
+
+import java.io.Serializable;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
+import java.util.Collection;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.distribution.BetaDistributionImpl;
+import org.apache.commons.math.distribution.BinomialDistributionImpl;
+import org.apache.commons.math.distribution.CauchyDistributionImpl;
+import org.apache.commons.math.distribution.ChiSquaredDistributionImpl;
+import org.apache.commons.math.distribution.ContinuousDistribution;
+import org.apache.commons.math.distribution.FDistributionImpl;
+import org.apache.commons.math.distribution.GammaDistributionImpl;
+import org.apache.commons.math.distribution.HypergeometricDistributionImpl;
+import org.apache.commons.math.distribution.IntegerDistribution;
+import org.apache.commons.math.distribution.PascalDistributionImpl;
+import org.apache.commons.math.distribution.TDistributionImpl;
+import org.apache.commons.math.distribution.WeibullDistributionImpl;
+import org.apache.commons.math.distribution.ZipfDistributionImpl;
+import org.apache.commons.math.exception.MathInternalError;
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+import org.apache.commons.math.exception.NumberIsTooLargeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * Implements the {@link RandomData} interface using a {@link RandomGenerator}
+ * instance to generate non-secure data and a {@link java.security.SecureRandom}
+ * instance to provide data for the <code>nextSecureXxx</code> methods. If no
+ * <code>RandomGenerator</code> is provided in the constructor, the default is
+ * to use a generator based on {@link java.util.Random}. To plug in a different
+ * implementation, either implement <code>RandomGenerator</code> directly or
+ * extend {@link AbstractRandomGenerator}.
+ * <p>
+ * Supports reseeding the underlying pseudo-random number generator (PRNG). The
+ * <code>SecurityProvider</code> and <code>Algorithm</code> used by the
+ * <code>SecureRandom</code> instance can also be reset.
+ * </p>
+ * <p>
+ * For details on the default PRNGs, see {@link java.util.Random} and
+ * {@link java.security.SecureRandom}.
+ * </p>
+ * <p>
+ * <strong>Usage Notes</strong>:
+ * <ul>
+ * <li>
+ * Instance variables are used to maintain <code>RandomGenerator</code> and
+ * <code>SecureRandom</code> instances used in data generation. Therefore, to
+ * generate a random sequence of values or strings, you should use just
+ * <strong>one</strong> <code>RandomDataImpl</code> instance repeatedly.</li>
+ * <li>
+ * The "secure" methods are *much* slower. These should be used only when a
+ * cryptographically secure random sequence is required. A secure random
+ * sequence is a sequence of pseudo-random values which, in addition to being
+ * well-dispersed (so no subsequence of values is an any more likely than other
+ * subsequence of the the same length), also has the additional property that
+ * knowledge of values generated up to any point in the sequence does not make
+ * it any easier to predict subsequent values.</li>
+ * <li>
+ * When a new <code>RandomDataImpl</code> is created, the underlying random
+ * number generators are <strong>not</strong> initialized. If you do not
+ * explicitly seed the default non-secure generator, it is seeded with the
+ * current time in milliseconds on first use. The same holds for the secure
+ * generator. If you provide a <code>RandomGenerator</code> to the constructor,
+ * however, this generator is not reseeded by the constructor nor is it reseeded
+ * on first use.</li>
+ * <li>
+ * The <code>reSeed</code> and <code>reSeedSecure</code> methods delegate to the
+ * corresponding methods on the underlying <code>RandomGenerator</code> and
+ * <code>SecureRandom</code> instances. Therefore, <code>reSeed(long)</code>
+ * fully resets the initial state of the non-secure random number generator (so
+ * that reseeding with a specific value always results in the same subsequent
+ * random sequence); whereas reSeedSecure(long) does <strong>not</strong>
+ * reinitialize the secure random number generator (so secure sequences started
+ * with calls to reseedSecure(long) won't be identical).</li>
+ * <li>
+ * This implementation is not synchronized.
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $
+ */
+public class RandomDataImpl implements RandomData, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -626730818244969716L;
+
+    /** underlying random number generator */
+    private RandomGenerator rand = null;
+
+    /** underlying secure random number generator */
+    private SecureRandom secRand = null;
+
+    /**
+     * Construct a RandomDataImpl.
+     */
+    public RandomDataImpl() {
+    }
+
+    /**
+     * Construct a RandomDataImpl using the supplied {@link RandomGenerator} as
+     * the source of (non-secure) random data.
+     *
+     * @param rand
+     *            the source of (non-secure) random data
+     * @since 1.1
+     */
+    public RandomDataImpl(RandomGenerator rand) {
+        super();
+        this.rand = rand;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * <strong>Algorithm Description:</strong> hex strings are generated using a
+     * 2-step process.
+     * <ol>
+     * <li>
+     * len/2+1 binary bytes are generated using the underlying Random</li>
+     * <li>
+     * Each binary byte is translated into 2 hex digits</li>
+     * </ol>
+     * </p>
+     *
+     * @param len
+     *            the desired string length.
+     * @return the random string.
+     * @throws NotStrictlyPositiveException if {@code len <= 0}.
+     */
+    public String nextHexString(int len) {
+        if (len <= 0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.LENGTH, len);
+        }
+
+        // Get a random number generator
+        RandomGenerator ran = getRan();
+
+        // Initialize output buffer
+        StringBuilder outBuffer = new StringBuilder();
+
+        // Get int(len/2)+1 random bytes
+        byte[] randomBytes = new byte[(len / 2) + 1];
+        ran.nextBytes(randomBytes);
+
+        // Convert each byte to 2 hex digits
+        for (int i = 0; i < randomBytes.length; i++) {
+            Integer c = Integer.valueOf(randomBytes[i]);
+
+            /*
+             * Add 128 to byte value to make interval 0-255 before doing hex
+             * conversion. This guarantees <= 2 hex digits from toHexString()
+             * toHexString would otherwise add 2^32 to negative arguments.
+             */
+            String hex = Integer.toHexString(c.intValue() + 128);
+
+            // Make sure we add 2 hex digits for each byte
+            if (hex.length() == 1) {
+                hex = "0" + hex;
+            }
+            outBuffer.append(hex);
+        }
+        return outBuffer.toString().substring(0, len);
+    }
+
+    /**
+     * Generate a random int value uniformly distributed between
+     * <code>lower</code> and <code>upper</code>, inclusive.
+     *
+     * @param lower
+     *            the lower bound.
+     * @param upper
+     *            the upper bound.
+     * @return the random integer.
+     * @throws NumberIsTooLargeException if {@code lower >= upper}.
+     */
+    public int nextInt(int lower, int upper) {
+        if (lower >= upper) {
+            throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
+                                                lower, upper, false);
+        }
+        double r = getRan().nextDouble();
+        return (int) ((r * upper) + ((1.0 - r) * lower) + r);
+    }
+
+    /**
+     * Generate a random long value uniformly distributed between
+     * <code>lower</code> and <code>upper</code>, inclusive.
+     *
+     * @param lower
+     *            the lower bound.
+     * @param upper
+     *            the upper bound.
+     * @return the random integer.
+     * @throws NumberIsTooLargeException if {@code lower >= upper}.
+     */
+    public long nextLong(long lower, long upper) {
+        if (lower >= upper) {
+            throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
+                                                lower, upper, false);
+        }
+        double r = getRan().nextDouble();
+        return (long) ((r * upper) + ((1.0 - r) * lower) + r);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * <strong>Algorithm Description:</strong> hex strings are generated in
+     * 40-byte segments using a 3-step process.
+     * <ol>
+     * <li>
+     * 20 random bytes are generated using the underlying
+     * <code>SecureRandom</code>.</li>
+     * <li>
+     * SHA-1 hash is applied to yield a 20-byte binary digest.</li>
+     * <li>
+     * Each byte of the binary digest is converted to 2 hex digits.</li>
+     * </ol>
+     * </p>
+     *
+     * @param len
+     *            the length of the generated string
+     * @return the random string
+     * @throws NotStrictlyPositiveException if {@code len <= 0}.
+     */
+    public String nextSecureHexString(int len) {
+        if (len <= 0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.LENGTH, len);
+        }
+
+        // Get SecureRandom and setup Digest provider
+        SecureRandom secRan = getSecRan();
+        MessageDigest alg = null;
+        try {
+            alg = MessageDigest.getInstance("SHA-1");
+        } catch (NoSuchAlgorithmException ex) {
+            // this should never happen
+            throw new MathInternalError(ex);
+        }
+        alg.reset();
+
+        // Compute number of iterations required (40 bytes each)
+        int numIter = (len / 40) + 1;
+
+        StringBuilder outBuffer = new StringBuilder();
+        for (int iter = 1; iter < numIter + 1; iter++) {
+            byte[] randomBytes = new byte[40];
+            secRan.nextBytes(randomBytes);
+            alg.update(randomBytes);
+
+            // Compute hash -- will create 20-byte binary hash
+            byte hash[] = alg.digest();
+
+            // Loop over the hash, converting each byte to 2 hex digits
+            for (int i = 0; i < hash.length; i++) {
+                Integer c = Integer.valueOf(hash[i]);
+
+                /*
+                 * Add 128 to byte value to make interval 0-255 This guarantees
+                 * <= 2 hex digits from toHexString() toHexString would
+                 * otherwise add 2^32 to negative arguments
+                 */
+                String hex = Integer.toHexString(c.intValue() + 128);
+
+                // Keep strings uniform length -- guarantees 40 bytes
+                if (hex.length() == 1) {
+                    hex = "0" + hex;
+                }
+                outBuffer.append(hex);
+            }
+        }
+        return outBuffer.toString().substring(0, len);
+    }
+
+    /**
+     * Generate a random int value uniformly distributed between
+     * <code>lower</code> and <code>upper</code>, inclusive. This algorithm uses
+     * a secure random number generator.
+     *
+     * @param lower
+     *            the lower bound.
+     * @param upper
+     *            the upper bound.
+     * @return the random integer.
+     * @throws NumberIsTooLargeException if {@code lower >= upper}.
+     */
+    public int nextSecureInt(int lower, int upper) {
+        if (lower >= upper) {
+            throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
+                                                lower, upper, false);
+        }
+        SecureRandom sec = getSecRan();
+        return lower + (int) (sec.nextDouble() * (upper - lower + 1));
+    }
+
+    /**
+     * Generate a random long value uniformly distributed between
+     * <code>lower</code> and <code>upper</code>, inclusive. This algorithm uses
+     * a secure random number generator.
+     *
+     * @param lower
+     *            the lower bound.
+     * @param upper
+     *            the upper bound.
+     * @return the random integer.
+     * @throws NumberIsTooLargeException if {@code lower >= upper}.
+     */
+    public long nextSecureLong(long lower, long upper) {
+        if (lower >= upper) {
+            throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
+                                                lower, upper, false);
+        }
+        SecureRandom sec = getSecRan();
+        return lower + (long) (sec.nextDouble() * (upper - lower + 1));
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * <strong>Algorithm Description</strong>:
+     * <ul><li> For small means, uses simulation of a Poisson process
+     * using Uniform deviates, as described
+     * <a href="http://irmi.epfl.ch/cmos/Pmmi/interactive/rng7.htm"> here.</a>
+     * The Poisson process (and hence value returned) is bounded by 1000 * mean.</li>
+     *
+     * <li> For large means, uses the rejection algorithm described in <br/>
+     * Devroye, Luc. (1981).<i>The Computer Generation of Poisson Random Variables</i>
+     * <strong>Computing</strong> vol. 26 pp. 197-207.</li></ul></p>
+     *
+     * @param mean mean of the Poisson distribution.
+     * @return the random Poisson value.
+     * @throws NotStrictlyPositiveException if {@code mean <= 0}.
+     */
+    public long nextPoisson(double mean) {
+        if (mean <= 0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.MEAN, mean);
+        }
+
+        final RandomGenerator generator = getRan();
+
+        final double pivot = 40.0d;
+        if (mean < pivot) {
+            double p = FastMath.exp(-mean);
+            long n = 0;
+            double r = 1.0d;
+            double rnd = 1.0d;
+
+            while (n < 1000 * mean) {
+                rnd = generator.nextDouble();
+                r = r * rnd;
+                if (r >= p) {
+                    n++;
+                } else {
+                    return n;
+                }
+            }
+            return n;
+        } else {
+            final double lambda = FastMath.floor(mean);
+            final double lambdaFractional = mean - lambda;
+            final double logLambda = FastMath.log(lambda);
+            final double logLambdaFactorial = MathUtils.factorialLog((int) lambda);
+            final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional);
+            final double delta = FastMath.sqrt(lambda * FastMath.log(32 * lambda / FastMath.PI + 1));
+            final double halfDelta = delta / 2;
+            final double twolpd = 2 * lambda + delta;
+            final double a1 = FastMath.sqrt(FastMath.PI * twolpd) * FastMath.exp(1 / 8 * lambda);
+            final double a2 = (twolpd / delta) * FastMath.exp(-delta * (1 + delta) / twolpd);
+            final double aSum = a1 + a2 + 1;
+            final double p1 = a1 / aSum;
+            final double p2 = a2 / aSum;
+            final double c1 = 1 / (8 * lambda);
+
+            double x = 0;
+            double y = 0;
+            double v = 0;
+            int a = 0;
+            double t = 0;
+            double qr = 0;
+            double qa = 0;
+            for (;;) {
+                final double u = nextUniform(0.0, 1);
+                if (u <= p1) {
+                    final double n = nextGaussian(0d, 1d);
+                    x = n * FastMath.sqrt(lambda + halfDelta) - 0.5d;
+                    if (x > delta || x < -lambda) {
+                        continue;
+                    }
+                    y = x < 0 ? FastMath.floor(x) : FastMath.ceil(x);
+                    final double e = nextExponential(1d);
+                    v = -e - (n * n / 2) + c1;
+                } else {
+                    if (u > p1 + p2) {
+                        y = lambda;
+                        break;
+                    } else {
+                        x = delta + (twolpd / delta) * nextExponential(1d);
+                        y = FastMath.ceil(x);
+                        v = -nextExponential(1d) - delta * (x + 1) / twolpd;
+                    }
+                }
+                a = x < 0 ? 1 : 0;
+                t = y * (y + 1) / (2 * lambda);
+                if (v < -t && a == 0) {
+                    y = lambda + y;
+                    break;
+                }
+                qr = t * ((2 * y + 1) / (6 * lambda) - 1);
+                qa = qr - (t * t) / (3 * (lambda + a * (y + 1)));
+                if (v < qa) {
+                    y = lambda + y;
+                    break;
+                }
+                if (v > qr) {
+                    continue;
+                }
+                if (v < y * logLambda - MathUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) {
+                    y = lambda + y;
+                    break;
+                }
+            }
+            return y2 + (long) y;
+        }
+    }
+
+    /**
+     * Generate a random value from a Normal (a.k.a. Gaussian) distribution with
+     * the given mean, <code>mu</code> and the given standard deviation,
+     * <code>sigma</code>.
+     *
+     * @param mu
+     *            the mean of the distribution
+     * @param sigma
+     *            the standard deviation of the distribution
+     * @return the random Normal value
+     * @throws NotStrictlyPositiveException if {@code sigma <= 0}.
+     */
+    public double nextGaussian(double mu, double sigma) {
+        if (sigma <= 0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.STANDARD_DEVIATION, sigma);
+        }
+        return sigma * getRan().nextGaussian() + mu;
+    }
+
+    /**
+     * Returns a random value from an Exponential distribution with the given
+     * mean.
+     * <p>
+     * <strong>Algorithm Description</strong>: Uses the <a
+     * href="http://www.jesus.ox.ac.uk/~clifford/a5/chap1/node5.html"> Inversion
+     * Method</a> to generate exponentially distributed random values from
+     * uniform deviates.
+     * </p>
+     *
+     * @param mean the mean of the distribution
+     * @return the random Exponential value
+     * @throws NotStrictlyPositiveException if {@code mean <= 0}.
+     */
+    public double nextExponential(double mean) {
+        if (mean <= 0.0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.MEAN, mean);
+        }
+        final RandomGenerator generator = getRan();
+        double unif = generator.nextDouble();
+        while (unif == 0.0d) {
+            unif = generator.nextDouble();
+        }
+        return -mean * FastMath.log(unif);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * <strong>Algorithm Description</strong>: scales the output of
+     * Random.nextDouble(), but rejects 0 values (i.e., will generate another
+     * random double if Random.nextDouble() returns 0). This is necessary to
+     * provide a symmetric output interval (both endpoints excluded).
+     * </p>
+     *
+     * @param lower
+     *            the lower bound.
+     * @param upper
+     *            the upper bound.
+     * @return a uniformly distributed random value from the interval (lower,
+     *         upper)
+     * @throws NumberIsTooLargeException if {@code lower >= upper}.
+     */
+    public double nextUniform(double lower, double upper) {
+        if (lower >= upper) {
+            throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
+                                                lower, upper, false);
+        }
+        final RandomGenerator generator = getRan();
+
+        // ensure nextDouble() isn't 0.0
+        double u = generator.nextDouble();
+        while (u <= 0.0) {
+            u = generator.nextDouble();
+        }
+
+        return lower + u * (upper - lower);
+    }
+
+    /**
+     * Generates a random value from the {@link BetaDistributionImpl Beta Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param alpha first distribution shape parameter
+     * @param beta second distribution shape parameter
+     * @return random value sampled from the beta(alpha, beta) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextBeta(double alpha, double beta) throws MathException {
+        return nextInversionDeviate(new BetaDistributionImpl(alpha, beta));
+    }
+
+    /**
+     * Generates a random value from the {@link BinomialDistributionImpl Binomial Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param numberOfTrials number of trials of the Binomial distribution
+     * @param probabilityOfSuccess probability of success of the Binomial distribution
+     * @return random value sampled from the Binomial(numberOfTrials, probabilityOfSuccess) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public int nextBinomial(int numberOfTrials, double probabilityOfSuccess) throws MathException {
+        return nextInversionDeviate(new BinomialDistributionImpl(numberOfTrials, probabilityOfSuccess));
+    }
+
+    /**
+     * Generates a random value from the {@link CauchyDistributionImpl Cauchy Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param median the median of the Cauchy distribution
+     * @param scale the scale parameter of the Cauchy distribution
+     * @return random value sampled from the Cauchy(median, scale) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextCauchy(double median, double scale) throws MathException {
+        return nextInversionDeviate(new CauchyDistributionImpl(median, scale));
+    }
+
+    /**
+     * Generates a random value from the {@link ChiSquaredDistributionImpl ChiSquare Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param df the degrees of freedom of the ChiSquare distribution
+     * @return random value sampled from the ChiSquare(df) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextChiSquare(double df) throws MathException {
+        return nextInversionDeviate(new ChiSquaredDistributionImpl(df));
+    }
+
+    /**
+     * Generates a random value from the {@link FDistributionImpl F Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param numeratorDf the numerator degrees of freedom of the F distribution
+     * @param denominatorDf the denominator degrees of freedom of the F distribution
+     * @return random value sampled from the F(numeratorDf, denominatorDf) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextF(double numeratorDf, double denominatorDf) throws MathException {
+        return nextInversionDeviate(new FDistributionImpl(numeratorDf, denominatorDf));
+    }
+
+    /**
+     * Generates a random value from the {@link GammaDistributionImpl Gamma Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param shape the median of the Gamma distribution
+     * @param scale the scale parameter of the Gamma distribution
+     * @return random value sampled from the Gamma(shape, scale) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextGamma(double shape, double scale) throws MathException {
+        return nextInversionDeviate(new GammaDistributionImpl(shape, scale));
+    }
+
+    /**
+     * Generates a random value from the {@link HypergeometricDistributionImpl Hypergeometric Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(IntegerDistribution) inversion}
+     * to generate random values.
+     *
+     * @param populationSize the population size of the Hypergeometric distribution
+     * @param numberOfSuccesses number of successes in the population of the Hypergeometric distribution
+     * @param sampleSize the sample size of the Hypergeometric distribution
+     * @return random value sampled from the Hypergeometric(numberOfSuccesses, sampleSize) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public int nextHypergeometric(int populationSize, int numberOfSuccesses, int sampleSize) throws MathException {
+        return nextInversionDeviate(new HypergeometricDistributionImpl(populationSize, numberOfSuccesses, sampleSize));
+    }
+
+    /**
+     * Generates a random value from the {@link PascalDistributionImpl Pascal Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(IntegerDistribution) inversion}
+     * to generate random values.
+     *
+     * @param r the number of successes of the Pascal distribution
+     * @param p the probability of success of the Pascal distribution
+     * @return random value sampled from the Pascal(r, p) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public int nextPascal(int r, double p) throws MathException {
+        return nextInversionDeviate(new PascalDistributionImpl(r, p));
+    }
+
+    /**
+     * Generates a random value from the {@link TDistributionImpl T Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param df the degrees of freedom of the T distribution
+     * @return random value from the T(df) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextT(double df) throws MathException {
+        return nextInversionDeviate(new TDistributionImpl(df));
+    }
+
+    /**
+     * Generates a random value from the {@link WeibullDistributionImpl Weibull Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(ContinuousDistribution) inversion}
+     * to generate random values.
+     *
+     * @param shape the shape parameter of the Weibull distribution
+     * @param scale the scale parameter of the Weibull distribution
+     * @return random value sampled from the Weibull(shape, size) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public double nextWeibull(double shape, double scale) throws MathException {
+        return nextInversionDeviate(new WeibullDistributionImpl(shape, scale));
+    }
+
+    /**
+     * Generates a random value from the {@link ZipfDistributionImpl Zipf Distribution}.
+     * This implementation uses {@link #nextInversionDeviate(IntegerDistribution) inversion}
+     * to generate random values.
+     *
+     * @param numberOfElements the number of elements of the ZipfDistribution
+     * @param exponent the exponent of the ZipfDistribution
+     * @return random value sampled from the Zipf(numberOfElements, exponent) distribution
+     * @throws MathException if an error occurs generating the random value
+     * @since 2.2
+     */
+    public int nextZipf(int numberOfElements, double exponent) throws MathException {
+        return nextInversionDeviate(new ZipfDistributionImpl(numberOfElements, exponent));
+    }
+
+    /**
+     * Returns the RandomGenerator used to generate non-secure random data.
+     * <p>
+     * Creates and initializes a default generator if null.
+     * </p>
+     *
+     * @return the Random used to generate random data
+     * @since 1.1
+     */
+    private RandomGenerator getRan() {
+        if (rand == null) {
+            rand = new JDKRandomGenerator();
+            rand.setSeed(System.currentTimeMillis());
+        }
+        return rand;
+    }
+
+    /**
+     * Returns the SecureRandom used to generate secure random data.
+     * <p>
+     * Creates and initializes if null.
+     * </p>
+     *
+     * @return the SecureRandom used to generate secure random data
+     */
+    private SecureRandom getSecRan() {
+        if (secRand == null) {
+            secRand = new SecureRandom();
+            secRand.setSeed(System.currentTimeMillis());
+        }
+        return secRand;
+    }
+
+    /**
+     * Reseeds the random number generator with the supplied seed.
+     * <p>
+     * Will create and initialize if null.
+     * </p>
+     *
+     * @param seed
+     *            the seed value to use
+     */
+    public void reSeed(long seed) {
+        if (rand == null) {
+            rand = new JDKRandomGenerator();
+        }
+        rand.setSeed(seed);
+    }
+
+    /**
+     * Reseeds the secure random number generator with the current time in
+     * milliseconds.
+     * <p>
+     * Will create and initialize if null.
+     * </p>
+     */
+    public void reSeedSecure() {
+        if (secRand == null) {
+            secRand = new SecureRandom();
+        }
+        secRand.setSeed(System.currentTimeMillis());
+    }
+
+    /**
+     * Reseeds the secure random number generator with the supplied seed.
+     * <p>
+     * Will create and initialize if null.
+     * </p>
+     *
+     * @param seed
+     *            the seed value to use
+     */
+    public void reSeedSecure(long seed) {
+        if (secRand == null) {
+            secRand = new SecureRandom();
+        }
+        secRand.setSeed(seed);
+    }
+
+    /**
+     * Reseeds the random number generator with the current time in
+     * milliseconds.
+     */
+    public void reSeed() {
+        if (rand == null) {
+            rand = new JDKRandomGenerator();
+        }
+        rand.setSeed(System.currentTimeMillis());
+    }
+
+    /**
+     * Sets the PRNG algorithm for the underlying SecureRandom instance using
+     * the Security Provider API. The Security Provider API is defined in <a
+     * href =
+     * "http://java.sun.com/j2se/1.3/docs/guide/security/CryptoSpec.html#AppA">
+     * Java Cryptography Architecture API Specification & Reference.</a>
+     * <p>
+     * <strong>USAGE NOTE:</strong> This method carries <i>significant</i>
+     * overhead and may take several seconds to execute.
+     * </p>
+     *
+     * @param algorithm
+     *            the name of the PRNG algorithm
+     * @param provider
+     *            the name of the provider
+     * @throws NoSuchAlgorithmException
+     *             if the specified algorithm is not available
+     * @throws NoSuchProviderException
+     *             if the specified provider is not installed
+     */
+    public void setSecureAlgorithm(String algorithm, String provider)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        secRand = SecureRandom.getInstance(algorithm, provider);
+    }
+
+    /**
+     * Generates an integer array of length <code>k</code> whose entries are
+     * selected randomly, without repetition, from the integers
+     * <code>0 through n-1</code> (inclusive).
+     * <p>
+     * Generated arrays represent permutations of <code>n</code> taken
+     * <code>k</code> at a time.
+     * </p>
+     * <p>
+     * <strong>Preconditions:</strong>
+     * <ul>
+     * <li> <code>k <= n</code></li>
+     * <li> <code>n > 0</code></li>
+     * </ul>
+     * If the preconditions are not met, an IllegalArgumentException is thrown.
+     * </p>
+     * <p>
+     * Uses a 2-cycle permutation shuffle. The shuffling process is described <a
+     * href="http://www.maths.abdn.ac.uk/~igc/tch/mx4002/notes/node83.html">
+     * here</a>.
+     * </p>
+     *
+     * @param n
+     *            domain of the permutation (must be positive)
+     * @param k
+     *            size of the permutation (must satisfy 0 < k <= n).
+     * @return the random permutation as an int array
+     * @throws NumberIsTooLargeException if {@code k > n}.
+     * @throws NotStrictlyPositiveException if {@code k <= 0}.
+     */
+    public int[] nextPermutation(int n, int k) {
+        if (k > n) {
+            throw new NumberIsTooLargeException(LocalizedFormats.PERMUTATION_EXCEEDS_N,
+                                                k, n, true);
+        }
+        if (k == 0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.PERMUTATION_SIZE,
+                                                   k);
+        }
+
+        int[] index = getNatural(n);
+        shuffle(index, n - k);
+        int[] result = new int[k];
+        for (int i = 0; i < k; i++) {
+            result[i] = index[n - i - 1];
+        }
+
+        return result;
+    }
+
+    /**
+     * Uses a 2-cycle permutation shuffle to generate a random permutation.
+     * <strong>Algorithm Description</strong>: Uses a 2-cycle permutation
+     * shuffle to generate a random permutation of <code>c.size()</code> and
+     * then returns the elements whose indexes correspond to the elements of the
+     * generated permutation. This technique is described, and proven to
+     * generate random samples, <a
+     * href="http://www.maths.abdn.ac.uk/~igc/tch/mx4002/notes/node83.html">
+     * here</a>
+     *
+     * @param c
+     *            Collection to sample from.
+     * @param k
+     *            sample size.
+     * @return the random sample.
+     * @throws NumberIsTooLargeException if {@code k > c.size()}.
+     * @throws NotStrictlyPositiveException if {@code k <= 0}.
+     */
+    public Object[] nextSample(Collection<?> c, int k) {
+        int len = c.size();
+        if (k > len) {
+            throw new NumberIsTooLargeException(LocalizedFormats.SAMPLE_SIZE_EXCEEDS_COLLECTION_SIZE,
+                                                k, len, true);
+        }
+        if (k <= 0) {
+            throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_SAMPLES, k);
+        }
+
+        Object[] objects = c.toArray();
+        int[] index = nextPermutation(len, k);
+        Object[] result = new Object[k];
+        for (int i = 0; i < k; i++) {
+            result[i] = objects[index[i]];
+        }
+        return result;
+    }
+
+    /**
+     * Generate a random deviate from the given distribution using the
+     * <a href="http://en.wikipedia.org/wiki/Inverse_transform_sampling"> inversion method.</a>
+     *
+     * @param distribution Continuous distribution to generate a random value from
+     * @return a random value sampled from the given distribution
+     * @throws MathException if an error occurs computing the inverse cumulative distribution function
+     * @since 2.2
+     */
+    public double nextInversionDeviate(ContinuousDistribution distribution) throws MathException {
+        return distribution.inverseCumulativeProbability(nextUniform(0, 1));
+
+    }
+
+    /**
+     * Generate a random deviate from the given distribution using the
+     * <a href="http://en.wikipedia.org/wiki/Inverse_transform_sampling"> inversion method.</a>
+     *
+     * @param distribution Integer distribution to generate a random value from
+     * @return a random value sampled from the given distribution
+     * @throws MathException if an error occurs computing the inverse cumulative distribution function
+     * @since 2.2
+     */
+    public int nextInversionDeviate(IntegerDistribution distribution) throws MathException {
+        final double target = nextUniform(0, 1);
+        final int glb = distribution.inverseCumulativeProbability(target);
+        if (distribution.cumulativeProbability(glb) == 1.0d) { // No mass above
+            return glb;
+        } else {
+            return glb + 1;
+        }
+    }
+
+    // ------------------------Private methods----------------------------------
+
+    /**
+     * Uses a 2-cycle permutation shuffle to randomly re-order the last elements
+     * of list.
+     *
+     * @param list
+     *            list to be shuffled
+     * @param end
+     *            element past which shuffling begins
+     */
+    private void shuffle(int[] list, int end) {
+        int target = 0;
+        for (int i = list.length - 1; i >= end; i--) {
+            if (i == 0) {
+                target = 0;
+            } else {
+                target = nextInt(0, i);
+            }
+            int temp = list[target];
+            list[target] = list[i];
+            list[i] = temp;
+        }
+    }
+
+    /**
+     * Returns an array representing n.
+     *
+     * @param n
+     *            the natural number to represent
+     * @return array with entries = elements of n
+     */
+    private int[] getNatural(int n) {
+        int[] natural = new int[n];
+        for (int i = 0; i < n; i++) {
+            natural[i] = i;
+        }
+        return natural;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/RandomGenerator.java b/src/main/java/org/apache/commons/math/random/RandomGenerator.java
new file mode 100644
index 0000000..0b86c2a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/RandomGenerator.java
@@ -0,0 +1,148 @@
+/*
+ * 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.random;
+
+
+/**
+ * Interface extracted from <code>java.util.Random</code>.  This interface is
+ * implemented by {@link AbstractRandomGenerator}.
+ *
+ * @since 1.1
+ * @version $Revision: 949750 $ $Date: 2010-05-31 16:06:04 +0200 (lun. 31 mai 2010) $
+ */
+public interface RandomGenerator {
+
+    /**
+     * Sets the seed of the underlying random number generator using an
+     * <code>int</code> seed.
+     * <p>Sequences of values generated starting with the same seeds
+     * should be identical.
+     * </p>
+     * @param seed the seed value
+     */
+    void setSeed(int seed);
+
+    /**
+     * Sets the seed of the underlying random number generator using an
+     * <code>int</code> array seed.
+     * <p>Sequences of values generated starting with the same seeds
+     * should be identical.
+     * </p>
+     * @param seed the seed value
+     */
+    void setSeed(int[] seed);
+
+    /**
+     * Sets the seed of the underlying random number generator using a
+     * <code>long</code> seed.
+     * <p>Sequences of values generated starting with the same seeds
+     * should be identical.
+     * </p>
+     * @param seed the seed value
+     */
+    void setSeed(long seed);
+
+    /**
+     * Generates random bytes and places them into a user-supplied
+     * byte array.  The number of random bytes produced is equal to
+     * the length of the byte array.
+     *
+     * @param bytes the non-null byte array in which to put the
+     * random bytes
+     */
+    void nextBytes(byte[] bytes);
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>int</code>
+     * value from this random number generator's sequence.
+     * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values
+     * should be produced with  (approximately) equal probability.
+     *
+     * @return the next pseudorandom, uniformly distributed <code>int</code>
+     *  value from this random number generator's sequence
+     */
+    int nextInt();
+
+    /**
+     * Returns a pseudorandom, uniformly distributed <tt>int</tt> value
+     * between 0 (inclusive) and the specified value (exclusive), drawn from
+     * this random number generator's sequence.
+     *
+     * @param n the bound on the random number to be returned.  Must be
+     * positive.
+     * @return  a pseudorandom, uniformly distributed <tt>int</tt>
+     * value between 0 (inclusive) and n (exclusive).
+     * @throws IllegalArgumentException  if n is not positive.
+     */
+    int nextInt(int n);
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>long</code>
+     * value from this random number generator's sequence.  All
+     * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values
+     * should be produced with (approximately) equal probability.
+     *
+     * @return  the next pseudorandom, uniformly distributed <code>long</code>
+     *value from this random number generator's sequence
+     */
+    long nextLong();
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed
+     * <code>boolean</code> value from this random number generator's
+     * sequence.
+     *
+     * @return  the next pseudorandom, uniformly distributed
+     * <code>boolean</code> value from this random number generator's
+     * sequence
+     */
+    boolean nextBoolean();
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>float</code>
+     * value between <code>0.0</code> and <code>1.0</code> from this random
+     * number generator's sequence.
+     *
+     * @return  the next pseudorandom, uniformly distributed <code>float</code>
+     * value between <code>0.0</code> and <code>1.0</code> from this
+     * random number generator's sequence
+     */
+    float nextFloat();
+
+    /**
+     * Returns the next pseudorandom, uniformly distributed
+     * <code>double</code> value between <code>0.0</code> and
+     * <code>1.0</code> from this random number generator's sequence.
+     *
+     * @return  the next pseudorandom, uniformly distributed
+     *  <code>double</code> value between <code>0.0</code> and
+     *  <code>1.0</code> from this random number generator's sequence
+     */
+    double nextDouble();
+
+    /**
+     * Returns the next pseudorandom, Gaussian ("normally") distributed
+     * <code>double</code> value with mean <code>0.0</code> and standard
+     * deviation <code>1.0</code> from this random number generator's sequence.
+     *
+     * @return  the next pseudorandom, Gaussian ("normally") distributed
+     * <code>double</code> value with mean <code>0.0</code> and
+     * standard deviation <code>1.0</code> from this random number
+     *  generator's sequence
+     */
+    double nextGaussian();
+}
diff --git a/src/main/java/org/apache/commons/math/random/RandomVectorGenerator.java b/src/main/java/org/apache/commons/math/random/RandomVectorGenerator.java
new file mode 100644
index 0000000..15abbd7
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/RandomVectorGenerator.java
@@ -0,0 +1,35 @@
+/*
+ * 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.random;
+
+
+/** This interface represents a random generator for whole vectors.
+ *
+ * @since 1.2
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ *
+ */
+
+public interface RandomVectorGenerator {
+
+    /** Generate a random vector.
+     * @return a random vector as an array of double.
+     */
+    double[] nextVector();
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.java b/src/main/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.java
new file mode 100644
index 0000000..d365f9b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.java
@@ -0,0 +1,93 @@
+/*
+ * 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.random;
+
+import java.util.Arrays;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+
+/**
+ * A {@link RandomVectorGenerator} that generates vectors with uncorrelated
+ * components. Components of generated vectors follow (independent) Gaussian
+ * distributions, with parameters supplied in the constructor.
+ *
+ * @version $Revision: 962515 $ $Date: 2010-07-09 15:15:28 +0200 (ven. 09 juil. 2010) $
+ * @since 1.2
+ */
+
+public class UncorrelatedRandomVectorGenerator
+  implements RandomVectorGenerator {
+
+    /** Underlying scalar generator. */
+    private final NormalizedRandomGenerator generator;
+
+    /** Mean vector. */
+    private final double[] mean;
+
+    /** Standard deviation vector. */
+    private final double[] standardDeviation;
+
+  /** Simple constructor.
+   * <p>Build an uncorrelated random vector generator from
+   * its mean and standard deviation vectors.</p>
+   * @param mean expected mean values for each component
+   * @param standardDeviation standard deviation for each component
+   * @param generator underlying generator for uncorrelated normalized
+   * components
+   */
+  public UncorrelatedRandomVectorGenerator(double[] mean,
+                                           double[] standardDeviation,
+                                           NormalizedRandomGenerator generator) {
+    if (mean.length != standardDeviation.length) {
+        throw new DimensionMismatchException(mean.length, standardDeviation.length);
+    }
+    this.mean              = mean.clone();
+    this.standardDeviation = standardDeviation.clone();
+    this.generator = generator;
+  }
+
+  /** Simple constructor.
+   * <p>Build a null mean random and unit standard deviation
+   * uncorrelated vector generator</p>
+   * @param dimension dimension of the vectors to generate
+   * @param generator underlying generator for uncorrelated normalized
+   * components
+   */
+  public UncorrelatedRandomVectorGenerator(int dimension,
+                                           NormalizedRandomGenerator generator) {
+    mean              = new double[dimension];
+    standardDeviation = new double[dimension];
+    Arrays.fill(standardDeviation, 1.0);
+    this.generator = generator;
+  }
+
+  /** Generate an uncorrelated random vector.
+   * @return a random vector as a newly built array of double
+   */
+  public double[] nextVector() {
+
+    double[] random = new double[mean.length];
+    for (int i = 0; i < random.length; ++i) {
+      random[i] = mean[i] + standardDeviation[i] * generator.nextNormalizedDouble();
+    }
+
+    return random;
+
+  }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/UniformRandomGenerator.java b/src/main/java/org/apache/commons/math/random/UniformRandomGenerator.java
new file mode 100644
index 0000000..54492d0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/UniformRandomGenerator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.random;
+
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This class implements a normalized uniform random generator.
+ * <p>Since it is a normalized random generator, it generates values
+ * from a uniform distribution with mean equal to 0 and standard
+ * deviation equal to 1. Generated values fall in the range
+ * [-&#x0221A;3, +&#x0221A;3].</p>
+ *
+ * @since 1.2
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+
+public class UniformRandomGenerator implements NormalizedRandomGenerator {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 1569292426375546027L;
+
+    /** Square root of three. */
+    private static final double SQRT3 = FastMath.sqrt(3.0);
+
+    /** Underlying generator. */
+    private final RandomGenerator generator;
+
+    /** Create a new generator.
+     * @param generator underlying random generator to use
+     */
+    public UniformRandomGenerator(RandomGenerator generator) {
+        this.generator = generator;
+    }
+
+    /** Generate a random scalar with null mean and unit standard deviation.
+     * <p>The number generated is uniformly distributed between -&sqrt;(3)
+     * and +&sqrt;(3).</p>
+     * @return a random scalar with null mean and unit standard deviation
+     */
+    public double nextNormalizedDouble() {
+        return SQRT3 * (2 * generator.nextDouble() - 1.0);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java b/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java
new file mode 100644
index 0000000..cac8f18
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.random;
+
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Generate random vectors isotropically located on the surface of a sphere.
+ *
+ * @since 2.1
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+
+public class UnitSphereRandomVectorGenerator
+    implements RandomVectorGenerator {
+    /**
+     * RNG used for generating the individual components of the vectors.
+     */
+    private final RandomGenerator rand;
+    /**
+     * Space dimension.
+     */
+    private final int dimension;
+
+    /**
+     * @param dimension Space dimension.
+     * @param rand RNG for the individual components of the vectors.
+     */
+    public UnitSphereRandomVectorGenerator(final int dimension,
+                                           final RandomGenerator rand) {
+        this.dimension = dimension;
+        this.rand = rand;
+    }
+    /**
+     * Create an object that will use a default RNG ({@link MersenneTwister}),
+     * in order to generate the individual components.
+     *
+     * @param dimension Space dimension.
+     */
+    public UnitSphereRandomVectorGenerator(final int dimension) {
+        this(dimension, new MersenneTwister());
+    }
+
+    /** {@inheritDoc} */
+    public double[] nextVector() {
+
+        final double[] v = new double[dimension];
+
+        double normSq;
+        do {
+            normSq = 0;
+            for (int i = 0; i < dimension; i++) {
+                final double comp = 2 * rand.nextDouble() - 1;
+                v[i] = comp;
+                normSq += comp * comp;
+            }
+        } while (normSq > 1);
+
+        final double f = 1 / FastMath.sqrt(normSq);
+        for (int i = 0; i < dimension; i++) {
+            v[i] *= f;
+        }
+
+        return v;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/ValueServer.java b/src/main/java/org/apache/commons/math/random/ValueServer.java
new file mode 100644
index 0000000..9146e69
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/ValueServer.java
@@ -0,0 +1,385 @@
+/*
+ * 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.random;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Generates values for use in simulation applications.
+ * <p>
+ * How values are generated is determined by the <code>mode</code>
+ * property.</p>
+ * <p>
+ * Supported <code>mode</code> values are: <ul>
+ * <li> DIGEST_MODE -- uses an empirical distribution </li>
+ * <li> REPLAY_MODE -- replays data from <code>valuesFileURL</code></li>
+ * <li> UNIFORM_MODE -- generates uniformly distributed random values with
+ *                      mean = <code>mu</code> </li>
+ * <li> EXPONENTIAL_MODE -- generates exponentially distributed random values
+ *                         with mean = <code>mu</code></li>
+ * <li> GAUSSIAN_MODE -- generates Gaussian distributed random values with
+ *                       mean = <code>mu</code> and
+ *                       standard deviation = <code>sigma</code></li>
+ * <li> CONSTANT_MODE -- returns <code>mu</code> every time.</li></ul></p>
+ *
+ * @version $Revision: 1003886 $ $Date: 2010-10-02 23:04:44 +0200 (sam. 02 oct. 2010) $
+ *
+ */
+public class ValueServer {
+
+    /** Use empirical distribution.  */
+    public static final int DIGEST_MODE = 0;
+
+    /** Replay data from valuesFilePath. */
+    public static final int REPLAY_MODE = 1;
+
+    /** Uniform random deviates with mean = &mu;. */
+    public static final int UNIFORM_MODE = 2;
+
+    /** Exponential random deviates with mean = &mu;. */
+    public static final int EXPONENTIAL_MODE = 3;
+
+    /** Gaussian random deviates with mean = &mu;, std dev = &sigma;. */
+    public static final int GAUSSIAN_MODE = 4;
+
+    /** Always return mu */
+    public static final int CONSTANT_MODE = 5;
+
+    /** mode determines how values are generated. */
+    private int mode = 5;
+
+    /** URI to raw data values. */
+    private URL valuesFileURL = null;
+
+    /** Mean for use with non-data-driven modes. */
+    private double mu = 0.0;
+
+    /** Standard deviation for use with GAUSSIAN_MODE. */
+    private double sigma = 0.0;
+
+    /** Empirical probability distribution for use with DIGEST_MODE. */
+    private EmpiricalDistribution empiricalDistribution = null;
+
+    /** File pointer for REPLAY_MODE. */
+    private BufferedReader filePointer = null;
+
+    /** RandomDataImpl to use for random data generation. */
+    private final RandomData randomData;
+
+    // Data generation modes ======================================
+
+    /** Creates new ValueServer */
+    public ValueServer() {
+        randomData = new RandomDataImpl();
+    }
+
+    /**
+     * Construct a ValueServer instance using a RandomData as its source
+     * of random data.
+     *
+     * @param randomData the RandomData instance used to source random data
+     * @since 1.1
+     */
+    public ValueServer(RandomData randomData) {
+        this.randomData = randomData;
+    }
+
+    /**
+     * Returns the next generated value, generated according
+     * to the mode value (see MODE constants).
+     *
+     * @return generated value
+     * @throws IOException in REPLAY_MODE if a file I/O error occurs
+     */
+    public double getNext() throws IOException {
+        switch (mode) {
+            case DIGEST_MODE: return getNextDigest();
+            case REPLAY_MODE: return getNextReplay();
+            case UNIFORM_MODE: return getNextUniform();
+            case EXPONENTIAL_MODE: return getNextExponential();
+            case GAUSSIAN_MODE: return getNextGaussian();
+            case CONSTANT_MODE: return mu;
+            default: throw MathRuntimeException.createIllegalStateException(
+                    LocalizedFormats.UNKNOWN_MODE,
+                    mode,
+                    "DIGEST_MODE",   DIGEST_MODE,   "REPLAY_MODE",      REPLAY_MODE,
+                    "UNIFORM_MODE",  UNIFORM_MODE,  "EXPONENTIAL_MODE", EXPONENTIAL_MODE,
+                    "GAUSSIAN_MODE", GAUSSIAN_MODE, "CONSTANT_MODE",    CONSTANT_MODE);
+        }
+    }
+
+    /**
+     * Fills the input array with values generated using getNext() repeatedly.
+     *
+     * @param values array to be filled
+     * @throws IOException in REPLAY_MODE if a file I/O error occurs
+     */
+    public void fill(double[] values) throws IOException {
+        for (int i = 0; i < values.length; i++) {
+            values[i] = getNext();
+        }
+    }
+
+    /**
+     * Returns an array of length <code>length</code> with values generated
+     * using getNext() repeatedly.
+     *
+     * @param length length of output array
+     * @return array of generated values
+     * @throws IOException in REPLAY_MODE if a file I/O error occurs
+     */
+    public double[] fill(int length) throws IOException {
+        double[] out = new double[length];
+        for (int i = 0; i < length; i++) {
+            out[i] = getNext();
+        }
+        return out;
+    }
+
+    /**
+     * Computes the empirical distribution using values from the file
+     * in <code>valuesFileURL</code>, using the default number of bins.
+     * <p>
+     * <code>valuesFileURL</code> must exist and be
+     * readable by *this at runtime.</p>
+     * <p>
+     * This method must be called before using <code>getNext()</code>
+     * with <code>mode = DIGEST_MODE</code></p>
+     *
+     * @throws IOException if an I/O error occurs reading the input file
+     */
+    public void computeDistribution() throws IOException {
+        empiricalDistribution = new EmpiricalDistributionImpl();
+        empiricalDistribution.load(valuesFileURL);
+    }
+
+    /**
+     * Computes the empirical distribution using values from the file
+     * in <code>valuesFileURL</code> and <code>binCount</code> bins.
+     * <p>
+     * <code>valuesFileURL</code> must exist and be readable by this process
+     * at runtime.</p>
+     * <p>
+     * This method must be called before using <code>getNext()</code>
+     * with <code>mode = DIGEST_MODE</code></p>
+     *
+     * @param binCount the number of bins used in computing the empirical
+     * distribution
+     * @throws IOException if an error occurs reading the input file
+     */
+    public void computeDistribution(int binCount)
+            throws IOException {
+        empiricalDistribution = new EmpiricalDistributionImpl(binCount);
+        empiricalDistribution.load(valuesFileURL);
+        mu = empiricalDistribution.getSampleStats().getMean();
+        sigma = empiricalDistribution.getSampleStats().getStandardDeviation();
+    }
+
+    /** Getter for property mode.
+     * @return Value of property mode.
+     */
+    public int getMode() {
+        return mode;
+    }
+
+    /** Setter for property mode.
+     * @param mode New value of property mode.
+     */
+    public void setMode(int mode) {
+        this.mode = mode;
+    }
+
+    /**
+     * Getter for <code>valuesFileURL<code>
+     * @return Value of property valuesFileURL.
+     */
+    public URL getValuesFileURL() {
+        return valuesFileURL;
+    }
+
+    /**
+     * Sets the <code>valuesFileURL</code> using a string URL representation
+     * @param url String representation for new valuesFileURL.
+     * @throws MalformedURLException if url is not well formed
+     */
+    public void setValuesFileURL(String url) throws MalformedURLException {
+        this.valuesFileURL = new URL(url);
+    }
+
+    /**
+     * Sets the <code>valuesFileURL</code>
+     * @param url New value of property valuesFileURL.
+     */
+    public void setValuesFileURL(URL url) {
+        this.valuesFileURL = url;
+    }
+
+    /** Getter for property empiricalDistribution.
+     * @return Value of property empiricalDistribution.
+     */
+    public EmpiricalDistribution getEmpiricalDistribution() {
+        return empiricalDistribution;
+    }
+
+    /**
+     * Resets REPLAY_MODE file pointer to the beginning of the <code>valuesFileURL</code>.
+     *
+     * @throws IOException if an error occurs opening the file
+     */
+    public void resetReplayFile() throws IOException {
+        if (filePointer != null) {
+            try {
+                filePointer.close();
+                filePointer = null;
+            } catch (IOException ex) {
+                // ignore
+            }
+        }
+        filePointer = new BufferedReader(new InputStreamReader(valuesFileURL.openStream()));
+    }
+
+    /**
+     * Closes <code>valuesFileURL</code> after use in REPLAY_MODE.
+     *
+     * @throws IOException if an error occurs closing the file
+     */
+    public void closeReplayFile() throws IOException {
+        if (filePointer != null) {
+            filePointer.close();
+            filePointer = null;
+        }
+    }
+
+    /** Getter for property mu.
+     * @return Value of property mu.
+     */
+    public double getMu() {
+        return mu;
+    }
+
+    /** Setter for property mu.
+     * @param mu New value of property mu.
+     */
+    public void setMu(double mu) {
+        this.mu = mu;
+    }
+
+    /** Getter for property sigma.
+     * @return Value of property sigma.
+     */
+    public double getSigma() {
+        return sigma;
+    }
+
+    /** Setter for property sigma.
+     * @param sigma New value of property sigma.
+     */
+    public void setSigma(double sigma) {
+        this.sigma = sigma;
+    }
+
+    //------------- private methods ---------------------------------
+
+    /**
+     * Gets a random value in DIGEST_MODE.
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Before this method is called, <code>computeDistribution()</code>
+     * must have completed successfully; otherwise an
+     * <code>IllegalStateException</code> will be thrown</li></ul></p>
+     *
+     * @return next random value from the empirical distribution digest
+     */
+    private double getNextDigest() {
+        if ((empiricalDistribution == null) ||
+            (empiricalDistribution.getBinStats().size() == 0)) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.DIGEST_NOT_INITIALIZED);
+        }
+        return empiricalDistribution.getNextValue();
+    }
+
+    /**
+     * Gets next sequential value from the <code>valuesFileURL</code>.
+     * <p>
+     * Throws an IOException if the read fails.</p>
+     * <p>
+     * This method will open the <code>valuesFileURL</code> if there is no
+     * replay file open.</p>
+     * <p>
+     * The <code>valuesFileURL</code> will be closed and reopened to wrap around
+     * from EOF to BOF if EOF is encountered. EOFException (which is a kind of
+     * IOException) may still be thrown if the <code>valuesFileURL</code> is
+     * empty.</p>
+     *
+     * @return next value from the replay file
+     * @throws IOException if there is a problem reading from the file
+     * @throws NumberFormatException if an invalid numeric string is
+     *   encountered in the file
+     */
+    private double getNextReplay() throws IOException {
+        String str = null;
+        if (filePointer == null) {
+            resetReplayFile();
+        }
+        if ((str = filePointer.readLine()) == null) {
+            // we have probably reached end of file, wrap around from EOF to BOF
+            closeReplayFile();
+            resetReplayFile();
+            if ((str = filePointer.readLine()) == null) {
+                throw MathRuntimeException.createEOFException(LocalizedFormats.URL_CONTAINS_NO_DATA,
+                                                              valuesFileURL);
+            }
+        }
+        return Double.valueOf(str).doubleValue();
+    }
+
+    /**
+     * Gets a uniformly distributed random value with mean = mu.
+     *
+     * @return random uniform value
+     */
+    private double getNextUniform() {
+        return randomData.nextUniform(0, 2 * mu);
+    }
+
+    /**
+     * Gets an exponentially distributed random value with mean = mu.
+     *
+     * @return random exponential value
+     */
+    private double getNextExponential() {
+        return randomData.nextExponential(mu);
+    }
+
+    /**
+     * Gets a Gaussian distributed random value with mean = mu
+     * and standard deviation = sigma.
+     *
+     * @return random Gaussian value
+     */
+    private double getNextGaussian() {
+        return randomData.nextGaussian(mu, sigma);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/Well1024a.java b/src/main/java/org/apache/commons/math/random/Well1024a.java
new file mode 100644
index 0000000..8406ed5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/Well1024a.java
@@ -0,0 +1,106 @@
+/*
+ * 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.random;
+
+
+/** This class implements the WELL1024a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public class Well1024a extends AbstractWell {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 5680173464174485492L;
+
+    /** Number of bits in the pool. */
+    private static final int K = 1024;
+
+    /** First parameter of the algorithm. */
+    private static final int M1 = 3;
+
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 24;
+
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 10;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public Well1024a() {
+        super(K, M1, M2, M3);
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public Well1024a(int seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public Well1024a(int[] seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public Well1024a(long seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int next(final int bits) {
+
+        final int indexRm1 = iRm1[index];
+
+        final int v0       = v[index];
+        final int vM1      = v[i1[index]];
+        final int vM2      = v[i2[index]];
+        final int vM3      = v[i3[index]];
+
+        final int z0 = v[indexRm1];
+        final int z1 = v0  ^ (vM1 ^ (vM1 >>> 8));
+        final int z2 = (vM2 ^ (vM2 << 19)) ^ (vM3 ^ (vM3 << 14));
+        final int z3 = z1      ^ z2;
+        final int z4 = (z0 ^ (z0 << 11)) ^ (z1 ^ (z1 << 7)) ^ (z2 ^ (z2 << 13));
+
+        v[index]     = z3;
+        v[indexRm1]  = z4;
+        index        = indexRm1;
+
+        return z4 >>> (32 - bits);
+
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/random/Well19937a.java b/src/main/java/org/apache/commons/math/random/Well19937a.java
new file mode 100644
index 0000000..97f9bfd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/Well19937a.java
@@ -0,0 +1,108 @@
+/*
+ * 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.random;
+
+
+/** This class implements the WELL19937a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public class Well19937a extends AbstractWell {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -7462102162223815419L;
+
+    /** Number of bits in the pool. */
+    private static final int K = 19937;
+
+    /** First parameter of the algorithm. */
+    private static final int M1 = 70;
+
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 179;
+
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 449;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public Well19937a() {
+        super(K, M1, M2, M3);
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public Well19937a(int seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public Well19937a(int[] seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public Well19937a(long seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int next(final int bits) {
+
+        final int indexRm1 = iRm1[index];
+        final int indexRm2 = iRm2[index];
+
+        final int v0       = v[index];
+        final int vM1      = v[i1[index]];
+        final int vM2      = v[i2[index]];
+        final int vM3      = v[i3[index]];
+
+        final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]);
+        final int z1 = (v0 ^ (v0 << 25))  ^ (vM1 ^ (vM1 >>> 27));
+        final int z2 = (vM2 >>> 9) ^ (vM3 ^ (vM3 >>> 1));
+        final int z3 = z1      ^ z2;
+        final int z4 = z0 ^ (z1 ^ (z1 << 9)) ^ (z2 ^ (z2 << 21)) ^ (z3 ^ (z3 >>> 21));
+
+        v[index]     = z3;
+        v[indexRm1]  = z4;
+        v[indexRm2] &= 0x80000000;
+        index        = indexRm1;
+
+        return z4 >>> (32 - bits);
+
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/random/Well19937c.java b/src/main/java/org/apache/commons/math/random/Well19937c.java
new file mode 100644
index 0000000..53029c1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/Well19937c.java
@@ -0,0 +1,115 @@
+/*
+ * 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.random;
+
+
+/** This class implements the WELL19937c pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public class Well19937c extends AbstractWell {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -7203498180754925124L;
+
+    /** Number of bits in the pool. */
+    private static final int K = 19937;
+
+    /** First parameter of the algorithm. */
+    private static final int M1 = 70;
+
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 179;
+
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 449;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public Well19937c() {
+        super(K, M1, M2, M3);
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public Well19937c(int seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public Well19937c(int[] seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public Well19937c(long seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int next(final int bits) {
+
+        final int indexRm1 = iRm1[index];
+        final int indexRm2 = iRm2[index];
+
+        final int v0       = v[index];
+        final int vM1      = v[i1[index]];
+        final int vM2      = v[i2[index]];
+        final int vM3      = v[i3[index]];
+
+        final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]);
+        final int z1 = (v0 ^ (v0 << 25))  ^ (vM1 ^ (vM1 >>> 27));
+        final int z2 = (vM2 >>> 9) ^ (vM3 ^ (vM3 >>> 1));
+        final int z3 = z1      ^ z2;
+        int z4 = z0 ^ (z1 ^ (z1 << 9)) ^ (z2 ^ (z2 << 21)) ^ (z3 ^ (z3 >>> 21));
+
+        v[index]     = z3;
+        v[indexRm1]  = z4;
+        v[indexRm2] &= 0x80000000;
+        index        = indexRm1;
+
+
+        // add Matsumoto-Kurita tempering
+        // to get a maximally-equidistributed generator
+        z4 = z4 ^ ((z4 <<  7) & 0xe46e1700);
+        z4 = z4 ^ ((z4 << 15) & 0x9b868000);
+
+        return z4 >>> (32 - bits);
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/Well44497a.java b/src/main/java/org/apache/commons/math/random/Well44497a.java
new file mode 100644
index 0000000..70d672c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/Well44497a.java
@@ -0,0 +1,111 @@
+/*
+ * 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.random;
+
+
+/** This class implements the WELL44497a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public class Well44497a extends AbstractWell {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -3859207588353972099L;
+
+    /** Number of bits in the pool. */
+    private static final int K = 44497;
+
+    /** First parameter of the algorithm. */
+    private static final int M1 = 23;
+
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 481;
+
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 229;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public Well44497a() {
+        super(K, M1, M2, M3);
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public Well44497a(int seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public Well44497a(int[] seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public Well44497a(long seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int next(final int bits) {
+
+        final int indexRm1 = iRm1[index];
+        final int indexRm2 = iRm2[index];
+
+        final int v0       = v[index];
+        final int vM1      = v[i1[index]];
+        final int vM2      = v[i2[index]];
+        final int vM3      = v[i3[index]];
+
+        // the values below include the errata of the original article
+        final int z0       = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]);
+        final int z1       = (v0 ^ (v0 << 24))  ^ (vM1 ^ (vM1 >>> 30));
+        final int z2       = (vM2 ^ (vM2 << 10)) ^ (vM3 << 26);
+        final int z3       = z1      ^ z2;
+        final int z2Prime  = ((z2 << 9) ^ (z2 >>> 23)) & 0xfbffffff;
+        final int z2Second = ((z2 & 0x00020000) != 0) ? (z2Prime ^ 0xb729fcec) : z2Prime;
+        final int z4       = z0 ^ (z1 ^ (z1 >>> 20)) ^ z2Second ^ z3;
+
+        v[index]     = z3;
+        v[indexRm1]  = z4;
+        v[indexRm2] &= 0xFFFF8000;
+        index        = indexRm1;
+
+        return z4 >>> (32 - bits);
+
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/random/Well44497b.java b/src/main/java/org/apache/commons/math/random/Well44497b.java
new file mode 100644
index 0000000..28b5dbb
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/Well44497b.java
@@ -0,0 +1,119 @@
+/*
+ * 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.random;
+
+
+/** This class implements the WELL44497b pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public class Well44497b extends AbstractWell {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 4032007538246675492L;
+
+    /** Number of bits in the pool. */
+    private static final int K = 44497;
+
+    /** First parameter of the algorithm. */
+    private static final int M1 = 23;
+
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 481;
+
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 229;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public Well44497b() {
+        super(K, M1, M2, M3);
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public Well44497b(int seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public Well44497b(int[] seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public Well44497b(long seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int next(final int bits) {
+
+        // compute raw value given by WELL44497a generator
+        // which is NOT maximally-equidistributed
+        final int indexRm1 = iRm1[index];
+        final int indexRm2 = iRm2[index];
+
+        final int v0       = v[index];
+        final int vM1      = v[i1[index]];
+        final int vM2      = v[i2[index]];
+        final int vM3      = v[i3[index]];
+
+        // the values below include the errata of the original article
+        final int z0       = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]);
+        final int z1       = (v0 ^ (v0 << 24))  ^ (vM1 ^ (vM1 >>> 30));
+        final int z2       = (vM2 ^ (vM2 << 10)) ^ (vM3 << 26);
+        final int z3       = z1      ^ z2;
+        final int z2Prime  = ((z2 << 9) ^ (z2 >>> 23)) & 0xfbffffff;
+        final int z2Second = ((z2 & 0x00020000) != 0) ? (z2Prime ^ 0xb729fcec) : z2Prime;
+        int z4             = z0 ^ (z1 ^ (z1 >>> 20)) ^ z2Second ^ z3;
+
+        v[index]     = z3;
+        v[indexRm1]  = z4;
+        v[indexRm2] &= 0xFFFF8000;
+        index        = indexRm1;
+
+        // add Matsumoto-Kurita tempering
+        // to get a maximally-equidistributed generator
+        z4 = z4 ^ ((z4 <<  7) & 0x93dd1400);
+        z4 = z4 ^ ((z4 << 15) & 0xfa118000);
+
+        return z4 >>> (32 - bits);
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/Well512a.java b/src/main/java/org/apache/commons/math/random/Well512a.java
new file mode 100644
index 0000000..c822c9d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/Well512a.java
@@ -0,0 +1,107 @@
+/*
+ * 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.random;
+
+
+/** This class implements the WELL512a pseudo-random number generator
+ * from Fran&ccedil;ois Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
+
+ * <p>This generator is described in a paper by Fran&ccedil;ois Panneton,
+ * Pierre L'Ecuyer and Makoto Matsumoto <a
+ * href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
+ * Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
+ * Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
+ * are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
+
+ * @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
+ * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
+ * @since 2.2
+
+ */
+public class Well512a extends AbstractWell {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -6104179812103820574L;
+
+    /** Number of bits in the pool. */
+    private static final int K = 512;
+
+    /** First parameter of the algorithm. */
+    private static final int M1 = 13;
+
+    /** Second parameter of the algorithm. */
+    private static final int M2 = 9;
+
+    /** Third parameter of the algorithm. */
+    private static final int M3 = 5;
+
+    /** Creates a new random number generator.
+     * <p>The instance is initialized using the current time as the
+     * seed.</p>
+     */
+    public Well512a() {
+        super(K, M1, M2, M3);
+    }
+
+    /** Creates a new random number generator using a single int seed.
+     * @param seed the initial seed (32 bits integer)
+     */
+    public Well512a(int seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using an int array seed.
+     * @param seed the initial seed (32 bits integers array), if null
+     * the seed of the generator will be related to the current time
+     */
+    public Well512a(int[] seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** Creates a new random number generator using a single long seed.
+     * @param seed the initial seed (64 bits integer)
+     */
+    public Well512a(long seed) {
+        super(K, M1, M2, M3, seed);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected int next(final int bits) {
+
+        final int indexRm1 = iRm1[index];
+
+        final int vi = v[index];
+        final int vi1 = v[i1[index]];
+        final int vi2 = v[i2[index]];
+        final int z0 = v[indexRm1];
+
+        // the values below include the errata of the original article
+        final int z1 = (vi ^ (vi << 16))   ^ (vi1 ^ (vi1 << 15));
+        final int z2 = vi2 ^ (vi2 >>> 11);
+        final int z3 = z1 ^ z2;
+        final int z4 = (z0 ^ (z0 << 2)) ^ (z1 ^ (z1 << 18)) ^ (z2 << 28) ^ (z3 ^ ((z3 << 5) & 0xda442d24));
+
+        v[index] = z3;
+        v[indexRm1]  = z4;
+        index    = indexRm1;
+
+        return z4 >>> (32 - bits);
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/random/package.html b/src/main/java/org/apache/commons/math/random/package.html
new file mode 100644
index 0000000..9978ca0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/random/package.html
@@ -0,0 +1,132 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $ -->
+    <body>
+      <p>Random number and random data generators.</p>
+      <p>Commons-math provides a few pseudo random number generators. The top level interface is RandomGenerator.
+      It is implemented by three classes:
+      <ul>
+        <li>{@link org.apache.commons.math.random.JDKRandomGenerator JDKRandomGenerator}
+            that extends the JDK provided generator</li>
+        <li>AbstractRandomGenerator as a helper for users generators</li>
+        <li>BitStreamGenerator which is an abstract class for several generators and
+            which in turn is extended by:
+            <ul>
+              <li>{@link org.apache.commons.math.random.MersenneTwister MersenneTwister}</li>
+              <li>{@link org.apache.commons.math.random.Well512a Well512a}</li>
+              <li>{@link org.apache.commons.math.random.Well1024a Well1024a}</li>
+              <li>{@link org.apache.commons.math.random.Well19937a Well19937a}</li>
+              <li>{@link org.apache.commons.math.random.Well19937c Well19937c}</li>
+              <li>{@link org.apache.commons.math.random.Well44497a Well44497a}</li>
+              <li>{@link org.apache.commons.math.random.Well44497b Well44497b}</li>
+            </ul>
+          </li>
+        </ul>
+      </p>
+
+      <p>
+      The JDK provided generator is a simple one that can be used only for very simple needs.
+      The Mersenne Twister is a fast generator with very good properties well suited for
+      Monte-Carlo simulation. It is equidistributed for generating vectors up to dimension 623
+      and has a huge period: 2<sup>19937</sup> - 1 (which is a Mersenne prime). This generator
+      is described in a paper by Makoto Matsumoto and Takuji Nishimura in 1998: <a
+      href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.pdf">Mersenne Twister:
+      A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator</a>, ACM
+      Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3--30.
+      The WELL generators are a family of generators with period ranging from 2<sup>512</sup> - 1
+      to 2<sup>44497</sup> - 1 (this last one is also a Mersenne prime) with even better properties
+      than Mersenne Twister. These generators are described in a paper by Fran&ccedil;ois Panneton,
+      Pierre L'Ecuyer and Makoto Matsumoto <a
+      href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved Long-Period
+      Generators Based on Linear Recurrences Modulo 2</a> ACM Transactions on Mathematical Software,
+      32, 1 (2006). The errata for the paper are in <a
+      href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.
+      </p>
+
+      <p>
+      For simple sampling, any of these generators is sufficient. For Monte-Carlo simulations the
+      JDK generator does not have any of the good mathematical properties of the other generators,
+      so it should be avoided. The Mersenne twister and WELL generators have equidistribution properties
+      proven according to their bits pool size which is directly linked to their period (all of them
+      have maximal period, i.e. a generator with size n pool has a period 2<sup>n</sup>-1). They also
+      have equidistribution properties for 32 bits blocks up to s/32 dimension where s is their pool size.
+      So WELL19937c for exemple is equidistributed up to dimension 623 (19937/32). This means a Monte-Carlo
+      simulation generating a vector of n variables at each iteration has some guarantees on the properties
+      of the vector as long as its dimension does not exceed the limit. However, since we use bits from two
+      successive 32 bits generated integers to create one double, this limit is smaller when the variables are
+      of type double. so for Monte-Carlo simulation where less the 16 doubles are generated at each round,
+      WELL1024 may be sufficient. If a larger number of doubles are needed a generator with a larger pool
+      would be useful.
+      </p>
+
+      <p>
+      The WELL generators are more modern then MersenneTwister (the paper describing than has been published
+      in 2006 instead of 1998) and fix some of its (few) drawbacks. If initialization array contains many
+      zero bits, MersenneTwister may take a very long time (several hundreds of thousands of iterations to
+      reach a steady state with a balanced number of zero and one in its bits pool). So the WELL generators
+      are better to <i>escape zeroland</i> as explained by the WELL generators creators. The Well19937a and
+      Well44497a generator are not maximally equidistributed (i.e. there are some dimensions or bits blocks
+      size for which they are not equidistributed). The Well512a, Well1024a, Well19937c and Well44497b are
+      maximally equidistributed for blocks size up to 32 bits (they should behave correctly also for double
+      based on more than 32 bits blocks, but equidistribution is not proven at these blocks sizes).
+      </p>
+
+      <p>
+      The MersenneTwister generator uses a 624 elements integer array, so it consumes less than 2.5 kilobytes.
+      The WELL generators use 6 integer arrays with a size equal to the pool size, so for example the
+      WELL44497b generator uses about 33 kilobytes. This may be important if a very large number of
+      generator instances were used at the same time.
+      </p>
+
+      <p>
+      All generators are quite fast. As an example, here are some comparisons, obtained on a 64 bits JVM on a
+      linux computer with a 2008 processor (AMD phenom Quad 9550 at 2.2 GHz). The generation rate for
+      MersenneTwister was about 27 millions doubles per second (remember we generate two 32 bits integers for
+      each double). Generation rates for other PRNG, relative to MersenneTwister:
+      </p>
+
+      <p>
+        <table border="1" align="center">
+          <tr BGCOLOR="#CCCCFF"><td colspan="2"><font size="+2">Example of performances</font></td></tr>
+          <tr BGCOLOR="#EEEEFF"><font size="+1"><td>Name</td><td>generation rate (relative to MersenneTwister)</td></font></tr>
+          <tr><td>{@link org.apache.commons.math.random.MersenneTwister MersenneTwister}</td><td>1</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.JDKRandomGenerator JDKRandomGenerator}</td><td>between 0.96 and 1.16</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.Well512a Well512a}</td><td>between 0.85 and 0.88</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.Well1024a Well1024a}</td><td>between 0.63 and 0.73</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.Well19937a Well19937a}</td><td>between 0.70 and 0.71</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.Well19937c Well19937c}</td><td>between 0.57 and 0.71</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.Well44497a Well44497a}</td><td>between 0.69 and 0.71</td></tr>
+          <tr><td>{@link org.apache.commons.math.random.Well44497b Well44497b}</td><td>between 0.65 and 0.71</td></tr>
+        </table>
+      </p>
+
+      <p>
+      So for most simulation problems, the better generators like {@link
+      org.apache.commons.math.random.Well19937c Well19937c} and {@link
+      org.apache.commons.math.random.Well44497b Well44497b} are probably very good choices.
+      </p>
+
+      <p>
+      Note that <em>none</em> of these generators are suitable for cryptography. They are devoted
+      to simulation, and to generate very long series with strong properties on the series as a whole
+      (equidistribution, no correlation ...). They do not attempt to create small series but with
+      very strong properties of unpredictability as needed in cryptography.
+      </p>
+
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/special/Beta.java b/src/main/java/org/apache/commons/math/special/Beta.java
new file mode 100644
index 0000000..6ab284f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/special/Beta.java
@@ -0,0 +1,202 @@
+/*
+ * 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.special;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.ContinuedFraction;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This is a utility class that provides computation methods related to the
+ * Beta family of functions.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public class Beta {
+
+    /** Maximum allowed numerical error. */
+    private static final double DEFAULT_EPSILON = 10e-15;
+
+    /**
+     * Default constructor.  Prohibit instantiation.
+     */
+    private Beta() {
+        super();
+    }
+
+    /**
+     * Returns the
+     * <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html">
+     * regularized beta function</a> I(x, a, b).
+     *
+     * @param x the value.
+     * @param a the a parameter.
+     * @param b the b parameter.
+     * @return the regularized beta function I(x, a, b)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedBeta(double x, double a, double b)
+        throws MathException
+    {
+        return regularizedBeta(x, a, b, DEFAULT_EPSILON, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Returns the
+     * <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html">
+     * regularized beta function</a> I(x, a, b).
+     *
+     * @param x the value.
+     * @param a the a parameter.
+     * @param b the b parameter.
+     * @param epsilon When the absolute value of the nth item in the
+     *                series is less than epsilon the approximation ceases
+     *                to calculate further elements in the series.
+     * @return the regularized beta function I(x, a, b)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedBeta(double x, double a, double b,
+        double epsilon) throws MathException
+    {
+        return regularizedBeta(x, a, b, epsilon, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Returns the regularized beta function I(x, a, b).
+     *
+     * @param x the value.
+     * @param a the a parameter.
+     * @param b the b parameter.
+     * @param maxIterations Maximum number of "iterations" to complete.
+     * @return the regularized beta function I(x, a, b)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedBeta(double x, double a, double b,
+        int maxIterations) throws MathException
+    {
+        return regularizedBeta(x, a, b, DEFAULT_EPSILON, maxIterations);
+    }
+
+    /**
+     * Returns the regularized beta function I(x, a, b).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html">
+     * Regularized Beta Function</a>.</li>
+     * <li>
+     * <a href="http://functions.wolfram.com/06.21.10.0001.01">
+     * Regularized Beta Function</a>.</li>
+     * </ul>
+     *
+     * @param x the value.
+     * @param a the a parameter.
+     * @param b the b parameter.
+     * @param epsilon When the absolute value of the nth item in the
+     *                series is less than epsilon the approximation ceases
+     *                to calculate further elements in the series.
+     * @param maxIterations Maximum number of "iterations" to complete.
+     * @return the regularized beta function I(x, a, b)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedBeta(double x, final double a,
+        final double b, double epsilon, int maxIterations) throws MathException
+    {
+        double ret;
+
+        if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b) || (x < 0) ||
+            (x > 1) || (a <= 0.0) || (b <= 0.0))
+        {
+            ret = Double.NaN;
+        } else if (x > (a + 1.0) / (a + b + 2.0)) {
+            ret = 1.0 - regularizedBeta(1.0 - x, b, a, epsilon, maxIterations);
+        } else {
+            ContinuedFraction fraction = new ContinuedFraction() {
+
+                @Override
+                protected double getB(int n, double x) {
+                    double ret;
+                    double m;
+                    if (n % 2 == 0) { // even
+                        m = n / 2.0;
+                        ret = (m * (b - m) * x) /
+                            ((a + (2 * m) - 1) * (a + (2 * m)));
+                    } else {
+                        m = (n - 1.0) / 2.0;
+                        ret = -((a + m) * (a + b + m) * x) /
+                                ((a + (2 * m)) * (a + (2 * m) + 1.0));
+                    }
+                    return ret;
+                }
+
+                @Override
+                protected double getA(int n, double x) {
+                    return 1.0;
+                }
+            };
+            ret = FastMath.exp((a * FastMath.log(x)) + (b * FastMath.log(1.0 - x)) -
+                FastMath.log(a) - logBeta(a, b, epsilon, maxIterations)) *
+                1.0 / fraction.evaluate(x, epsilon, maxIterations);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the natural logarithm of the beta function B(a, b).
+     *
+     * @param a the a parameter.
+     * @param b the b parameter.
+     * @return log(B(a, b))
+     */
+    public static double logBeta(double a, double b) {
+        return logBeta(a, b, DEFAULT_EPSILON, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Returns the natural logarithm of the beta function B(a, b).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li><a href="http://mathworld.wolfram.com/BetaFunction.html">
+     * Beta Function</a>, equation (1).</li>
+     * </ul>
+     *
+     * @param a the a parameter.
+     * @param b the b parameter.
+     * @param epsilon When the absolute value of the nth item in the
+     *                series is less than epsilon the approximation ceases
+     *                to calculate further elements in the series.
+     * @param maxIterations Maximum number of "iterations" to complete.
+     * @return log(B(a, b))
+     */
+    public static double logBeta(double a, double b, double epsilon,
+        int maxIterations) {
+
+        double ret;
+
+        if (Double.isNaN(a) || Double.isNaN(b) || (a <= 0.0) || (b <= 0.0)) {
+            ret = Double.NaN;
+        } else {
+            ret = Gamma.logGamma(a) + Gamma.logGamma(b) -
+                Gamma.logGamma(a + b);
+        }
+
+        return ret;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/special/Erf.java b/src/main/java/org/apache/commons/math/special/Erf.java
new file mode 100644
index 0000000..5abe18b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/special/Erf.java
@@ -0,0 +1,92 @@
+/*
+ * 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.special;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This is a utility class that provides computation methods related to the
+ * error functions.
+ *
+ * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $
+ */
+public class Erf {
+
+    /**
+     * Default constructor.  Prohibit instantiation.
+     */
+    private Erf() {
+        super();
+    }
+
+    /**
+     * <p>Returns the error function</p>
+     * <p>erf(x) = 2/&radic;&pi; <sub>0</sub>&int;<sup>x</sup> e<sup>-t<sup>2</sup></sup>dt </p>
+     *
+     * <p>This implementation computes erf(x) using the
+     * {@link Gamma#regularizedGammaP(double, double, double, int) regularized gamma function},
+     * following <a href="http://mathworld.wolfram.com/Erf.html"> Erf</a>, equation (3)</p>
+     *
+     * <p>The value returned is always between -1 and 1 (inclusive).  If {@code abs(x) > 40}, then
+     * {@code erf(x)} is indistinguishable from either 1 or -1 as a double, so the appropriate extreme
+     * value is returned.</p>
+     *
+     * @param x the value.
+     * @return the error function erf(x)
+     * @throws MathException if the algorithm fails to converge.
+     * @see Gamma#regularizedGammaP(double, double, double, int)
+     */
+    public static double erf(double x) throws MathException {
+        if (FastMath.abs(x) > 40) {
+            return x > 0 ? 1 : -1;
+        }
+        double ret = Gamma.regularizedGammaP(0.5, x * x, 1.0e-15, 10000);
+        if (x < 0) {
+            ret = -ret;
+        }
+        return ret;
+    }
+
+    /**
+     * <p>Returns the complementary error function</p>
+     * <p>erfc(x) = 2/&radic;&pi; <sub>x</sub>&int;<sup>&infin;</sup> e<sup>-t<sup>2</sup></sup>dt <br/>
+     *    = 1 - {@link #erf(double) erf(x)} </p>
+     *
+     * <p>This implementation computes erfc(x) using the
+     * {@link Gamma#regularizedGammaQ(double, double, double, int) regularized gamma function},
+     * following <a href="http://mathworld.wolfram.com/Erf.html"> Erf</a>, equation (3).</p>
+     *
+     * <p>The value returned is always between 0 and 2 (inclusive).  If {@code abs(x) > 40}, then
+     * {@code erf(x)} is indistinguishable from either 0 or 2 as a double, so the appropriate extreme
+     * value is returned.</p>
+     *
+     * @param x the value
+     * @return the complementary error function erfc(x)
+     * @throws MathException if the algorithm fails to converge
+     * @see Gamma#regularizedGammaQ(double, double, double, int)
+     * @since 2.2
+     */
+    public static double erfc(double x) throws MathException {
+        if (FastMath.abs(x) > 40) {
+            return x > 0 ? 0 : 2;
+        }
+        final double ret = Gamma.regularizedGammaQ(0.5, x * x, 1.0e-15, 10000);
+        return x < 0 ? 2 - ret : ret;
+    }
+}
+
diff --git a/src/main/java/org/apache/commons/math/special/Gamma.java b/src/main/java/org/apache/commons/math/special/Gamma.java
new file mode 100644
index 0000000..327aa3a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/special/Gamma.java
@@ -0,0 +1,339 @@
+/*
+ * 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.special;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.util.ContinuedFraction;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * This is a utility class that provides computation methods related to the
+ * Gamma family of functions.
+ *
+ * @version $Revision: 1042510 $ $Date: 2010-12-06 02:54:18 +0100 (lun. 06 déc. 2010) $
+ */
+public class Gamma {
+
+    /**
+     * <a href="http://en.wikipedia.org/wiki/Euler-Mascheroni_constant">Euler-Mascheroni constant</a>
+     * @since 2.0
+     */
+    public static final double GAMMA = 0.577215664901532860606512090082;
+
+    /** Maximum allowed numerical error. */
+    private static final double DEFAULT_EPSILON = 10e-15;
+
+    /** Lanczos coefficients */
+    private static final double[] LANCZOS =
+    {
+        0.99999999999999709182,
+        57.156235665862923517,
+        -59.597960355475491248,
+        14.136097974741747174,
+        -0.49191381609762019978,
+        .33994649984811888699e-4,
+        .46523628927048575665e-4,
+        -.98374475304879564677e-4,
+        .15808870322491248884e-3,
+        -.21026444172410488319e-3,
+        .21743961811521264320e-3,
+        -.16431810653676389022e-3,
+        .84418223983852743293e-4,
+        -.26190838401581408670e-4,
+        .36899182659531622704e-5,
+    };
+
+    /** Avoid repeated computation of log of 2 PI in logGamma */
+    private static final double HALF_LOG_2_PI = 0.5 * FastMath.log(2.0 * FastMath.PI);
+
+    // limits for switching algorithm in digamma
+    /** C limit. */
+    private static final double C_LIMIT = 49;
+
+    /** S limit. */
+    private static final double S_LIMIT = 1e-5;
+
+    /**
+     * Default constructor.  Prohibit instantiation.
+     */
+    private Gamma() {
+        super();
+    }
+
+    /**
+     * Returns the natural logarithm of the gamma function &#915;(x).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li><a href="http://mathworld.wolfram.com/GammaFunction.html">
+     * Gamma Function</a>, equation (28).</li>
+     * <li><a href="http://mathworld.wolfram.com/LanczosApproximation.html">
+     * Lanczos Approximation</a>, equations (1) through (5).</li>
+     * <li><a href="http://my.fit.edu/~gabdo/gamma.txt">Paul Godfrey, A note on
+     * the computation of the convergent Lanczos complex Gamma approximation
+     * </a></li>
+     * </ul>
+     *
+     * @param x the value.
+     * @return log(&#915;(x))
+     */
+    public static double logGamma(double x) {
+        double ret;
+
+        if (Double.isNaN(x) || (x <= 0.0)) {
+            ret = Double.NaN;
+        } else {
+            double g = 607.0 / 128.0;
+
+            double sum = 0.0;
+            for (int i = LANCZOS.length - 1; i > 0; --i) {
+                sum = sum + (LANCZOS[i] / (x + i));
+            }
+            sum = sum + LANCZOS[0];
+
+            double tmp = x + g + .5;
+            ret = ((x + .5) * FastMath.log(tmp)) - tmp +
+                HALF_LOG_2_PI + FastMath.log(sum / x);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the regularized gamma function P(a, x).
+     *
+     * @param a the a parameter.
+     * @param x the value.
+     * @return the regularized gamma function P(a, x)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedGammaP(double a, double x)
+        throws MathException
+    {
+        return regularizedGammaP(a, x, DEFAULT_EPSILON, Integer.MAX_VALUE);
+    }
+
+
+    /**
+     * Returns the regularized gamma function P(a, x).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html">
+     * Regularized Gamma Function</a>, equation (1).</li>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/IncompleteGammaFunction.html">
+     * Incomplete Gamma Function</a>, equation (4).</li>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/ConfluentHypergeometricFunctionoftheFirstKind.html">
+     * Confluent Hypergeometric Function of the First Kind</a>, equation (1).
+     * </li>
+     * </ul>
+     *
+     * @param a the a parameter.
+     * @param x the value.
+     * @param epsilon When the absolute value of the nth item in the
+     *                series is less than epsilon the approximation ceases
+     *                to calculate further elements in the series.
+     * @param maxIterations Maximum number of "iterations" to complete.
+     * @return the regularized gamma function P(a, x)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedGammaP(double a,
+                                           double x,
+                                           double epsilon,
+                                           int maxIterations)
+        throws MathException
+    {
+        double ret;
+
+        if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0) || (x < 0.0)) {
+            ret = Double.NaN;
+        } else if (x == 0.0) {
+            ret = 0.0;
+        } else if (x >= a + 1) {
+            // use regularizedGammaQ because it should converge faster in this
+            // case.
+            ret = 1.0 - regularizedGammaQ(a, x, epsilon, maxIterations);
+        } else {
+            // calculate series
+            double n = 0.0; // current element index
+            double an = 1.0 / a; // n-th element in the series
+            double sum = an; // partial sum
+            while (FastMath.abs(an/sum) > epsilon && n < maxIterations && sum < Double.POSITIVE_INFINITY) {
+                // compute next element in the series
+                n = n + 1.0;
+                an = an * (x / (a + n));
+
+                // update partial sum
+                sum = sum + an;
+            }
+            if (n >= maxIterations) {
+                throw new MaxIterationsExceededException(maxIterations);
+            } else if (Double.isInfinite(sum)) {
+                ret = 1.0;
+            } else {
+                ret = FastMath.exp(-x + (a * FastMath.log(x)) - logGamma(a)) * sum;
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * Returns the regularized gamma function Q(a, x) = 1 - P(a, x).
+     *
+     * @param a the a parameter.
+     * @param x the value.
+     * @return the regularized gamma function Q(a, x)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedGammaQ(double a, double x)
+        throws MathException
+    {
+        return regularizedGammaQ(a, x, DEFAULT_EPSILON, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Returns the regularized gamma function Q(a, x) = 1 - P(a, x).
+     *
+     * The implementation of this method is based on:
+     * <ul>
+     * <li>
+     * <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html">
+     * Regularized Gamma Function</a>, equation (1).</li>
+     * <li>
+     * <a href="http://functions.wolfram.com/GammaBetaErf/GammaRegularized/10/0003/">
+     * Regularized incomplete gamma function: Continued fraction representations  (formula 06.08.10.0003)</a></li>
+     * </ul>
+     *
+     * @param a the a parameter.
+     * @param x the value.
+     * @param epsilon When the absolute value of the nth item in the
+     *                series is less than epsilon the approximation ceases
+     *                to calculate further elements in the series.
+     * @param maxIterations Maximum number of "iterations" to complete.
+     * @return the regularized gamma function P(a, x)
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public static double regularizedGammaQ(final double a,
+                                           double x,
+                                           double epsilon,
+                                           int maxIterations)
+        throws MathException
+    {
+        double ret;
+
+        if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0) || (x < 0.0)) {
+            ret = Double.NaN;
+        } else if (x == 0.0) {
+            ret = 1.0;
+        } else if (x < a + 1.0) {
+            // use regularizedGammaP because it should converge faster in this
+            // case.
+            ret = 1.0 - regularizedGammaP(a, x, epsilon, maxIterations);
+        } else {
+            // create continued fraction
+            ContinuedFraction cf = new ContinuedFraction() {
+
+                @Override
+                protected double getA(int n, double x) {
+                    return ((2.0 * n) + 1.0) - a + x;
+                }
+
+                @Override
+                protected double getB(int n, double x) {
+                    return n * (a - n);
+                }
+            };
+
+            ret = 1.0 / cf.evaluate(x, epsilon, maxIterations);
+            ret = FastMath.exp(-x + (a * FastMath.log(x)) - logGamma(a)) * ret;
+        }
+
+        return ret;
+    }
+
+
+    /**
+     * <p>Computes the digamma function of x.</p>
+     *
+     * <p>This is an independently written implementation of the algorithm described in
+     * Jose Bernardo, Algorithm AS 103: Psi (Digamma) Function, Applied Statistics, 1976.</p>
+     *
+     * <p>Some of the constants have been changed to increase accuracy at the moderate expense
+     * of run-time.  The result should be accurate to within 10^-8 absolute tolerance for
+     * x >= 10^-5 and within 10^-8 relative tolerance for x > 0.</p>
+     *
+     * <p>Performance for large negative values of x will be quite expensive (proportional to
+     * |x|).  Accuracy for negative values of x should be about 10^-8 absolute for results
+     * less than 10^5 and 10^-8 relative for results larger than that.</p>
+     *
+     * @param x  the argument
+     * @return   digamma(x) to within 10-8 relative or absolute error whichever is smaller
+     * @see <a href="http://en.wikipedia.org/wiki/Digamma_function"> Digamma at wikipedia </a>
+     * @see <a href="http://www.uv.es/~bernardo/1976AppStatist.pdf"> Bernardo&apos;s original article </a>
+     * @since 2.0
+     */
+    public static double digamma(double x) {
+        if (x > 0 && x <= S_LIMIT) {
+            // use method 5 from Bernardo AS103
+            // accurate to O(x)
+            return -GAMMA - 1 / x;
+        }
+
+        if (x >= C_LIMIT) {
+            // use method 4 (accurate to O(1/x^8)
+            double inv = 1 / (x * x);
+            //            1       1        1         1
+            // log(x) -  --- - ------ + ------- - -------
+            //           2 x   12 x^2   120 x^4   252 x^6
+            return FastMath.log(x) - 0.5 / x - inv * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252));
+        }
+
+        return digamma(x + 1) - 1 / x;
+    }
+
+    /**
+     * <p>Computes the trigamma function of x.  This function is derived by taking the derivative of
+     * the implementation of digamma.</p>
+     *
+     * @param x  the argument
+     * @return   trigamma(x) to within 10-8 relative or absolute error whichever is smaller
+     * @see <a href="http://en.wikipedia.org/wiki/Trigamma_function"> Trigamma at wikipedia </a>
+     * @see Gamma#digamma(double)
+     * @since 2.0
+     */
+    public static double trigamma(double x) {
+        if (x > 0 && x <= S_LIMIT) {
+            return 1 / (x * x);
+        }
+
+        if (x >= C_LIMIT) {
+            double inv = 1 / (x * x);
+            //  1    1      1       1       1
+            //  - + ---- + ---- - ----- + -----
+            //  x      2      3       5       7
+            //      2 x    6 x    30 x    42 x
+            return 1 / x + inv / 2 + inv / x * (1.0 / 6 - inv * (1.0 / 30 + inv / 42));
+        }
+
+        return trigamma(x + 1) + 1 / (x * x);
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/special/package.html b/src/main/java/org/apache/commons/math/special/package.html
new file mode 100644
index 0000000..0676334
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/special/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Implementations of special functions such as Beta and Gamma.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/Frequency.java b/src/main/java/org/apache/commons/math/stat/Frequency.java
new file mode 100644
index 0000000..434819e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/Frequency.java
@@ -0,0 +1,603 @@
+/*
+ * 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.stat;
+
+import java.io.Serializable;
+import java.text.NumberFormat;
+import java.util.Iterator;
+import java.util.Comparator;
+import java.util.TreeMap;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Maintains a frequency distribution.
+ * <p>
+ * Accepts int, long, char or Comparable values.  New values added must be
+ * comparable to those that have been added, otherwise the add method will
+ * throw an IllegalArgumentException.</p>
+ * <p>
+ * Integer values (int, long, Integer, Long) are not distinguished by type --
+ * i.e. <code>addValue(Long.valueOf(2)), addValue(2), addValue(2l)</code> all have
+ * the same effect (similarly for arguments to <code>getCount,</code> etc.).</p>
+ * <p>
+ * char values are converted by <code>addValue</code> to Character instances.
+ * As such, these values are not comparable to integral values, so attempts
+ * to combine integral types with chars in a frequency distribution will fail.
+ * </p>
+ * <p>
+ * The values are ordered using the default (natural order), unless a
+ * <code>Comparator</code> is supplied in the constructor.</p>
+ *
+ * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $
+ */
+public class Frequency implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3845586908418844111L;
+
+    /** underlying collection */
+    private final TreeMap<Comparable<?>, Long> freqTable;
+
+    /**
+     * Default constructor.
+     */
+    public Frequency() {
+        freqTable = new TreeMap<Comparable<?>, Long>();
+    }
+
+    /**
+     * Constructor allowing values Comparator to be specified.
+     *
+     * @param comparator Comparator used to order values
+     */
+    @SuppressWarnings("unchecked") // TODO is the cast OK?
+    public Frequency(Comparator<?> comparator) {
+        freqTable = new TreeMap<Comparable<?>, Long>((Comparator<? super Comparable<?>>) comparator);
+    }
+
+    /**
+     * Return a string representation of this frequency
+     * distribution.
+     *
+     * @return a string representation.
+     */
+    @Override
+    public String toString() {
+        NumberFormat nf = NumberFormat.getPercentInstance();
+        StringBuilder outBuffer = new StringBuilder();
+        outBuffer.append("Value \t Freq. \t Pct. \t Cum Pct. \n");
+        Iterator<Comparable<?>> iter = freqTable.keySet().iterator();
+        while (iter.hasNext()) {
+            Comparable<?> value = iter.next();
+            outBuffer.append(value);
+            outBuffer.append('\t');
+            outBuffer.append(getCount(value));
+            outBuffer.append('\t');
+            outBuffer.append(nf.format(getPct(value)));
+            outBuffer.append('\t');
+            outBuffer.append(nf.format(getCumPct(value)));
+            outBuffer.append('\n');
+        }
+        return outBuffer.toString();
+    }
+
+    /**
+     * Adds 1 to the frequency count for v.
+     * <p>
+     * If other objects have already been added to this Frequency, v must
+     * be comparable to those that have already been added.
+     * </p>
+     *
+     * @param v the value to add.
+     * @throws IllegalArgumentException if <code>v</code> is not Comparable,
+     *         or is not comparable with previous entries
+     * @deprecated use {@link #addValue(Comparable)} instead
+     */
+    @Deprecated
+    public void addValue(Object v) {
+        if (v instanceof Comparable<?>){
+            addValue((Comparable<?>) v);
+        } else {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.CLASS_DOESNT_IMPLEMENT_COMPARABLE,
+                  v.getClass().getName());
+        }
+    }
+
+    /**
+     * Adds 1 to the frequency count for v.
+     * <p>
+     * If other objects have already been added to this Frequency, v must
+     * be comparable to those that have already been added.
+     * </p>
+     *
+     * @param v the value to add.
+     * @throws IllegalArgumentException if <code>v</code> is not comparable with previous entries
+     */
+    public void addValue(Comparable<?> v){
+        Comparable<?> obj = v;
+        if (v instanceof Integer) {
+           obj = Long.valueOf(((Integer) v).longValue());
+        }
+        try {
+            Long count = freqTable.get(obj);
+            if (count == null) {
+                freqTable.put(obj, Long.valueOf(1));
+            } else {
+                freqTable.put(obj, Long.valueOf(count.longValue() + 1));
+            }
+        } catch (ClassCastException ex) {
+            //TreeMap will throw ClassCastException if v is not comparable
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSTANCES_NOT_COMPARABLE_TO_EXISTING_VALUES,
+                  v.getClass().getName());
+        }
+    }
+
+    /**
+     * Adds 1 to the frequency count for v.
+     *
+     * @param v the value to add.
+     */
+    public void addValue(int v) {
+        addValue(Long.valueOf(v));
+    }
+
+    /**
+     * Adds 1 to the frequency count for v.
+     *
+     * @param v the value to add.
+     * @deprecated to be removed in math 3.0
+     */
+    @Deprecated
+    public void addValue(Integer v) {
+        addValue(Long.valueOf(v.longValue()));
+    }
+
+    /**
+     * Adds 1 to the frequency count for v.
+     *
+     * @param v the value to add.
+     */
+    public void addValue(long v) {
+        addValue(Long.valueOf(v));
+    }
+
+    /**
+     * Adds 1 to the frequency count for v.
+     *
+     * @param v the value to add.
+     */
+    public void addValue(char v) {
+        addValue(Character.valueOf(v));
+    }
+
+    /** Clears the frequency table */
+    public void clear() {
+        freqTable.clear();
+    }
+
+    /**
+     * Returns an Iterator over the set of values that have been added.
+     * <p>
+     * If added values are integral (i.e., integers, longs, Integers, or Longs),
+     * they are converted to Longs when they are added, so the objects returned
+     * by the Iterator will in this case be Longs.</p>
+     *
+     * @return values Iterator
+     */
+    public Iterator<Comparable<?>> valuesIterator() {
+        return freqTable.keySet().iterator();
+    }
+
+    //-------------------------------------------------------------------------
+
+    /**
+     * Returns the sum of all frequencies.
+     *
+     * @return the total frequency count.
+     */
+    public long getSumFreq() {
+        long result = 0;
+        Iterator<Long> iterator = freqTable.values().iterator();
+        while (iterator.hasNext())  {
+            result += iterator.next().longValue();
+        }
+        return result;
+    }
+
+    /**
+     * Returns the number of values = v.
+     * Returns 0 if the value is not comparable.
+     *
+     * @param v the value to lookup.
+     * @return the frequency of v.
+     * @deprecated replaced by {@link #getCount(Comparable)} as of 2.0
+     */
+    @Deprecated
+    public long getCount(Object v) {
+        return getCount((Comparable<?>) v);
+    }
+
+    /**
+     * Returns the number of values = v.
+     * Returns 0 if the value is not comparable.
+     *
+     * @param v the value to lookup.
+     * @return the frequency of v.
+     */
+    public long getCount(Comparable<?> v) {
+        if (v instanceof Integer) {
+            return getCount(((Integer) v).longValue());
+        }
+        long result = 0;
+        try {
+            Long count =  freqTable.get(v);
+            if (count != null) {
+                result = count.longValue();
+            }
+        } catch (ClassCastException ex) {
+            // ignore and return 0 -- ClassCastException will be thrown if value is not comparable
+        }
+        return result;
+    }
+
+    /**
+     * Returns the number of values = v.
+     *
+     * @param v the value to lookup.
+     * @return the frequency of v.
+     */
+    public long getCount(int v) {
+        return getCount(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the number of values = v.
+     *
+     * @param v the value to lookup.
+     * @return the frequency of v.
+     */
+    public long getCount(long v) {
+        return getCount(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the number of values = v.
+     *
+     * @param v the value to lookup.
+     * @return the frequency of v.
+     */
+    public long getCount(char v) {
+        return getCount(Character.valueOf(v));
+    }
+
+    /**
+     * Returns the number of values in the frequency table.
+     *
+     * @return the number of unique values that have been added to the frequency table.
+     * @see #valuesIterator()
+     */
+    public int getUniqueCount(){
+        return freqTable.keySet().size();
+    }
+
+    //-------------------------------------------------------------
+
+    /**
+      * Returns the percentage of values that are equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns <code>Double.NaN</code> if no values have been added.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     * @deprecated replaced by {@link #getPct(Comparable)} as of 2.0
+     */
+    @Deprecated
+    public double getPct(Object v) {
+        return getPct((Comparable<?>) v);
+    }
+
+    /**
+     * Returns the percentage of values that are equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns <code>Double.NaN</code> if no values have been added.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public double getPct(Comparable<?> v) {
+        final long sumFreq = getSumFreq();
+        if (sumFreq == 0) {
+            return Double.NaN;
+        }
+        return (double) getCount(v) / (double) sumFreq;
+    }
+
+    /**
+     * Returns the percentage of values that are equal to v
+     * (as a proportion between 0 and 1).
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public double getPct(int v) {
+        return getPct(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the percentage of values that are equal to v
+     * (as a proportion between 0 and 1).
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public double getPct(long v) {
+        return getPct(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the percentage of values that are equal to v
+     * (as a proportion between 0 and 1).
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public double getPct(char v) {
+        return getPct(Character.valueOf(v));
+    }
+
+    //-----------------------------------------------------------------------------------------
+
+    /**
+     * Returns the cumulative frequency of values less than or equal to v.
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup.
+     * @return the proportion of values equal to v
+     * @deprecated replaced by {@link #getCumFreq(Comparable)} as of 2.0
+     */
+    @Deprecated
+    public long getCumFreq(Object v) {
+        return getCumFreq((Comparable<?>) v);
+    }
+
+    /**
+     * Returns the cumulative frequency of values less than or equal to v.
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup.
+     * @return the proportion of values equal to v
+     */
+    public long getCumFreq(Comparable<?> v) {
+        if (getSumFreq() == 0) {
+            return 0;
+        }
+        if (v instanceof Integer) {
+            return getCumFreq(((Integer) v).longValue());
+        }
+        @SuppressWarnings("unchecked") // OK, freqTable is Comparable<?>
+        Comparator<Comparable<?>> c = (Comparator<Comparable<?>>) freqTable.comparator();
+        if (c == null) {
+            c = new NaturalComparator();
+        }
+        long result = 0;
+
+        try {
+            Long value = freqTable.get(v);
+            if (value != null) {
+                result = value.longValue();
+            }
+        } catch (ClassCastException ex) {
+            return result;   // v is not comparable
+        }
+
+        if (c.compare(v, freqTable.firstKey()) < 0) {
+            return 0;  // v is comparable, but less than first value
+        }
+
+        if (c.compare(v, freqTable.lastKey()) >= 0) {
+            return getSumFreq();    // v is comparable, but greater than the last value
+        }
+
+        Iterator<Comparable<?>> values = valuesIterator();
+        while (values.hasNext()) {
+            Comparable<?> nextValue = values.next();
+            if (c.compare(v, nextValue) > 0) {
+                result += getCount(nextValue);
+            } else {
+                return result;
+            }
+        }
+        return result;
+    }
+
+     /**
+     * Returns the cumulative frequency of values less than or equal to v.
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public long getCumFreq(int v) {
+        return getCumFreq(Long.valueOf(v));
+    }
+
+     /**
+     * Returns the cumulative frequency of values less than or equal to v.
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public long getCumFreq(long v) {
+        return getCumFreq(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the cumulative frequency of values less than or equal to v.
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values equal to v
+     */
+    public long getCumFreq(char v) {
+        return getCumFreq(Character.valueOf(v));
+    }
+
+    //----------------------------------------------------------------------------------------------
+
+    /**
+     * Returns the cumulative percentage of values less than or equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns <code>Double.NaN</code> if no values have been added.
+     * Returns 0 if at least one value has been added, but v is not comparable
+     * to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values less than or equal to v
+     * @deprecated replaced by {@link #getCumPct(Comparable)} as of 2.0
+     */
+    @Deprecated
+    public double getCumPct(Object v) {
+        return getCumPct((Comparable<?>) v);
+
+    }
+
+    /**
+     * Returns the cumulative percentage of values less than or equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns <code>Double.NaN</code> if no values have been added.
+     * Returns 0 if at least one value has been added, but v is not comparable
+     * to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values less than or equal to v
+     */
+    public double getCumPct(Comparable<?> v) {
+        final long sumFreq = getSumFreq();
+        if (sumFreq == 0) {
+            return Double.NaN;
+        }
+        return (double) getCumFreq(v) / (double) sumFreq;
+    }
+
+    /**
+     * Returns the cumulative percentage of values less than or equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values less than or equal to v
+     */
+    public double getCumPct(int v) {
+        return getCumPct(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the cumulative percentage of values less than or equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values less than or equal to v
+     */
+    public double getCumPct(long v) {
+        return getCumPct(Long.valueOf(v));
+    }
+
+    /**
+     * Returns the cumulative percentage of values less than or equal to v
+     * (as a proportion between 0 and 1).
+     * <p>
+     * Returns 0 if v is not comparable to the values set.</p>
+     *
+     * @param v the value to lookup
+     * @return the proportion of values less than or equal to v
+     */
+    public double getCumPct(char v) {
+        return getCumPct(Character.valueOf(v));
+    }
+
+    /**
+     * A Comparator that compares comparable objects using the
+     * natural order.  Copied from Commons Collections ComparableComparator.
+     */
+    private static class NaturalComparator<T extends Comparable<T>> implements Comparator<Comparable<T>>, Serializable {
+
+        /** Serializable version identifier */
+        private static final long serialVersionUID = -3852193713161395148L;
+
+        /**
+         * Compare the two {@link Comparable Comparable} arguments.
+         * This method is equivalent to:
+         * <pre>(({@link Comparable Comparable})o1).{@link Comparable#compareTo compareTo}(o2)</pre>
+         *
+         * @param  o1 the first object
+         * @param  o2 the second object
+         * @return  result of comparison
+         * @throws NullPointerException when <i>o1</i> is <code>null</code>,
+         *         or when <code>((Comparable)o1).compareTo(o2)</code> does
+         * @throws ClassCastException when <i>o1</i> is not a {@link Comparable Comparable},
+         *         or when <code>((Comparable)o1).compareTo(o2)</code> does
+         */
+        @SuppressWarnings("unchecked") // cast to (T) may throw ClassCastException, see Javadoc
+        public int compare(Comparable<T> o1, Comparable<T> o2) {
+            return o1.compareTo((T) o2);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result +
+                 ((freqTable == null) ? 0 : freqTable.hashCode());
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof Frequency))
+            return false;
+        Frequency other = (Frequency) obj;
+        if (freqTable == null) {
+            if (other.freqTable != null)
+                return false;
+        } else if (!freqTable.equals(other.freqTable))
+            return false;
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/StatUtils.java b/src/main/java/org/apache/commons/math/stat/StatUtils.java
new file mode 100644
index 0000000..7ae1e17
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/StatUtils.java
@@ -0,0 +1,663 @@
+/*
+ * 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.stat;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
+import org.apache.commons.math.stat.descriptive.UnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.moment.GeometricMean;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.Variance;
+import org.apache.commons.math.stat.descriptive.rank.Max;
+import org.apache.commons.math.stat.descriptive.rank.Min;
+import org.apache.commons.math.stat.descriptive.rank.Percentile;
+import org.apache.commons.math.stat.descriptive.summary.Product;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
+import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
+
+/**
+ * StatUtils provides static methods for computing statistics based on data
+ * stored in double[] arrays.
+ *
+ * @version $Revision: 1073276 $ $Date: 2011-02-22 10:34:52 +0100 (mar. 22 févr. 2011) $
+ */
+public final class StatUtils {
+
+    /** sum */
+    private static final UnivariateStatistic SUM = new Sum();
+
+    /** sumSq */
+    private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares();
+
+    /** prod */
+    private static final UnivariateStatistic PRODUCT = new Product();
+
+    /** sumLog */
+    private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs();
+
+    /** min */
+    private static final UnivariateStatistic MIN = new Min();
+
+    /** max */
+    private static final UnivariateStatistic MAX = new Max();
+
+    /** mean */
+    private static final UnivariateStatistic MEAN = new Mean();
+
+    /** variance */
+    private static final Variance VARIANCE = new Variance();
+
+    /** percentile */
+    private static final Percentile PERCENTILE = new Percentile();
+
+    /** geometric mean */
+    private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean();
+
+    /**
+     * Private Constructor
+     */
+    private StatUtils() {
+    }
+
+    /**
+     * Returns the sum of the values in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the input array
+     * is null.</p>
+     *
+     * @param values  array of values to sum
+     * @return the sum of the values or <code>Double.NaN</code> if the array
+     * is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double sum(final double[] values) {
+        return SUM.evaluate(values);
+    }
+
+    /**
+     * Returns the sum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    public static double sum(final double[] values, final int begin,
+            final int length) {
+        return SUM.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns the sum of the squares of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values  input array
+     * @return the sum of the squared values or <code>Double.NaN</code> if the
+     * array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double sumSq(final double[] values) {
+        return SUM_OF_SQUARES.evaluate(values);
+    }
+
+    /**
+     * Returns the sum of the squares of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the squares of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double sumSq(final double[] values, final int begin,
+            final int length) {
+        return SUM_OF_SQUARES.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns the product of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @return the product of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double product(final double[] values) {
+        return PRODUCT.evaluate(values);
+    }
+
+    /**
+     * Returns the product of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the product of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double product(final double[] values, final int begin,
+            final int length) {
+        return PRODUCT.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns the sum of the natural logs of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.summary.SumOfLogs}.
+     * </p>
+     *
+     * @param values the input array
+     * @return the sum of the natural logs of the values or Double.NaN if
+     * the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double sumLog(final double[] values) {
+        return SUM_OF_LOGS.evaluate(values);
+    }
+
+    /**
+     * Returns the sum of the natural logs of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.summary.SumOfLogs}.
+     * </p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the natural logs of the values or Double.NaN if
+     * length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double sumLog(final double[] values, final int begin,
+            final int length) {
+        return SUM_OF_LOGS.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns the arithmetic mean of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.Mean} for
+     * details on the computing algorithm.</p>
+     *
+     * @param values the input array
+     * @return the mean of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double mean(final double[] values) {
+        return MEAN.evaluate(values);
+    }
+
+    /**
+     * Returns the arithmetic mean of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.Mean} for
+     * details on the computing algorithm.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the mean of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double mean(final double[] values, final int begin,
+            final int length) {
+        return MEAN.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns the geometric mean of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.GeometricMean}
+     * for details on the computing algorithm.</p>
+     *
+     * @param values the input array
+     * @return the geometric mean of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double geometricMean(final double[] values) {
+        return GEOMETRIC_MEAN.evaluate(values);
+    }
+
+    /**
+     * Returns the geometric mean of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.GeometricMean}
+     * for details on the computing algorithm.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the geometric mean of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double geometricMean(final double[] values, final int begin,
+            final int length) {
+        return GEOMETRIC_MEAN.evaluate(values, begin, length);
+    }
+
+
+    /**
+     * Returns the variance of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for
+     * details on the computing algorithm.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @return the variance of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double variance(final double[] values) {
+        return VARIANCE.evaluate(values);
+    }
+
+    /**
+     * Returns the variance of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for
+     * details on the computing algorithm.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null or the
+     * array index parameters are not valid.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    public static double variance(final double[] values, final int begin,
+            final int length) {
+        return VARIANCE.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns the variance of the entries in the specified portion of
+     * the input array, using the precomputed mean value.  Returns
+     * <code>Double.NaN</code> if the designated subarray is empty.
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for
+     * details on the computing algorithm.</p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the arithmetic
+     * mean of the sample data, not a known population parameter.  This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null or the
+     * array index parameters are not valid.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    public static double variance(final double[] values, final double mean,
+            final int begin, final int length) {
+        return VARIANCE.evaluate(values, mean, begin, length);
+    }
+
+    /**
+     * Returns the variance of the entries in the input array, using the
+     * precomputed mean value.  Returns <code>Double.NaN</code> if the array
+     * is empty.
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for
+     * details on the computing algorithm.</p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the arithmetic
+     * mean of the sample data, not a known population parameter.  This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @return the variance of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double variance(final double[] values, final double mean) {
+        return VARIANCE.evaluate(values, mean);
+    }
+
+    /**
+     * Returns the maximum of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * <ul>
+     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+     * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
+     * the result is <code>Double.POSITIVE_INFINITY.</code></li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @return the maximum of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double max(final double[] values) {
+        return MAX.evaluate(values);
+    }
+
+    /**
+     * Returns the maximum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null or
+     * the array index parameters are not valid.</p>
+     * <p>
+     * <ul>
+     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+     * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
+     * the result is <code>Double.POSITIVE_INFINITY.</code></li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the maximum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double max(final double[] values, final int begin,
+            final int length) {
+        return MAX.evaluate(values, begin, length);
+    }
+
+     /**
+     * Returns the minimum of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * <ul>
+     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+     * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
+     * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
+     * </ul> </p>
+     *
+     * @param values the input array
+     * @return the minimum of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public static double min(final double[] values) {
+        return MIN.evaluate(values);
+    }
+
+     /**
+     * Returns the minimum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null or
+     * the array index parameters are not valid.</p>
+     * <p>
+     * <ul>
+     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+     * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
+     * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the minimum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     * parameters are not valid
+     */
+    public static double min(final double[] values, final int begin,
+            final int length) {
+        return MIN.evaluate(values, begin, length);
+    }
+
+    /**
+     * Returns an estimate of the <code>p</code>th percentile of the values
+     * in the <code>values</code> array.
+     * <p>
+     * <ul>
+     * <li>Returns <code>Double.NaN</code> if <code>values</code> has length
+     * <code>0</code></li></p>
+     * <li>Returns (for any value of <code>p</code>) <code>values[0]</code>
+     *  if <code>values</code> has length <code>1</code></li>
+     * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
+     * is null  or p is not a valid quantile value (p must be greater than 0
+     * and less than or equal to 100)</li>
+     * </ul></p>
+     * <p>
+     * See {@link org.apache.commons.math.stat.descriptive.rank.Percentile} for
+     * a description of the percentile estimation algorithm used.</p>
+     *
+     * @param values input array of values
+     * @param p the percentile value to compute
+     * @return the percentile value or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if <code>values</code> is null
+     * or p is invalid
+     */
+    public static double percentile(final double[] values, final double p) {
+            return PERCENTILE.evaluate(values,p);
+    }
+
+     /**
+     * Returns an estimate of the <code>p</code>th percentile of the values
+     * in the <code>values</code> array, starting with the element in (0-based)
+     * position <code>begin</code> in the array and including <code>length</code>
+     * values.
+     * <p>
+     * <ul>
+     * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li>
+     * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code>
+     *  if <code>length = 1 </code></li>
+     * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
+     *  is null , <code>begin</code> or <code>length</code> is invalid, or
+     * <code>p</code> is not a valid quantile value (p must be greater than 0
+     * and less than or equal to 100)</li>
+     * </ul></p>
+     * <p>
+      * See {@link org.apache.commons.math.stat.descriptive.rank.Percentile} for
+      * a description of the percentile estimation algorithm used.</p>
+     *
+     * @param values array of input values
+     * @param p  the percentile to compute
+     * @param begin  the first (0-based) element to include in the computation
+     * @param length  the number of array elements to include
+     * @return  the percentile value
+     * @throws IllegalArgumentException if the parameters are not valid or the
+     * input array is null
+     */
+    public static double percentile(final double[] values, final int begin,
+            final int length, final double p) {
+        return PERCENTILE.evaluate(values, begin, length, p);
+    }
+
+    /**
+     * Returns the sum of the (signed) differences between corresponding elements of the
+     * input arrays -- i.e., sum(sample1[i] - sample2[i]).
+     *
+     * @param sample1  the first array
+     * @param sample2  the second array
+     * @return sum of paired differences
+     * @throws IllegalArgumentException if the arrays do not have the same
+     * (positive) length
+     */
+    public static double sumDifference(final double[] sample1, final double[] sample2)
+        throws IllegalArgumentException {
+        int n = sample1.length;
+        if (n  != sample2.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, n, sample2.length);
+        }
+        if (n < 1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, sample2.length, 1);
+        }
+        double result = 0;
+        for (int i = 0; i < n; i++) {
+            result += sample1[i] - sample2[i];
+        }
+        return result;
+    }
+
+    /**
+     * Returns the mean of the (signed) differences between corresponding elements of the
+     * input arrays -- i.e., sum(sample1[i] - sample2[i]) / sample1.length.
+     *
+     * @param sample1  the first array
+     * @param sample2  the second array
+     * @return mean of paired differences
+     * @throws IllegalArgumentException if the arrays do not have the same
+     * (positive) length
+     */
+    public static double meanDifference(final double[] sample1, final double[] sample2)
+    throws IllegalArgumentException {
+        return sumDifference(sample1, sample2) / sample1.length;
+    }
+
+    /**
+     * Returns the variance of the (signed) differences between corresponding elements of the
+     * input arrays -- i.e., var(sample1[i] - sample2[i]).
+     *
+     * @param sample1  the first array
+     * @param sample2  the second array
+     * @param meanDifference   the mean difference between corresponding entries
+     * @see #meanDifference(double[],double[])
+     * @return variance of paired differences
+     * @throws IllegalArgumentException if the arrays do not have the same
+     * length or their common length is less than 2.
+     */
+    public static double varianceDifference(final double[] sample1, final double[] sample2,
+            double meanDifference)  throws IllegalArgumentException {
+        double sum1 = 0d;
+        double sum2 = 0d;
+        double diff = 0d;
+        int n = sample1.length;
+        if (n != sample2.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, n, sample2.length);
+        }
+        if (n < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, n, 2);
+        }
+        for (int i = 0; i < n; i++) {
+            diff = sample1[i] - sample2[i];
+            sum1 += (diff - meanDifference) *(diff - meanDifference);
+            sum2 += diff - meanDifference;
+        }
+        return (sum1 - (sum2 * sum2 / n)) / (n - 1);
+    }
+
+
+    /**
+     * Normalize (standardize) the series, so in the end it is having a mean of 0 and a standard deviation of 1.
+     *
+     * @param sample sample to normalize
+     * @return normalized (standardized) sample
+     * @since 2.2
+     */
+    public static double[] normalize(final double[] sample) {
+        DescriptiveStatistics stats = new DescriptiveStatistics();
+
+        // Add the data from the series to stats
+        for (int i = 0; i < sample.length; i++) {
+            stats.addValue(sample[i]);
+        }
+
+        // Compute mean and standard deviation
+        double mean = stats.getMean();
+        double standardDeviation = stats.getStandardDeviation();
+
+        // initialize the standardizedSample, which has the same length as the sample
+        double[] standardizedSample = new double[sample.length];
+
+        for (int i = 0; i < sample.length; i++) {
+            // z = (x- mean)/standardDeviation
+            standardizedSample[i] = (sample[i] - mean) / standardDeviation;
+        }
+        return standardizedSample;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/clustering/Cluster.java b/src/main/java/org/apache/commons/math/stat/clustering/Cluster.java
new file mode 100644
index 0000000..f4913d3
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/clustering/Cluster.java
@@ -0,0 +1,74 @@
+/*
+ * 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.stat.clustering;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Cluster holding a set of {@link Clusterable} points.
+ * @param <T> the type of points that can be clustered
+ * @version $Revision: 771076 $ $Date: 2009-05-03 18:28:48 +0200 (dim. 03 mai 2009) $
+ * @since 2.0
+ */
+public class Cluster<T extends Clusterable<T>> implements Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -3442297081515880464L;
+
+    /** The points contained in this cluster. */
+    private final List<T> points;
+
+    /** Center of the cluster. */
+    private final T center;
+
+    /**
+     * Build a cluster centered at a specified point.
+     * @param center the point which is to be the center of this cluster
+     */
+    public Cluster(final T center) {
+        this.center = center;
+        points = new ArrayList<T>();
+    }
+
+    /**
+     * Add a point to this cluster.
+     * @param point point to add
+     */
+    public void addPoint(final T point) {
+        points.add(point);
+    }
+
+    /**
+     * Get the points contained in the cluster.
+     * @return points contained in the cluster
+     */
+    public List<T> getPoints() {
+        return points;
+    }
+
+    /**
+     * Get the point chosen to be the center of this cluster.
+     * @return chosen cluster center
+     */
+    public T getCenter() {
+        return center;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/clustering/Clusterable.java b/src/main/java/org/apache/commons/math/stat/clustering/Clusterable.java
new file mode 100644
index 0000000..65132e6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/clustering/Clusterable.java
@@ -0,0 +1,46 @@
+/*
+ * 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.stat.clustering;
+
+import java.util.Collection;
+
+/**
+ * Interface for points that can be clustered together.
+ * @param <T> the type of point that can be clustered
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface Clusterable<T> {
+
+    /**
+     * Returns the distance from the given point.
+     *
+     * @param p the point to compute the distance from
+     * @return the distance from the given point
+     */
+    double distanceFrom(T p);
+
+    /**
+     * Returns the centroid of the given Collection of points.
+     *
+     * @param p the Collection of points to compute the centroid of
+     * @return the centroid of the given Collection of Points
+     */
+    T centroidOf(Collection<T> p);
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.java b/src/main/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.java
new file mode 100644
index 0000000..7fec0ff
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.java
@@ -0,0 +1,120 @@
+/*
+ * 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.stat.clustering;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ * A simple implementation of {@link Clusterable} for points with integer coordinates.
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ * @since 2.0
+ */
+public class EuclideanIntegerPoint implements Clusterable<EuclideanIntegerPoint>, Serializable {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 3946024775784901369L;
+
+    /** Point coordinates. */
+    private final int[] point;
+
+    /**
+     * Build an instance wrapping an integer array.
+     * <p>The wrapped array is referenced, it is <em>not</em> copied.</p>
+     * @param point the n-dimensional point in integer space
+     */
+    public EuclideanIntegerPoint(final int[] point) {
+        this.point = point;
+    }
+
+    /**
+     * Get the n-dimensional point in integer space.
+     * @return a reference (not a copy!) to the wrapped array
+     */
+    public int[] getPoint() {
+        return point;
+    }
+
+    /** {@inheritDoc} */
+    public double distanceFrom(final EuclideanIntegerPoint p) {
+        return MathUtils.distance(point, p.getPoint());
+    }
+
+    /** {@inheritDoc} */
+    public EuclideanIntegerPoint centroidOf(final Collection<EuclideanIntegerPoint> points) {
+        int[] centroid = new int[getPoint().length];
+        for (EuclideanIntegerPoint p : points) {
+            for (int i = 0; i < centroid.length; i++) {
+                centroid[i] += p.getPoint()[i];
+            }
+        }
+        for (int i = 0; i < centroid.length; i++) {
+            centroid[i] /= points.size();
+        }
+        return new EuclideanIntegerPoint(centroid);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(final Object other) {
+        if (!(other instanceof EuclideanIntegerPoint)) {
+            return false;
+        }
+        final int[] otherPoint = ((EuclideanIntegerPoint) other).getPoint();
+        if (point.length != otherPoint.length) {
+            return false;
+        }
+        for (int i = 0; i < point.length; i++) {
+            if (point[i] != otherPoint[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        int hashCode = 0;
+        for (Integer i : point) {
+            hashCode += i.hashCode() * 13 + 7;
+        }
+        return hashCode;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @since 2.1
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buff = new StringBuilder("(");
+        final int[] coordinates = getPoint();
+        for (int i = 0; i < coordinates.length; i++) {
+            buff.append(coordinates[i]);
+            if (i < coordinates.length - 1) {
+                buff.append(",");
+            }
+        }
+        buff.append(")");
+        return buff.toString();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.java b/src/main/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.java
new file mode 100644
index 0000000..eb61866
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.java
@@ -0,0 +1,333 @@
+/*
+ * 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.stat.clustering;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.commons.math.exception.ConvergenceException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.moment.Variance;
+
+/**
+ * Clustering algorithm based on David Arthur and Sergei Vassilvitski k-means++ algorithm.
+ * @param <T> type of the points to cluster
+ * @see <a href="http://en.wikipedia.org/wiki/K-means%2B%2B">K-means++ (wikipedia)</a>
+ * @version $Revision: 1054333 $ $Date: 2011-01-02 01:34:58 +0100 (dim. 02 janv. 2011) $
+ * @since 2.0
+ */
+public class KMeansPlusPlusClusterer<T extends Clusterable<T>> {
+
+    /** Strategies to use for replacing an empty cluster. */
+    public static enum EmptyClusterStrategy {
+
+        /** Split the cluster with largest distance variance. */
+        LARGEST_VARIANCE,
+
+        /** Split the cluster with largest number of points. */
+        LARGEST_POINTS_NUMBER,
+
+        /** Create a cluster around the point farthest from its centroid. */
+        FARTHEST_POINT,
+
+        /** Generate an error. */
+        ERROR
+
+    }
+
+    /** Random generator for choosing initial centers. */
+    private final Random random;
+
+    /** Selected strategy for empty clusters. */
+    private final EmptyClusterStrategy emptyStrategy;
+
+    /** Build a clusterer.
+     * <p>
+     * The default strategy for handling empty clusters that may appear during
+     * algorithm iterations is to split the cluster with largest distance variance.
+     * </p>
+     * @param random random generator to use for choosing initial centers
+     */
+    public KMeansPlusPlusClusterer(final Random random) {
+        this(random, EmptyClusterStrategy.LARGEST_VARIANCE);
+    }
+
+    /** Build a clusterer.
+     * @param random random generator to use for choosing initial centers
+     * @param emptyStrategy strategy to use for handling empty clusters that
+     * may appear during algorithm iterations
+     * @since 2.2
+     */
+    public KMeansPlusPlusClusterer(final Random random, final EmptyClusterStrategy emptyStrategy) {
+        this.random        = random;
+        this.emptyStrategy = emptyStrategy;
+    }
+
+    /**
+     * Runs the K-means++ clustering algorithm.
+     *
+     * @param points the points to cluster
+     * @param k the number of clusters to split the data into
+     * @param maxIterations the maximum number of iterations to run the algorithm
+     *     for.  If negative, no maximum will be used
+     * @return a list of clusters containing the points
+     */
+    public List<Cluster<T>> cluster(final Collection<T> points,
+                                    final int k, final int maxIterations) {
+        // create the initial clusters
+        List<Cluster<T>> clusters = chooseInitialCenters(points, k, random);
+        assignPointsToClusters(clusters, points);
+
+        // iterate through updating the centers until we're done
+        final int max = (maxIterations < 0) ? Integer.MAX_VALUE : maxIterations;
+        for (int count = 0; count < max; count++) {
+            boolean clusteringChanged = false;
+            List<Cluster<T>> newClusters = new ArrayList<Cluster<T>>();
+            for (final Cluster<T> cluster : clusters) {
+                final T newCenter;
+                if (cluster.getPoints().isEmpty()) {
+                    switch (emptyStrategy) {
+                        case LARGEST_VARIANCE :
+                            newCenter = getPointFromLargestVarianceCluster(clusters);
+                            break;
+                        case LARGEST_POINTS_NUMBER :
+                            newCenter = getPointFromLargestNumberCluster(clusters);
+                            break;
+                        case FARTHEST_POINT :
+                            newCenter = getFarthestPoint(clusters);
+                            break;
+                        default :
+                            throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS);
+                    }
+                    clusteringChanged = true;
+                } else {
+                    newCenter = cluster.getCenter().centroidOf(cluster.getPoints());
+                    if (!newCenter.equals(cluster.getCenter())) {
+                        clusteringChanged = true;
+                    }
+                }
+                newClusters.add(new Cluster<T>(newCenter));
+            }
+            if (!clusteringChanged) {
+                return clusters;
+            }
+            assignPointsToClusters(newClusters, points);
+            clusters = newClusters;
+        }
+        return clusters;
+    }
+
+    /**
+     * Adds the given points to the closest {@link Cluster}.
+     *
+     * @param <T> type of the points to cluster
+     * @param clusters the {@link Cluster}s to add the points to
+     * @param points the points to add to the given {@link Cluster}s
+     */
+    private static <T extends Clusterable<T>> void
+        assignPointsToClusters(final Collection<Cluster<T>> clusters, final Collection<T> points) {
+        for (final T p : points) {
+            Cluster<T> cluster = getNearestCluster(clusters, p);
+            cluster.addPoint(p);
+        }
+    }
+
+    /**
+     * Use K-means++ to choose the initial centers.
+     *
+     * @param <T> type of the points to cluster
+     * @param points the points to choose the initial centers from
+     * @param k the number of centers to choose
+     * @param random random generator to use
+     * @return the initial centers
+     */
+    private static <T extends Clusterable<T>> List<Cluster<T>>
+        chooseInitialCenters(final Collection<T> points, final int k, final Random random) {
+
+        final List<T> pointSet = new ArrayList<T>(points);
+        final List<Cluster<T>> resultSet = new ArrayList<Cluster<T>>();
+
+        // Choose one center uniformly at random from among the data points.
+        final T firstPoint = pointSet.remove(random.nextInt(pointSet.size()));
+        resultSet.add(new Cluster<T>(firstPoint));
+
+        final double[] dx2 = new double[pointSet.size()];
+        while (resultSet.size() < k) {
+            // For each data point x, compute D(x), the distance between x and
+            // the nearest center that has already been chosen.
+            int sum = 0;
+            for (int i = 0; i < pointSet.size(); i++) {
+                final T p = pointSet.get(i);
+                final Cluster<T> nearest = getNearestCluster(resultSet, p);
+                final double d = p.distanceFrom(nearest.getCenter());
+                sum += d * d;
+                dx2[i] = sum;
+            }
+
+            // Add one new data point as a center. Each point x is chosen with
+            // probability proportional to D(x)2
+            final double r = random.nextDouble() * sum;
+            for (int i = 0 ; i < dx2.length; i++) {
+                if (dx2[i] >= r) {
+                    final T p = pointSet.remove(i);
+                    resultSet.add(new Cluster<T>(p));
+                    break;
+                }
+            }
+        }
+
+        return resultSet;
+
+    }
+
+    /**
+     * Get a random point from the {@link Cluster} with the largest distance variance.
+     *
+     * @param clusters the {@link Cluster}s to search
+     * @return a random point from the selected cluster
+     */
+    private T getPointFromLargestVarianceCluster(final Collection<Cluster<T>> clusters) {
+
+        double maxVariance = Double.NEGATIVE_INFINITY;
+        Cluster<T> selected = null;
+        for (final Cluster<T> cluster : clusters) {
+            if (!cluster.getPoints().isEmpty()) {
+
+                // compute the distance variance of the current cluster
+                final T center = cluster.getCenter();
+                final Variance stat = new Variance();
+                for (final T point : cluster.getPoints()) {
+                    stat.increment(point.distanceFrom(center));
+                }
+                final double variance = stat.getResult();
+
+                // select the cluster with the largest variance
+                if (variance > maxVariance) {
+                    maxVariance = variance;
+                    selected = cluster;
+                }
+
+            }
+        }
+
+        // did we find at least one non-empty cluster ?
+        if (selected == null) {
+            throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS);
+        }
+
+        // extract a random point from the cluster
+        final List<T> selectedPoints = selected.getPoints();
+        return selectedPoints.remove(random.nextInt(selectedPoints.size()));
+
+    }
+
+    /**
+     * Get a random point from the {@link Cluster} with the largest number of points
+     *
+     * @param clusters the {@link Cluster}s to search
+     * @return a random point from the selected cluster
+     */
+    private T getPointFromLargestNumberCluster(final Collection<Cluster<T>> clusters) {
+
+        int maxNumber = 0;
+        Cluster<T> selected = null;
+        for (final Cluster<T> cluster : clusters) {
+
+            // get the number of points of the current cluster
+            final int number = cluster.getPoints().size();
+
+            // select the cluster with the largest number of points
+            if (number > maxNumber) {
+                maxNumber = number;
+                selected = cluster;
+            }
+
+        }
+
+        // did we find at least one non-empty cluster ?
+        if (selected == null) {
+            throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS);
+        }
+
+        // extract a random point from the cluster
+        final List<T> selectedPoints = selected.getPoints();
+        return selectedPoints.remove(random.nextInt(selectedPoints.size()));
+
+    }
+
+    /**
+     * Get the point farthest to its cluster center
+     *
+     * @param clusters the {@link Cluster}s to search
+     * @return point farthest to its cluster center
+     */
+    private T getFarthestPoint(final Collection<Cluster<T>> clusters) {
+
+        double maxDistance = Double.NEGATIVE_INFINITY;
+        Cluster<T> selectedCluster = null;
+        int selectedPoint = -1;
+        for (final Cluster<T> cluster : clusters) {
+
+            // get the farthest point
+            final T center = cluster.getCenter();
+            final List<T> points = cluster.getPoints();
+            for (int i = 0; i < points.size(); ++i) {
+                final double distance = points.get(i).distanceFrom(center);
+                if (distance > maxDistance) {
+                    maxDistance     = distance;
+                    selectedCluster = cluster;
+                    selectedPoint   = i;
+                }
+            }
+
+        }
+
+        // did we find at least one non-empty cluster ?
+        if (selectedCluster == null) {
+            throw new ConvergenceException(LocalizedFormats.EMPTY_CLUSTER_IN_K_MEANS);
+        }
+
+        return selectedCluster.getPoints().remove(selectedPoint);
+
+    }
+
+    /**
+     * Returns the nearest {@link Cluster} to the given point
+     *
+     * @param <T> type of the points to cluster
+     * @param clusters the {@link Cluster}s to search
+     * @param point the point to find the nearest {@link Cluster} for
+     * @return the nearest {@link Cluster} to the given point
+     */
+    private static <T extends Clusterable<T>> Cluster<T>
+        getNearestCluster(final Collection<Cluster<T>> clusters, final T point) {
+        double minDistance = Double.MAX_VALUE;
+        Cluster<T> minCluster = null;
+        for (final Cluster<T> c : clusters) {
+            final double distance = point.distanceFrom(c.getCenter());
+            if (distance < minDistance) {
+                minDistance = distance;
+                minCluster = c;
+            }
+        }
+        return minCluster;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/clustering/package.html b/src/main/java/org/apache/commons/math/stat/clustering/package.html
new file mode 100644
index 0000000..21e9079
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/clustering/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 770979 $ $Date: 2009-05-02 21:34:51 +0200 (sam. 02 mai 2009) $ -->
+    <body>Clustering algorithms</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/correlation/Covariance.java b/src/main/java/org/apache/commons/math/stat/correlation/Covariance.java
new file mode 100644
index 0000000..393a02d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/correlation/Covariance.java
@@ -0,0 +1,274 @@
+/*
+ * 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.stat.correlation;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.BlockRealMatrix;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.Variance;
+
+/**
+ * Computes covariances for pairs of arrays or columns of a matrix.
+ *
+ * <p>The constructors that take <code>RealMatrix</code> or
+ * <code>double[][]</code> arguments generate covariance matrices.  The
+ * columns of the input matrices are assumed to represent variable values.</p>
+ *
+ * <p>The constructor argument <code>biasCorrected</code> determines whether or
+ * not computed covariances are bias-corrected.</p>
+ *
+ * <p>Unbiased covariances are given by the formula</p>
+ * <code>cov(X, Y) = &Sigma;[(x<sub>i</sub> - E(X))(y<sub>i</sub> - E(Y))] / (n - 1)</code>
+ * where <code>E(X)</code> is the mean of <code>X</code> and <code>E(Y)</code>
+ * is the mean of the <code>Y</code> values.
+ *
+ * <p>Non-bias-corrected estimates use <code>n</code> in place of <code>n - 1</code>
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ * @since 2.0
+ */
+public class Covariance {
+
+    /** covariance matrix */
+    private final RealMatrix covarianceMatrix;
+
+    /**
+     * Create an empty covariance matrix.
+     */
+    /** Number of observations (length of covariate vectors) */
+    private final int n;
+
+    /**
+     * Create a Covariance with no data
+     */
+    public Covariance() {
+        super();
+        covarianceMatrix = null;
+        n = 0;
+    }
+
+    /**
+     * Create a Covariance matrix from a rectangular array
+     * whose columns represent covariates.
+     *
+     * <p>The <code>biasCorrected</code> parameter determines whether or not
+     * covariance estimates are bias-corrected.</p>
+     *
+     * <p>The input array must be rectangular with at least two columns
+     * and two rows.</p>
+     *
+     * @param data rectangular array with columns representing covariates
+     * @param biasCorrected true means covariances are bias-corrected
+     * @throws IllegalArgumentException if the input data array is not
+     * rectangular with at least two rows and two columns.
+     */
+    public Covariance(double[][] data, boolean biasCorrected) {
+        this(new BlockRealMatrix(data), biasCorrected);
+    }
+
+    /**
+     * Create a Covariance matrix from a rectangular array
+     * whose columns represent covariates.
+     *
+     * <p>The input array must be rectangular with at least two columns
+     * and two rows</p>
+     *
+     * @param data rectangular array with columns representing covariates
+     * @throws IllegalArgumentException if the input data array is not
+     * rectangular with at least two rows and two columns.
+     */
+    public Covariance(double[][] data) {
+        this(data, true);
+    }
+
+    /**
+     * Create a covariance matrix from a matrix whose columns
+     * represent covariates.
+     *
+     * <p>The <code>biasCorrected</code> parameter determines whether or not
+     * covariance estimates are bias-corrected.</p>
+     *
+     * <p>The matrix must have at least two columns and two rows</p>
+     *
+     * @param matrix matrix with columns representing covariates
+     * @param biasCorrected true means covariances are bias-corrected
+     * @throws IllegalArgumentException if the input matrix does not have
+     * at least two rows and two columns
+     */
+    public Covariance(RealMatrix matrix, boolean biasCorrected) {
+       checkSufficientData(matrix);
+       n = matrix.getRowDimension();
+       covarianceMatrix = computeCovarianceMatrix(matrix, biasCorrected);
+    }
+
+    /**
+     * Create a covariance matrix from a matrix whose columns
+     * represent covariates.
+     *
+     * <p>The matrix must have at least two columns and two rows</p>
+     *
+     * @param matrix matrix with columns representing covariates
+     * @throws IllegalArgumentException if the input matrix does not have
+     * at least two rows and two columns
+     */
+    public Covariance(RealMatrix matrix) {
+        this(matrix, true);
+    }
+
+    /**
+     * Returns the covariance matrix
+     *
+     * @return covariance matrix
+     */
+    public RealMatrix getCovarianceMatrix() {
+        return covarianceMatrix;
+    }
+
+    /**
+     * Returns the number of observations (length of covariate vectors)
+     *
+     * @return number of observations
+     */
+
+    public int getN() {
+        return n;
+    }
+
+    /**
+     * Compute a covariance matrix from a matrix whose columns represent
+     * covariates.
+     * @param matrix input matrix (must have at least two columns and two rows)
+     * @param biasCorrected determines whether or not covariance estimates are bias-corrected
+     * @return covariance matrix
+     */
+    protected RealMatrix computeCovarianceMatrix(RealMatrix matrix, boolean biasCorrected) {
+        int dimension = matrix.getColumnDimension();
+        Variance variance = new Variance(biasCorrected);
+        RealMatrix outMatrix = new BlockRealMatrix(dimension, dimension);
+        for (int i = 0; i < dimension; i++) {
+            for (int j = 0; j < i; j++) {
+              double cov = covariance(matrix.getColumn(i), matrix.getColumn(j), biasCorrected);
+              outMatrix.setEntry(i, j, cov);
+              outMatrix.setEntry(j, i, cov);
+            }
+            outMatrix.setEntry(i, i, variance.evaluate(matrix.getColumn(i)));
+        }
+        return outMatrix;
+    }
+
+    /**
+     * Create a covariance matrix from a matrix whose columns represent
+     * covariates. Covariances are computed using the bias-corrected formula.
+     * @param matrix input matrix (must have at least two columns and two rows)
+     * @return covariance matrix
+     * @see #Covariance
+     */
+    protected RealMatrix computeCovarianceMatrix(RealMatrix matrix) {
+        return computeCovarianceMatrix(matrix, true);
+    }
+
+    /**
+     * Compute a covariance matrix from a rectangular array whose columns represent
+     * covariates.
+     * @param data input array (must have at least two columns and two rows)
+     * @param biasCorrected determines whether or not covariance estimates are bias-corrected
+     * @return covariance matrix
+     */
+    protected RealMatrix computeCovarianceMatrix(double[][] data, boolean biasCorrected) {
+        return computeCovarianceMatrix(new BlockRealMatrix(data), biasCorrected);
+    }
+
+    /**
+     * Create a covariance matrix from a rectangual array whose columns represent
+     * covariates. Covariances are computed using the bias-corrected formula.
+     * @param data input array (must have at least two columns and two rows)
+     * @return covariance matrix
+     * @see #Covariance
+     */
+    protected RealMatrix computeCovarianceMatrix(double[][] data) {
+        return computeCovarianceMatrix(data, true);
+    }
+
+    /**
+     * Computes the covariance between the two arrays.
+     *
+     * <p>Array lengths must match and the common length must be at least 2.</p>
+     *
+     * @param xArray first data array
+     * @param yArray second data array
+     * @param biasCorrected if true, returned value will be bias-corrected
+     * @return returns the covariance for the two arrays
+     * @throws  IllegalArgumentException if the arrays lengths do not match or
+     * there is insufficient data
+     */
+    public double covariance(final double[] xArray, final double[] yArray, boolean biasCorrected)
+        throws IllegalArgumentException {
+        Mean mean = new Mean();
+        double result = 0d;
+        int length = xArray.length;
+        if (length != yArray.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, length, yArray.length);
+        } else if (length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, length, 2);
+        } else {
+            double xMean = mean.evaluate(xArray);
+            double yMean = mean.evaluate(yArray);
+            for (int i = 0; i < length; i++) {
+                double xDev = xArray[i] - xMean;
+                double yDev = yArray[i] - yMean;
+                result += (xDev * yDev - result) / (i + 1);
+            }
+        }
+        return biasCorrected ? result * ((double) length / (double)(length - 1)) : result;
+    }
+
+    /**
+     * Computes the covariance between the two arrays, using the bias-corrected
+     * formula.
+     *
+     * <p>Array lengths must match and the common length must be at least 2.</p>
+     *
+     * @param xArray first data array
+     * @param yArray second data array
+     * @return returns the covariance for the two arrays
+     * @throws  IllegalArgumentException if the arrays lengths do not match or
+     * there is insufficient data
+     */
+    public double covariance(final double[] xArray, final double[] yArray)
+        throws IllegalArgumentException {
+        return covariance(xArray, yArray, true);
+    }
+
+    /**
+     * Throws IllegalArgumentException of the matrix does not have at least
+     * two columns and two rows
+     * @param matrix matrix to check
+     */
+    private void checkSufficientData(final RealMatrix matrix) {
+        int nRows = matrix.getRowDimension();
+        int nCols = matrix.getColumnDimension();
+        if (nRows < 2 || nCols < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_ROWS_AND_COLUMNS,
+                    nRows, nCols);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/correlation/PearsonsCorrelation.java b/src/main/java/org/apache/commons/math/stat/correlation/PearsonsCorrelation.java
new file mode 100644
index 0000000..6467c69
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/correlation/PearsonsCorrelation.java
@@ -0,0 +1,285 @@
+/*
+ * 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.stat.correlation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.distribution.TDistribution;
+import org.apache.commons.math.distribution.TDistributionImpl;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.BlockRealMatrix;
+import org.apache.commons.math.stat.regression.SimpleRegression;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Computes Pearson's product-moment correlation coefficients for pairs of arrays
+ * or columns of a matrix.
+ *
+ * <p>The constructors that take <code>RealMatrix</code> or
+ * <code>double[][]</code> arguments generate correlation matrices.  The
+ * columns of the input matrices are assumed to represent variable values.
+ * Correlations are given by the formula</p>
+ * <code>cor(X, Y) = &Sigma;[(x<sub>i</sub> - E(X))(y<sub>i</sub> - E(Y))] / [(n - 1)s(X)s(Y)]</code>
+ * where <code>E(X)</code> is the mean of <code>X</code>, <code>E(Y)</code>
+ * is the mean of the <code>Y</code> values and s(X), s(Y) are standard deviations.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class PearsonsCorrelation {
+
+    /** correlation matrix */
+    private final RealMatrix correlationMatrix;
+
+    /** number of observations */
+    private final int nObs;
+
+    /**
+     * Create a PearsonsCorrelation instance without data
+     */
+    public PearsonsCorrelation() {
+        super();
+        correlationMatrix = null;
+        nObs = 0;
+    }
+
+    /**
+     * Create a PearsonsCorrelation from a rectangular array
+     * whose columns represent values of variables to be correlated.
+     *
+     * @param data rectangular array with columns representing variables
+     * @throws IllegalArgumentException if the input data array is not
+     * rectangular with at least two rows and two columns.
+     */
+    public PearsonsCorrelation(double[][] data) {
+        this(new BlockRealMatrix(data));
+    }
+
+    /**
+     * Create a PearsonsCorrelation from a RealMatrix whose columns
+     * represent variables to be correlated.
+     *
+     * @param matrix matrix with columns representing variables to correlate
+     */
+    public PearsonsCorrelation(RealMatrix matrix) {
+        checkSufficientData(matrix);
+        nObs = matrix.getRowDimension();
+        correlationMatrix = computeCorrelationMatrix(matrix);
+    }
+
+    /**
+     * Create a PearsonsCorrelation from a {@link Covariance}.  The correlation
+     * matrix is computed by scaling the Covariance's covariance matrix.
+     * The Covariance instance must have been created from a data matrix with
+     * columns representing variable values.
+     *
+     * @param covariance Covariance instance
+     */
+    public PearsonsCorrelation(Covariance covariance) {
+        RealMatrix covarianceMatrix = covariance.getCovarianceMatrix();
+        if (covarianceMatrix == null) {
+            throw new NullArgumentException(LocalizedFormats.COVARIANCE_MATRIX);
+        }
+        nObs = covariance.getN();
+        correlationMatrix = covarianceToCorrelation(covarianceMatrix);
+    }
+
+    /**
+     * Create a PearsonsCorrelation from a covariance matrix.  The correlation
+     * matrix is computed by scaling the covariance matrix.
+     *
+     * @param covarianceMatrix covariance matrix
+     * @param numberOfObservations the number of observations in the dataset used to compute
+     * the covariance matrix
+     */
+    public PearsonsCorrelation(RealMatrix covarianceMatrix, int numberOfObservations) {
+        nObs = numberOfObservations;
+        correlationMatrix = covarianceToCorrelation(covarianceMatrix);
+
+    }
+
+    /**
+     * Returns the correlation matrix
+     *
+     * @return correlation matrix
+     */
+    public RealMatrix getCorrelationMatrix() {
+        return correlationMatrix;
+    }
+
+    /**
+     * Returns a matrix of standard errors associated with the estimates
+     * in the correlation matrix.<br/>
+     * <code>getCorrelationStandardErrors().getEntry(i,j)</code> is the standard
+     * error associated with <code>getCorrelationMatrix.getEntry(i,j)</code>
+     * <p>The formula used to compute the standard error is <br/>
+     * <code>SE<sub>r</sub> = ((1 - r<sup>2</sup>) / (n - 2))<sup>1/2</sup></code>
+     * where <code>r</code> is the estimated correlation coefficient and
+     * <code>n</code> is the number of observations in the source dataset.</p>
+     *
+     * @return matrix of correlation standard errors
+     */
+    public RealMatrix getCorrelationStandardErrors() {
+        int nVars = correlationMatrix.getColumnDimension();
+        double[][] out = new double[nVars][nVars];
+        for (int i = 0; i < nVars; i++) {
+            for (int j = 0; j < nVars; j++) {
+                double r = correlationMatrix.getEntry(i, j);
+                out[i][j] = FastMath.sqrt((1 - r * r) /(nObs - 2));
+            }
+        }
+        return new BlockRealMatrix(out);
+    }
+
+    /**
+     * Returns a matrix of p-values associated with the (two-sided) null
+     * hypothesis that the corresponding correlation coefficient is zero.
+     * <p><code>getCorrelationPValues().getEntry(i,j)</code> is the probability
+     * that a random variable distributed as <code>t<sub>n-2</sub></code> takes
+     * a value with absolute value greater than or equal to <br>
+     * <code>|r|((n - 2) / (1 - r<sup>2</sup>))<sup>1/2</sup></code></p>
+     * <p>The values in the matrix are sometimes referred to as the
+     * <i>significance</i> of the corresponding correlation coefficients.</p>
+     *
+     * @return matrix of p-values
+     * @throws MathException if an error occurs estimating probabilities
+     */
+    public RealMatrix getCorrelationPValues() throws MathException {
+        TDistribution tDistribution = new TDistributionImpl(nObs - 2);
+        int nVars = correlationMatrix.getColumnDimension();
+        double[][] out = new double[nVars][nVars];
+        for (int i = 0; i < nVars; i++) {
+            for (int j = 0; j < nVars; j++) {
+                if (i == j) {
+                    out[i][j] = 0d;
+                } else {
+                    double r = correlationMatrix.getEntry(i, j);
+                    double t = FastMath.abs(r * FastMath.sqrt((nObs - 2)/(1 - r * r)));
+                    out[i][j] = 2 * tDistribution.cumulativeProbability(-t);
+                }
+            }
+        }
+        return new BlockRealMatrix(out);
+    }
+
+
+    /**
+     * Computes the correlation matrix for the columns of the
+     * input matrix.
+     *
+     * @param matrix matrix with columns representing variables to correlate
+     * @return correlation matrix
+     */
+    public RealMatrix computeCorrelationMatrix(RealMatrix matrix) {
+        int nVars = matrix.getColumnDimension();
+        RealMatrix outMatrix = new BlockRealMatrix(nVars, nVars);
+        for (int i = 0; i < nVars; i++) {
+            for (int j = 0; j < i; j++) {
+              double corr = correlation(matrix.getColumn(i), matrix.getColumn(j));
+              outMatrix.setEntry(i, j, corr);
+              outMatrix.setEntry(j, i, corr);
+            }
+            outMatrix.setEntry(i, i, 1d);
+        }
+        return outMatrix;
+    }
+
+    /**
+     * Computes the correlation matrix for the columns of the
+     * input rectangular array.  The colums of the array represent values
+     * of variables to be correlated.
+     *
+     * @param data matrix with columns representing variables to correlate
+     * @return correlation matrix
+     */
+    public RealMatrix computeCorrelationMatrix(double[][] data) {
+       return computeCorrelationMatrix(new BlockRealMatrix(data));
+    }
+
+    /**
+     * Computes the Pearson's product-moment correlation coefficient between the two arrays.
+     *
+     * </p>Throws IllegalArgumentException if the arrays do not have the same length
+     * or their common length is less than 2</p>
+     *
+     * @param xArray first data array
+     * @param yArray second data array
+     * @return Returns Pearson's correlation coefficient for the two arrays
+     * @throws  IllegalArgumentException if the arrays lengths do not match or
+     * there is insufficient data
+     */
+    public double correlation(final double[] xArray, final double[] yArray) throws IllegalArgumentException {
+        SimpleRegression regression = new SimpleRegression();
+        if (xArray.length != yArray.length) {
+            throw new DimensionMismatchException(xArray.length, yArray.length);
+        } else if (xArray.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, xArray.length, 2);
+        } else {
+            for(int i=0; i<xArray.length; i++) {
+                regression.addData(xArray[i], yArray[i]);
+            }
+            return regression.getR();
+        }
+    }
+
+    /**
+     * Derives a correlation matrix from a covariance matrix.
+     *
+     * <p>Uses the formula <br/>
+     * <code>r(X,Y) = cov(X,Y)/s(X)s(Y)</code> where
+     * <code>r(&middot,&middot;)</code> is the correlation coefficient and
+     * <code>s(&middot;)</code> means standard deviation.</p>
+     *
+     * @param covarianceMatrix the covariance matrix
+     * @return correlation matrix
+     */
+    public RealMatrix covarianceToCorrelation(RealMatrix covarianceMatrix) {
+        int nVars = covarianceMatrix.getColumnDimension();
+        RealMatrix outMatrix = new BlockRealMatrix(nVars, nVars);
+        for (int i = 0; i < nVars; i++) {
+            double sigma = FastMath.sqrt(covarianceMatrix.getEntry(i, i));
+            outMatrix.setEntry(i, i, 1d);
+            for (int j = 0; j < i; j++) {
+                double entry = covarianceMatrix.getEntry(i, j) /
+                       (sigma * FastMath.sqrt(covarianceMatrix.getEntry(j, j)));
+                outMatrix.setEntry(i, j, entry);
+                outMatrix.setEntry(j, i, entry);
+            }
+        }
+        return outMatrix;
+    }
+
+    /**
+     * Throws IllegalArgumentException of the matrix does not have at least
+     * two columns and two rows
+     *
+     * @param matrix matrix to check for sufficiency
+     */
+    private void checkSufficientData(final RealMatrix matrix) {
+        int nRows = matrix.getRowDimension();
+        int nCols = matrix.getColumnDimension();
+        if (nRows < 2 || nCols < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INSUFFICIENT_ROWS_AND_COLUMNS,
+                    nRows, nCols);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/correlation/SpearmansCorrelation.java b/src/main/java/org/apache/commons/math/stat/correlation/SpearmansCorrelation.java
new file mode 100644
index 0000000..fe121fe
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/correlation/SpearmansCorrelation.java
@@ -0,0 +1,172 @@
+/*
+ * 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.stat.correlation;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.BlockRealMatrix;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.stat.ranking.NaturalRanking;
+import org.apache.commons.math.stat.ranking.RankingAlgorithm;
+
+/**
+ * <p>Spearman's rank correlation. This implementation performs a rank
+ * transformation on the input data and then computes {@link PearsonsCorrelation}
+ * on the ranked data.</p>
+ *
+ * <p>By default, ranks are computed using {@link NaturalRanking} with default
+ * strategies for handling NaNs and ties in the data (NaNs maximal, ties averaged).
+ * The ranking algorithm can be set using a constructor argument.</p>
+ *
+ * @since 2.0
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+
+public class SpearmansCorrelation {
+
+    /** Input data */
+    private final RealMatrix data;
+
+    /** Ranking algorithm  */
+    private final RankingAlgorithm rankingAlgorithm;
+
+    /** Rank correlation */
+    private final PearsonsCorrelation rankCorrelation;
+
+    /**
+     * Create a SpearmansCorrelation with the given input data matrix
+     * and ranking algorithm.
+     *
+     * @param dataMatrix matrix of data with columns representing
+     * variables to correlate
+     * @param rankingAlgorithm ranking algorithm
+     */
+    public SpearmansCorrelation(final RealMatrix dataMatrix, final RankingAlgorithm rankingAlgorithm) {
+        this.data = dataMatrix.copy();
+        this.rankingAlgorithm = rankingAlgorithm;
+        rankTransform(data);
+        rankCorrelation = new PearsonsCorrelation(data);
+    }
+
+    /**
+     * Create a SpearmansCorrelation from the given data matrix.
+     *
+     * @param dataMatrix matrix of data with columns representing
+     * variables to correlate
+     */
+    public SpearmansCorrelation(final RealMatrix dataMatrix) {
+        this(dataMatrix, new NaturalRanking());
+    }
+
+    /**
+     * Create a SpearmansCorrelation without data.
+     */
+    public SpearmansCorrelation() {
+        data = null;
+        this.rankingAlgorithm = new NaturalRanking();
+        rankCorrelation = null;
+    }
+
+    /**
+     * Calculate the Spearman Rank Correlation Matrix.
+     *
+     * @return Spearman Rank Correlation Matrix
+     */
+    public RealMatrix getCorrelationMatrix() {
+        return rankCorrelation.getCorrelationMatrix();
+    }
+
+    /**
+     * Returns a {@link PearsonsCorrelation} instance constructed from the
+     * ranked input data. That is,
+     * <code>new SpearmansCorrelation(matrix).getRankCorrelation()</code>
+     * is equivalent to
+     * <code>new PearsonsCorrelation(rankTransform(matrix))</code> where
+     * <code>rankTransform(matrix)</code> is the result of applying the
+     * configured <code>RankingAlgorithm</code> to each of the columns of
+     * <code>matrix.</code>
+     *
+     * @return PearsonsCorrelation among ranked column data
+     */
+    public PearsonsCorrelation getRankCorrelation() {
+        return rankCorrelation;
+    }
+
+    /**
+     * Computes the Spearman's rank correlation matrix for the columns of the
+     * input matrix.
+     *
+     * @param matrix matrix with columns representing variables to correlate
+     * @return correlation matrix
+     */
+    public RealMatrix computeCorrelationMatrix(RealMatrix matrix) {
+        RealMatrix matrixCopy = matrix.copy();
+        rankTransform(matrixCopy);
+        return new PearsonsCorrelation().computeCorrelationMatrix(matrixCopy);
+    }
+
+    /**
+     * Computes the Spearman's rank correlation matrix for the columns of the
+     * input rectangular array.  The columns of the array represent values
+     * of variables to be correlated.
+     *
+     * @param matrix matrix with columns representing variables to correlate
+     * @return correlation matrix
+     */
+    public RealMatrix computeCorrelationMatrix(double[][] matrix) {
+       return computeCorrelationMatrix(new BlockRealMatrix(matrix));
+    }
+
+    /**
+     * Computes the Spearman's rank correlation coefficient between the two arrays.
+     *
+     * </p>Throws IllegalArgumentException if the arrays do not have the same length
+     * or their common length is less than 2</p>
+     *
+     * @param xArray first data array
+     * @param yArray second data array
+     * @return Returns Spearman's rank correlation coefficient for the two arrays
+     * @throws  IllegalArgumentException if the arrays lengths do not match or
+     * there is insufficient data
+     */
+    public double correlation(final double[] xArray, final double[] yArray)
+    throws IllegalArgumentException {
+        if (xArray.length != yArray.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, xArray.length, yArray.length);
+        } else if (xArray.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, xArray.length, 2);
+        } else {
+            return new PearsonsCorrelation().correlation(rankingAlgorithm.rank(xArray),
+                    rankingAlgorithm.rank(yArray));
+        }
+    }
+
+    /**
+     * Applies rank transform to each of the columns of <code>matrix</code>
+     * using the current <code>rankingAlgorithm</code>
+     *
+     * @param matrix matrix to transform
+     */
+    private void rankTransform(RealMatrix matrix) {
+        for (int i = 0; i < matrix.getColumnDimension(); i++) {
+            matrix.setColumn(i, rankingAlgorithm.rank(matrix.getColumn(i)));
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/correlation/package.html b/src/main/java/org/apache/commons/math/stat/correlation/package.html
new file mode 100644
index 0000000..8b12fc2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/correlation/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 744716 $ $Date: 2009-02-15 19:38:49 +0100 (dim. 15 févr. 2009) $ -->
+    <body>
+        Correlations/Covariance computations.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivariateStatistic.java b/src/main/java/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivariateStatistic.java
new file mode 100644
index 0000000..9e721ea
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivariateStatistic.java
@@ -0,0 +1,183 @@
+/*
+ * 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.stat.descriptive;
+
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ *
+ * Abstract implementation of the {@link StorelessUnivariateStatistic} interface.
+ * <p>
+ * Provides default <code>evaluate()</code> and <code>incrementAll(double[])<code>
+ * implementations.</p>
+ * <p>
+ * <strong>Note that these implementations are not synchronized.</strong></p>
+ *
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public abstract class AbstractStorelessUnivariateStatistic
+    extends AbstractUnivariateStatistic
+    implements StorelessUnivariateStatistic {
+
+    /**
+     * This default implementation calls {@link #clear}, then invokes
+     * {@link #increment} in a loop over the the input array, and then uses
+     * {@link #getResult} to compute the return value.
+     * <p>
+     * Note that this implementation changes the internal state of the
+     * statistic.  Its side effects are the same as invoking {@link #clear} and
+     * then {@link #incrementAll(double[])}.</p>
+     * <p>
+     * Implementations may override this method with a more efficient and
+     * possibly more accurate implementation that works directly with the
+     * input array.</p>
+     * <p>
+     * If the array is null, an IllegalArgumentException is thrown.</p>
+     * @param values input array
+     * @return the value of the statistic applied to the input array
+     * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[])
+     */
+    @Override
+    public double evaluate(final double[] values) {
+        if (values == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        return evaluate(values, 0, values.length);
+    }
+
+    /**
+     * This default implementation calls {@link #clear}, then invokes
+     * {@link #increment} in a loop over the specified portion of the input
+     * array, and then uses {@link #getResult} to compute the return value.
+     * <p>
+     * Note that this implementation changes the internal state of the
+     * statistic.  Its side effects are the same as invoking {@link #clear} and
+     * then {@link #incrementAll(double[], int, int)}.</p>
+     * <p>
+     * Implementations may override this method with a more efficient and
+     * possibly more accurate implementation that works directly with the
+     * input array.</p>
+     * <p>
+     * If the array is null or the index parameters are not valid, an
+     * IllegalArgumentException is thrown.</p>
+     * @param values the input array
+     * @param begin the index of the first element to include
+     * @param length the number of elements to include
+     * @return the value of the statistic applied to the included array entries
+     * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[], int, int)
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length) {
+        if (test(values, begin, length)) {
+            clear();
+            incrementAll(values, begin, length);
+        }
+        return getResult();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public abstract StorelessUnivariateStatistic copy();
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract void clear();
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract double getResult();
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract void increment(final double d);
+
+    /**
+     * This default implementation just calls {@link #increment} in a loop over
+     * the input array.
+     * <p>
+     * Throws IllegalArgumentException if the input values array is null.</p>
+     *
+     * @param values values to add
+     * @throws IllegalArgumentException if values is null
+     * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[])
+     */
+    public void incrementAll(double[] values) {
+        if (values == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        incrementAll(values, 0, values.length);
+    }
+
+    /**
+     * This default implementation just calls {@link #increment} in a loop over
+     * the specified portion of the input array.
+     * <p>
+     * Throws IllegalArgumentException if the input values array is null.</p>
+     *
+     * @param values  array holding values to add
+     * @param begin   index of the first array element to add
+     * @param length  number of array elements to add
+     * @throws IllegalArgumentException if values is null
+     * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[], int, int)
+     */
+    public void incrementAll(double[] values, int begin, int length) {
+        if (test(values, begin, length)) {
+            int k = begin + length;
+            for (int i = begin; i < k; i++) {
+                increment(values[i]);
+            }
+        }
+    }
+
+    /**
+     * Returns true iff <code>object</code> is an
+     * <code>AbstractStorelessUnivariateStatistic</code> returning the same
+     * values as this for <code>getResult()</code> and <code>getN()</code>
+     * @param object object to test equality against.
+     * @return true if object returns the same value as this
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this ) {
+            return true;
+        }
+       if (object instanceof AbstractStorelessUnivariateStatistic == false) {
+            return false;
+        }
+        AbstractStorelessUnivariateStatistic stat = (AbstractStorelessUnivariateStatistic) object;
+        return MathUtils.equalsIncludingNaN(stat.getResult(), this.getResult()) &&
+               MathUtils.equalsIncludingNaN(stat.getN(), this.getN());
+    }
+
+    /**
+     * Returns hash code based on getResult() and getN()
+     *
+     * @return hash code
+     */
+    @Override
+    public int hashCode() {
+        return 31* (31 + MathUtils.hash(getResult())) + MathUtils.hash(getN());
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java b/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java
new file mode 100644
index 0000000..354dee6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.java
@@ -0,0 +1,232 @@
+/*
+ * 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.stat.descriptive;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.NotPositiveException;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Abstract base class for all implementations of the
+ * {@link UnivariateStatistic} interface.
+ * <p>
+ * Provides a default implementation of <code>evaluate(double[]),</code>
+ * delegating to <code>evaluate(double[], int, int)</code> in the natural way.
+ * </p>
+ * <p>
+ * Also includes a <code>test</code> method that performs generic parameter
+ * validation for the <code>evaluate</code> methods.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public abstract class AbstractUnivariateStatistic
+    implements UnivariateStatistic {
+
+    /** Stored data. */
+    private double[] storedData;
+
+    /**
+     * Set the data array.
+     * <p>
+     * The stored value is a copy of the parameter array, not the array itself
+     * </p>
+     * @param values data array to store (may be null to remove stored data)
+     * @see #evaluate()
+     */
+    public void setData(final double[] values) {
+        storedData = (values == null) ? null : values.clone();
+    }
+
+    /**
+     * Get a copy of the stored data array.
+     * @return copy of the stored data array (may be null)
+     */
+    public double[] getData() {
+        return (storedData == null) ? null : storedData.clone();
+    }
+
+    /**
+     * Get a reference to the stored data array.
+     * @return reference to the stored data array (may be null)
+     */
+    protected double[] getDataRef() {
+        return storedData;
+    }
+
+    /**
+     * Set the data array.
+     * @param values data array to store
+     * @param begin the index of the first element to include
+     * @param length the number of elements to include
+     * @see #evaluate()
+     */
+    public void setData(final double[] values, final int begin, final int length) {
+        storedData = new double[length];
+        System.arraycopy(values, begin, storedData, 0, length);
+    }
+
+    /**
+     * Returns the result of evaluating the statistic over the stored data.
+     * <p>
+     * The stored array is the one which was set by previous calls to
+     * </p>
+     * @return the value of the statistic applied to the stored data
+     */
+    public double evaluate() {
+        return evaluate(storedData);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double evaluate(final double[] values) {
+        test(values, 0, 0);
+        return evaluate(values, 0, values.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract double evaluate(final double[] values, final int begin, final int length);
+
+    /**
+     * {@inheritDoc}
+     */
+    public abstract UnivariateStatistic copy();
+
+    /**
+     * This method is used by <code>evaluate(double[], int, int)</code> methods
+     * to verify that the input parameters designate a subarray of positive length.
+     * <p>
+     * <ul>
+     * <li>returns <code>true</code> iff the parameters designate a subarray of
+     * positive length</li>
+     * <li>throws <code>IllegalArgumentException</code> if the array is null or
+     * or the indices are invalid</li>
+     * <li>returns <code>false</li> if the array is non-null, but
+     * <code>length</code> is 0.
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return true if the parameters are valid and designate a subarray of positive length
+     * @throws IllegalArgumentException if the indices are invalid or the array is null
+     */
+    protected boolean test(
+        final double[] values,
+        final int begin,
+        final int length) {
+
+        if (values == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+
+        if (begin < 0) {
+            throw new NotPositiveException(LocalizedFormats.START_POSITION, begin);
+        }
+
+        if (length < 0) {
+            throw new NotPositiveException(LocalizedFormats.LENGTH, length);
+        }
+
+        if (begin + length > values.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.SUBARRAY_ENDS_AFTER_ARRAY_END);
+        }
+
+        if (length == 0) {
+            return false;
+        }
+
+        return true;
+
+    }
+
+    /**
+     * This method is used by <code>evaluate(double[], double[], int, int)</code> methods
+     * to verify that the begin and length parameters designate a subarray of positive length
+     * and the weights are all non-negative, non-NaN, finite, and not all zero.
+     * <p>
+     * <ul>
+     * <li>returns <code>true</code> iff the parameters designate a subarray of
+     * positive length and the weights array contains legitimate values.</li>
+     * <li>throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     *     <li>the start and length arguments do not determine a valid array</li></ul>
+     * </li>
+     * <li>returns <code>false</li> if the array is non-null, but
+     * <code>length</code> is 0.
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return true if the parameters are valid and designate a subarray of positive length
+     * @throws IllegalArgumentException if the indices are invalid or the array is null
+     * @since 2.1
+     */
+    protected boolean test(
+        final double[] values,
+        final double[] weights,
+        final int begin,
+        final int length) {
+
+        if (weights == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+
+        if (weights.length != values.length) {
+            throw new DimensionMismatchException(weights.length, values.length);
+        }
+
+        boolean containsPositiveWeight = false;
+        for (int i = begin; i < begin + length; i++) {
+            if (Double.isNaN(weights[i])) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.NAN_ELEMENT_AT_INDEX, i);
+            }
+            if (Double.isInfinite(weights[i])) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.INFINITE_ARRAY_ELEMENT, weights[i], i);
+            }
+            if (weights[i] < 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX, i, weights[i]);
+            }
+            if (!containsPositiveWeight && weights[i] > 0.0) {
+                containsPositiveWeight = true;
+            }
+        }
+
+        if (!containsPositiveWeight) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.WEIGHT_AT_LEAST_ONE_NON_ZERO);
+        }
+
+        return test(values, begin, length);
+    }
+}
+
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatistics.java
new file mode 100644
index 0000000..98c58c8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/AggregateSummaryStatistics.java
@@ -0,0 +1,416 @@
+/*
+ * 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.stat.descriptive;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * <p>
+ * An aggregator for {@code SummaryStatistics} from several data sets or
+ * data set partitions.  In its simplest usage mode, the client creates an
+ * instance via the zero-argument constructor, then uses
+ * {@link #createContributingStatistics()} to obtain a {@code SummaryStatistics}
+ * for each individual data set / partition.  The per-set statistics objects
+ * are used as normal, and at any time the aggregate statistics for all the
+ * contributors can be obtained from this object.
+ * </p><p>
+ * Clients with specialized requirements can use alternative constructors to
+ * control the statistics implementations and initial values used by the
+ * contributing and the internal aggregate {@code SummaryStatistics} objects.
+ * </p><p>
+ * A static {@link #aggregate(Collection)} method is also included that computes
+ * aggregate statistics directly from a Collection of SummaryStatistics instances.
+ * </p><p>
+ * When {@link #createContributingStatistics()} is used to create SummaryStatistics
+ * instances to be aggregated concurrently, the created instances'
+ * {@link SummaryStatistics#addValue(double)} methods must synchronize on the aggregating
+ * instance maintained by this class.  In multithreaded environments, if the functionality
+ * provided by {@link #aggregate(Collection)} is adequate, that method should be used
+ * to avoid unecessary computation and synchronization delays.</p>
+ *
+ * @since 2.0
+ * @version $Revision: 811833 $ $Date: 2009-09-06 18:27:50 +0200 (dim. 06 sept. 2009) $
+ *
+ */
+public class AggregateSummaryStatistics implements StatisticalSummary,
+        Serializable {
+
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -8207112444016386906L;
+
+    /**
+     * A SummaryStatistics serving as a prototype for creating SummaryStatistics
+     * contributing to this aggregate
+     */
+    private final SummaryStatistics statisticsPrototype;
+
+    /**
+     * The SummaryStatistics in which aggregate statistics are accumulated.
+     */
+    private final SummaryStatistics statistics;
+
+    /**
+     * Initializes a new AggregateSummaryStatistics with default statistics
+     * implementations.
+     *
+     */
+    public AggregateSummaryStatistics() {
+        this(new SummaryStatistics());
+    }
+
+    /**
+     * Initializes a new AggregateSummaryStatistics with the specified statistics
+     * object as a prototype for contributing statistics and for the internal
+     * aggregate statistics.  This provides for customized statistics implementations
+     * to be used by contributing and aggregate statistics.
+     *
+     * @param prototypeStatistics a {@code SummaryStatistics} serving as a
+     *      prototype both for the internal aggregate statistics and for
+     *      contributing statistics obtained via the
+     *      {@code createContributingStatistics()} method.  Being a prototype
+     *      means that other objects are initialized by copying this object's state.
+     *      If {@code null}, a new, default statistics object is used.  Any statistic
+     *      values in the prototype are propagated to contributing statistics
+     *      objects and (once) into these aggregate statistics.
+     * @see #createContributingStatistics()
+     */
+    public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics) {
+        this(prototypeStatistics,
+             prototypeStatistics == null ? null : new SummaryStatistics(prototypeStatistics));
+    }
+
+    /**
+     * Initializes a new AggregateSummaryStatistics with the specified statistics
+     * object as a prototype for contributing statistics and for the internal
+     * aggregate statistics.  This provides for different statistics implementations
+     * to be used by contributing and aggregate statistics and for an initial
+     * state to be supplied for the aggregate statistics.
+     *
+     * @param prototypeStatistics a {@code SummaryStatistics} serving as a
+     *      prototype both for the internal aggregate statistics and for
+     *      contributing statistics obtained via the
+     *      {@code createContributingStatistics()} method.  Being a prototype
+     *      means that other objects are initialized by copying this object's state.
+     *      If {@code null}, a new, default statistics object is used.  Any statistic
+     *      values in the prototype are propagated to contributing statistics
+     *      objects, but not into these aggregate statistics.
+     * @param initialStatistics a {@code SummaryStatistics} to serve as the
+     *      internal aggregate statistics object.  If {@code null}, a new, default
+     *      statistics object is used.
+     * @see #createContributingStatistics()
+     */
+    public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics,
+                                      SummaryStatistics initialStatistics) {
+        this.statisticsPrototype =
+            (prototypeStatistics == null) ? new SummaryStatistics() : prototypeStatistics;
+        this.statistics =
+            (initialStatistics == null) ? new SummaryStatistics() : initialStatistics;
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns the maximum over all the aggregated
+     * data.
+     *
+     * @see StatisticalSummary#getMax()
+     */
+    public double getMax() {
+        synchronized (statistics) {
+            return statistics.getMax();
+        }
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns the mean of all the aggregated data.
+     *
+     * @see StatisticalSummary#getMean()
+     */
+    public double getMean() {
+        synchronized (statistics) {
+            return statistics.getMean();
+        }
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns the minimum over all the aggregated
+     * data.
+     *
+     * @see StatisticalSummary#getMin()
+     */
+    public double getMin() {
+        synchronized (statistics) {
+            return statistics.getMin();
+        }
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns a count of all the aggregated data.
+     *
+     * @see StatisticalSummary#getN()
+     */
+    public long getN() {
+        synchronized (statistics) {
+            return statistics.getN();
+        }
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns the standard deviation of all the
+     * aggregated data.
+     *
+     * @see StatisticalSummary#getStandardDeviation()
+     */
+    public double getStandardDeviation() {
+        synchronized (statistics) {
+            return statistics.getStandardDeviation();
+        }
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns a sum of all the aggregated data.
+     *
+     * @see StatisticalSummary#getSum()
+     */
+    public double getSum() {
+        synchronized (statistics) {
+            return statistics.getSum();
+        }
+    }
+
+    /**
+     * {@inheritDoc}.  This version returns the variance of all the aggregated
+     * data.
+     *
+     * @see StatisticalSummary#getVariance()
+     */
+    public double getVariance() {
+        synchronized (statistics) {
+            return statistics.getVariance();
+        }
+    }
+
+    /**
+     * Returns the sum of the logs of all the aggregated data.
+     *
+     * @return the sum of logs
+     * @see SummaryStatistics#getSumOfLogs()
+     */
+    public double getSumOfLogs() {
+        synchronized (statistics) {
+            return statistics.getSumOfLogs();
+        }
+    }
+
+    /**
+     * Returns the geometric mean of all the aggregated data.
+     *
+     * @return the geometric mean
+     * @see SummaryStatistics#getGeometricMean()
+     */
+    public double getGeometricMean() {
+        synchronized (statistics) {
+            return statistics.getGeometricMean();
+        }
+    }
+
+    /**
+     * Returns the sum of the squares of all the aggregated data.
+     *
+     * @return The sum of squares
+     * @see SummaryStatistics#getSumsq()
+     */
+    public double getSumsq() {
+        synchronized (statistics) {
+            return statistics.getSumsq();
+        }
+    }
+
+    /**
+     * Returns a statistic related to the Second Central Moment.  Specifically,
+     * what is returned is the sum of squared deviations from the sample mean
+     * among the all of the aggregated data.
+     *
+     * @return second central moment statistic
+     * @see SummaryStatistics#getSecondMoment()
+     */
+    public double getSecondMoment() {
+        synchronized (statistics) {
+            return statistics.getSecondMoment();
+        }
+    }
+
+    /**
+     * Return a {@link StatisticalSummaryValues} instance reporting current
+     * aggregate statistics.
+     *
+     * @return Current values of aggregate statistics
+     */
+    public StatisticalSummary getSummary() {
+        synchronized (statistics) {
+            return new StatisticalSummaryValues(getMean(), getVariance(), getN(),
+                    getMax(), getMin(), getSum());
+        }
+    }
+
+    /**
+     * Creates and returns a {@code SummaryStatistics} whose data will be
+     * aggregated with those of this {@code AggregateSummaryStatistics}.
+     *
+     * @return a {@code SummaryStatistics} whose data will be aggregated with
+     *      those of this {@code AggregateSummaryStatistics}.  The initial state
+     *      is a copy of the configured prototype statistics.
+     */
+    public SummaryStatistics createContributingStatistics() {
+        SummaryStatistics contributingStatistics
+                = new AggregatingSummaryStatistics(statistics);
+
+        SummaryStatistics.copy(statisticsPrototype, contributingStatistics);
+
+        return contributingStatistics;
+    }
+
+    /**
+     * Computes aggregate summary statistics. This method can be used to combine statistics
+     * computed over partitions or subsamples - i.e., the StatisticalSummaryValues returned
+     * should contain the same values that would have been obtained by computing a single
+     * StatisticalSummary over the combined dataset.
+     * <p>
+     * Returns null if the collection is empty or null.
+     * </p>
+     *
+     * @param statistics collection of SummaryStatistics to aggregate
+     * @return summary statistics for the combined dataset
+     */
+    public static StatisticalSummaryValues aggregate(Collection<SummaryStatistics> statistics) {
+        if (statistics == null) {
+            return null;
+        }
+        Iterator<SummaryStatistics> iterator = statistics.iterator();
+        if (!iterator.hasNext()) {
+            return null;
+        }
+        SummaryStatistics current = iterator.next();
+        long n = current.getN();
+        double min = current.getMin();
+        double sum = current.getSum();
+        double max = current.getMax();
+        double m2 = current.getSecondMoment();
+        double mean = current.getMean();
+        while (iterator.hasNext()) {
+            current = iterator.next();
+            if (current.getMin() < min || Double.isNaN(min)) {
+                min = current.getMin();
+            }
+            if (current.getMax() > max || Double.isNaN(max)) {
+                max = current.getMax();
+            }
+            sum += current.getSum();
+            final double oldN = n;
+            final double curN = current.getN();
+            n += curN;
+            final double meanDiff = current.getMean() - mean;
+            mean = sum / n;
+            m2 = m2 + current.getSecondMoment() + meanDiff * meanDiff * oldN * curN / n;
+        }
+        final double variance;
+        if (n == 0) {
+            variance = Double.NaN;
+        } else if (n == 1) {
+            variance = 0d;
+        } else {
+            variance = m2 / (n - 1);
+        }
+        return new StatisticalSummaryValues(mean, variance, n, max, min, sum);
+    }
+
+    /**
+     * A SummaryStatistics that also forwards all values added to it to a second
+     * {@code SummaryStatistics} for aggregation.
+     *
+     * @since 2.0
+     */
+    private static class AggregatingSummaryStatistics extends SummaryStatistics {
+
+        /**
+         * The serialization version of this class
+         */
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * An additional SummaryStatistics into which values added to these
+         * statistics (and possibly others) are aggregated
+         */
+        private final SummaryStatistics aggregateStatistics;
+
+        /**
+         * Initializes a new AggregatingSummaryStatistics with the specified
+         * aggregate statistics object
+         *
+         * @param aggregateStatistics a {@code SummaryStatistics} into which
+         *      values added to this statistics object should be aggregated
+         */
+        public AggregatingSummaryStatistics(SummaryStatistics aggregateStatistics) {
+            this.aggregateStatistics = aggregateStatistics;
+        }
+
+        /**
+         * {@inheritDoc}.  This version adds the provided value to the configured
+         * aggregate after adding it to these statistics.
+         *
+         * @see SummaryStatistics#addValue(double)
+         */
+        @Override
+        public void addValue(double value) {
+            super.addValue(value);
+            synchronized (aggregateStatistics) {
+                aggregateStatistics.addValue(value);
+            }
+        }
+
+        /**
+         * Returns true iff <code>object</code> is a
+         * <code>SummaryStatistics</code> instance and all statistics have the
+         * same values as this.
+         * @param object the object to test equality against.
+         * @return true if object equals this
+         */
+        @Override
+        public boolean equals(Object object) {
+            if (object == this) {
+                return true;
+            }
+            if (object instanceof AggregatingSummaryStatistics == false) {
+                return false;
+            }
+            AggregatingSummaryStatistics stat = (AggregatingSummaryStatistics)object;
+            return super.equals(stat) &&
+                   aggregateStatistics.equals(stat.aggregateStatistics);
+        }
+
+        /**
+         * Returns hash code based on values of statistics
+         * @return hash code
+         */
+        @Override
+        public int hashCode() {
+            return 123 + super.hashCode() + aggregateStatistics.hashCode();
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java
new file mode 100644
index 0000000..e5a18dc
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.java
@@ -0,0 +1,721 @@
+/*
+ * 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.stat.descriptive;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.moment.GeometricMean;
+import org.apache.commons.math.stat.descriptive.moment.Kurtosis;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.Skewness;
+import org.apache.commons.math.stat.descriptive.moment.Variance;
+import org.apache.commons.math.stat.descriptive.rank.Max;
+import org.apache.commons.math.stat.descriptive.rank.Min;
+import org.apache.commons.math.stat.descriptive.rank.Percentile;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
+import org.apache.commons.math.util.ResizableDoubleArray;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Maintains a dataset of values of a single variable and computes descriptive
+ * statistics based on stored data. The {@link #getWindowSize() windowSize}
+ * property sets a limit on the number of values that can be stored in the
+ * dataset.  The default value, INFINITE_WINDOW, puts no limit on the size of
+ * the dataset.  This value should be used with caution, as the backing store
+ * will grow without bound in this case.  For very large datasets,
+ * {@link SummaryStatistics}, which does not store the dataset, should be used
+ * instead of this class. If <code>windowSize</code> is not INFINITE_WINDOW and
+ * more values are added than can be stored in the dataset, new values are
+ * added in a "rolling" manner, with new values replacing the "oldest" values
+ * in the dataset.
+ *
+ * <p>Note: this class is not threadsafe.  Use
+ * {@link SynchronizedDescriptiveStatistics} if concurrent access from multiple
+ * threads is required.</p>
+ *
+ * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $
+ */
+public class DescriptiveStatistics implements StatisticalSummary, Serializable {
+
+    /**
+     * Represents an infinite window size.  When the {@link #getWindowSize()}
+     * returns this value, there is no limit to the number of data values
+     * that can be stored in the dataset.
+     */
+    public static final int INFINITE_WINDOW = -1;
+
+    /** Serialization UID */
+    private static final long serialVersionUID = 4133067267405273064L;
+
+    /** Name of the setQuantile method. */
+    private static final String SET_QUANTILE_METHOD_NAME = "setQuantile";
+
+    /** hold the window size **/
+    protected int windowSize = INFINITE_WINDOW;
+
+    /**
+     *  Stored data values
+     */
+    protected ResizableDoubleArray eDA = new ResizableDoubleArray();
+
+    /** Mean statistic implementation - can be reset by setter. */
+    private UnivariateStatistic meanImpl = new Mean();
+
+    /** Geometric mean statistic implementation - can be reset by setter. */
+    private UnivariateStatistic geometricMeanImpl = new GeometricMean();
+
+    /** Kurtosis statistic implementation - can be reset by setter. */
+    private UnivariateStatistic kurtosisImpl = new Kurtosis();
+
+    /** Maximum statistic implementation - can be reset by setter. */
+    private UnivariateStatistic maxImpl = new Max();
+
+    /** Minimum statistic implementation - can be reset by setter. */
+    private UnivariateStatistic minImpl = new Min();
+
+    /** Percentile statistic implementation - can be reset by setter. */
+    private UnivariateStatistic percentileImpl = new Percentile();
+
+    /** Skewness statistic implementation - can be reset by setter. */
+    private UnivariateStatistic skewnessImpl = new Skewness();
+
+    /** Variance statistic implementation - can be reset by setter. */
+    private UnivariateStatistic varianceImpl = new Variance();
+
+    /** Sum of squares statistic implementation - can be reset by setter. */
+    private UnivariateStatistic sumsqImpl = new SumOfSquares();
+
+    /** Sum statistic implementation - can be reset by setter. */
+    private UnivariateStatistic sumImpl = new Sum();
+
+    /**
+     * Construct a DescriptiveStatistics instance with an infinite window
+     */
+    public DescriptiveStatistics() {
+    }
+
+    /**
+     * Construct a DescriptiveStatistics instance with the specified window
+     *
+     * @param window the window size.
+     */
+    public DescriptiveStatistics(int window) {
+        setWindowSize(window);
+    }
+
+    /**
+     * Construct a DescriptiveStatistics instance with an infinite window
+     * and the initial data values in double[] initialDoubleArray.
+     * If initialDoubleArray is null, then this constructor corresponds to
+     * DescriptiveStatistics()
+     *
+     * @param initialDoubleArray the initial double[].
+     */
+    public DescriptiveStatistics(double[] initialDoubleArray) {
+        if (initialDoubleArray != null) {
+            eDA = new ResizableDoubleArray(initialDoubleArray);
+        }
+    }
+
+    /**
+     * Copy constructor.  Construct a new DescriptiveStatistics instance that
+     * is a copy of original.
+     *
+     * @param original DescriptiveStatistics instance to copy
+     */
+    public DescriptiveStatistics(DescriptiveStatistics original) {
+        copy(original, this);
+    }
+
+    /**
+     * Adds the value to the dataset. If the dataset is at the maximum size
+     * (i.e., the number of stored elements equals the currently configured
+     * windowSize), the first (oldest) element in the dataset is discarded
+     * to make room for the new value.
+     *
+     * @param v the value to be added
+     */
+    public void addValue(double v) {
+        if (windowSize != INFINITE_WINDOW) {
+            if (getN() == windowSize) {
+                eDA.addElementRolling(v);
+            } else if (getN() < windowSize) {
+                eDA.addElement(v);
+            }
+        } else {
+            eDA.addElement(v);
+        }
+    }
+
+    /**
+     * Removes the most recent value from the dataset.
+     */
+    public void removeMostRecentValue() {
+        eDA.discardMostRecentElements(1);
+    }
+
+    /**
+     * Replaces the most recently stored value with the given value.
+     * There must be at least one element stored to call this method.
+     *
+     * @param v the value to replace the most recent stored value
+     * @return replaced value
+     */
+    public double replaceMostRecentValue(double v) {
+        return eDA.substituteMostRecentElement(v);
+    }
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/arithmetic_mean.htm">
+     * arithmetic mean </a> of the available values
+     * @return The mean or Double.NaN if no values have been added.
+     */
+    public double getMean() {
+        return apply(meanImpl);
+    }
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/geometric_mean.htm">
+     * geometric mean </a> of the available values
+     * @return The geometricMean, Double.NaN if no values have been added,
+     * or if the product of the available values is less than or equal to 0.
+     */
+    public double getGeometricMean() {
+        return apply(geometricMeanImpl);
+    }
+
+    /**
+     * Returns the variance of the available values.
+     * @return The variance, Double.NaN if no values have been added
+     * or 0.0 for a single value set.
+     */
+    public double getVariance() {
+        return apply(varianceImpl);
+    }
+
+    /**
+     * Returns the standard deviation of the available values.
+     * @return The standard deviation, Double.NaN if no values have been added
+     * or 0.0 for a single value set.
+     */
+    public double getStandardDeviation() {
+        double stdDev = Double.NaN;
+        if (getN() > 0) {
+            if (getN() > 1) {
+                stdDev = FastMath.sqrt(getVariance());
+            } else {
+                stdDev = 0.0;
+            }
+        }
+        return stdDev;
+    }
+
+    /**
+     * Returns the skewness of the available values. Skewness is a
+     * measure of the asymmetry of a given distribution.
+     * @return The skewness, Double.NaN if no values have been added
+     * or 0.0 for a value set &lt;=2.
+     */
+    public double getSkewness() {
+        return apply(skewnessImpl);
+    }
+
+    /**
+     * Returns the Kurtosis of the available values. Kurtosis is a
+     * measure of the "peakedness" of a distribution
+     * @return The kurtosis, Double.NaN if no values have been added, or 0.0
+     * for a value set &lt;=3.
+     */
+    public double getKurtosis() {
+        return apply(kurtosisImpl);
+    }
+
+    /**
+     * Returns the maximum of the available values
+     * @return The max or Double.NaN if no values have been added.
+     */
+    public double getMax() {
+        return apply(maxImpl);
+    }
+
+    /**
+    * Returns the minimum of the available values
+    * @return The min or Double.NaN if no values have been added.
+    */
+    public double getMin() {
+        return apply(minImpl);
+    }
+
+    /**
+     * Returns the number of available values
+     * @return The number of available values
+     */
+    public long getN() {
+        return eDA.getNumElements();
+    }
+
+    /**
+     * Returns the sum of the values that have been added to Univariate.
+     * @return The sum or Double.NaN if no values have been added
+     */
+    public double getSum() {
+        return apply(sumImpl);
+    }
+
+    /**
+     * Returns the sum of the squares of the available values.
+     * @return The sum of the squares or Double.NaN if no
+     * values have been added.
+     */
+    public double getSumsq() {
+        return apply(sumsqImpl);
+    }
+
+    /**
+     * Resets all statistics and storage
+     */
+    public void clear() {
+        eDA.clear();
+    }
+
+
+    /**
+     * Returns the maximum number of values that can be stored in the
+     * dataset, or INFINITE_WINDOW (-1) if there is no limit.
+     *
+     * @return The current window size or -1 if its Infinite.
+     */
+    public int getWindowSize() {
+        return windowSize;
+    }
+
+    /**
+     * WindowSize controls the number of values which contribute
+     * to the reported statistics.  For example, if
+     * windowSize is set to 3 and the values {1,2,3,4,5}
+     * have been added <strong> in that order</strong>
+     * then the <i>available values</i> are {3,4,5} and all
+     * reported statistics will be based on these values
+     * @param windowSize sets the size of the window.
+     */
+    public void setWindowSize(int windowSize) {
+        if (windowSize < 1) {
+            if (windowSize != INFINITE_WINDOW) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.NOT_POSITIVE_WINDOW_SIZE, windowSize);
+            }
+        }
+
+        this.windowSize = windowSize;
+
+        // We need to check to see if we need to discard elements
+        // from the front of the array.  If the windowSize is less than
+        // the current number of elements.
+        if (windowSize != INFINITE_WINDOW && windowSize < eDA.getNumElements()) {
+            eDA.discardFrontElements(eDA.getNumElements() - windowSize);
+        }
+    }
+
+    /**
+     * Returns the current set of values in an array of double primitives.
+     * The order of addition is preserved.  The returned array is a fresh
+     * copy of the underlying data -- i.e., it is not a reference to the
+     * stored data.
+     *
+     * @return returns the current set of numbers in the order in which they
+     *         were added to this set
+     */
+    public double[] getValues() {
+        return eDA.getElements();
+    }
+
+    /**
+     * Returns the current set of values in an array of double primitives,
+     * sorted in ascending order.  The returned array is a fresh
+     * copy of the underlying data -- i.e., it is not a reference to the
+     * stored data.
+     * @return returns the current set of
+     * numbers sorted in ascending order
+     */
+    public double[] getSortedValues() {
+        double[] sort = getValues();
+        Arrays.sort(sort);
+        return sort;
+    }
+
+    /**
+     * Returns the element at the specified index
+     * @param index The Index of the element
+     * @return return the element at the specified index
+     */
+    public double getElement(int index) {
+        return eDA.getElement(index);
+    }
+
+    /**
+     * Returns an estimate for the pth percentile of the stored values.
+     * <p>
+     * The implementation provided here follows the first estimation procedure presented
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm">here.</a>
+     * </p><p>
+     * <strong>Preconditions</strong>:<ul>
+     * <li><code>0 &lt; p &le; 100</code> (otherwise an
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * <li>at least one value must be stored (returns <code>Double.NaN
+     *     </code> otherwise)</li>
+     * </ul></p>
+     *
+     * @param p the requested percentile (scaled from 0 - 100)
+     * @return An estimate for the pth percentile of the stored data
+     * @throws IllegalStateException if percentile implementation has been
+     *  overridden and the supplied implementation does not support setQuantile
+     * values
+     */
+    public double getPercentile(double p) {
+        if (percentileImpl instanceof Percentile) {
+            ((Percentile) percentileImpl).setQuantile(p);
+        } else {
+            try {
+                percentileImpl.getClass().getMethod(SET_QUANTILE_METHOD_NAME,
+                        new Class[] {Double.TYPE}).invoke(percentileImpl,
+                                new Object[] {Double.valueOf(p)});
+            } catch (NoSuchMethodException e1) { // Setter guard should prevent
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD,
+                      percentileImpl.getClass().getName(), SET_QUANTILE_METHOD_NAME);
+            } catch (IllegalAccessException e2) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD,
+                      SET_QUANTILE_METHOD_NAME, percentileImpl.getClass().getName());
+            } catch (InvocationTargetException e3) {
+                throw MathRuntimeException.createIllegalArgumentException(e3.getCause());
+            }
+        }
+        return apply(percentileImpl);
+    }
+
+    /**
+     * Generates a text report displaying univariate statistics from values
+     * that have been added.  Each statistic is displayed on a separate
+     * line.
+     *
+     * @return String with line feeds displaying statistics
+     */
+    @Override
+    public String toString() {
+        StringBuilder outBuffer = new StringBuilder();
+        String endl = "\n";
+        outBuffer.append("DescriptiveStatistics:").append(endl);
+        outBuffer.append("n: ").append(getN()).append(endl);
+        outBuffer.append("min: ").append(getMin()).append(endl);
+        outBuffer.append("max: ").append(getMax()).append(endl);
+        outBuffer.append("mean: ").append(getMean()).append(endl);
+        outBuffer.append("std dev: ").append(getStandardDeviation())
+            .append(endl);
+        outBuffer.append("median: ").append(getPercentile(50)).append(endl);
+        outBuffer.append("skewness: ").append(getSkewness()).append(endl);
+        outBuffer.append("kurtosis: ").append(getKurtosis()).append(endl);
+        return outBuffer.toString();
+    }
+
+    /**
+     * Apply the given statistic to the data associated with this set of statistics.
+     * @param stat the statistic to apply
+     * @return the computed value of the statistic.
+     */
+    public double apply(UnivariateStatistic stat) {
+        return stat.evaluate(eDA.getInternalValues(), eDA.start(), eDA.getNumElements());
+    }
+
+    // Implementation getters and setter
+
+    /**
+     * Returns the currently configured mean implementation.
+     *
+     * @return the UnivariateStatistic implementing the mean
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getMeanImpl() {
+        return meanImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the mean.</p>
+     *
+     * @param meanImpl the UnivariateStatistic instance to use
+     * for computing the mean
+     * @since 1.2
+     */
+    public synchronized void setMeanImpl(UnivariateStatistic meanImpl) {
+        this.meanImpl = meanImpl;
+    }
+
+    /**
+     * Returns the currently configured geometric mean implementation.
+     *
+     * @return the UnivariateStatistic implementing the geometric mean
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getGeometricMeanImpl() {
+        return geometricMeanImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the gemoetric mean.</p>
+     *
+     * @param geometricMeanImpl the UnivariateStatistic instance to use
+     * for computing the geometric mean
+     * @since 1.2
+     */
+    public synchronized void setGeometricMeanImpl(
+            UnivariateStatistic geometricMeanImpl) {
+        this.geometricMeanImpl = geometricMeanImpl;
+    }
+
+    /**
+     * Returns the currently configured kurtosis implementation.
+     *
+     * @return the UnivariateStatistic implementing the kurtosis
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getKurtosisImpl() {
+        return kurtosisImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the kurtosis.</p>
+     *
+     * @param kurtosisImpl the UnivariateStatistic instance to use
+     * for computing the kurtosis
+     * @since 1.2
+     */
+    public synchronized void setKurtosisImpl(UnivariateStatistic kurtosisImpl) {
+        this.kurtosisImpl = kurtosisImpl;
+    }
+
+    /**
+     * Returns the currently configured maximum implementation.
+     *
+     * @return the UnivariateStatistic implementing the maximum
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getMaxImpl() {
+        return maxImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the maximum.</p>
+     *
+     * @param maxImpl the UnivariateStatistic instance to use
+     * for computing the maximum
+     * @since 1.2
+     */
+    public synchronized void setMaxImpl(UnivariateStatistic maxImpl) {
+        this.maxImpl = maxImpl;
+    }
+
+    /**
+     * Returns the currently configured minimum implementation.
+     *
+     * @return the UnivariateStatistic implementing the minimum
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getMinImpl() {
+        return minImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the minimum.</p>
+     *
+     * @param minImpl the UnivariateStatistic instance to use
+     * for computing the minimum
+     * @since 1.2
+     */
+    public synchronized void setMinImpl(UnivariateStatistic minImpl) {
+        this.minImpl = minImpl;
+    }
+
+    /**
+     * Returns the currently configured percentile implementation.
+     *
+     * @return the UnivariateStatistic implementing the percentile
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getPercentileImpl() {
+        return percentileImpl;
+    }
+
+    /**
+     * Sets the implementation to be used by {@link #getPercentile(double)}.
+     * The supplied <code>UnivariateStatistic</code> must provide a
+     * <code>setQuantile(double)</code> method; otherwise
+     * <code>IllegalArgumentException</code> is thrown.
+     *
+     * @param percentileImpl the percentileImpl to set
+     * @throws IllegalArgumentException if the supplied implementation does not
+     *  provide a <code>setQuantile</code> method
+     * @since 1.2
+     */
+    public synchronized void setPercentileImpl(
+            UnivariateStatistic percentileImpl) {
+        try {
+            percentileImpl.getClass().getMethod(SET_QUANTILE_METHOD_NAME,
+                    new Class[] {Double.TYPE}).invoke(percentileImpl,
+                            new Object[] {Double.valueOf(50.0d)});
+        } catch (NoSuchMethodException e1) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.PERCENTILE_IMPLEMENTATION_UNSUPPORTED_METHOD,
+                  percentileImpl.getClass().getName(), SET_QUANTILE_METHOD_NAME);
+        } catch (IllegalAccessException e2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.PERCENTILE_IMPLEMENTATION_CANNOT_ACCESS_METHOD,
+                  SET_QUANTILE_METHOD_NAME, percentileImpl.getClass().getName());
+        } catch (InvocationTargetException e3) {
+            throw MathRuntimeException.createIllegalArgumentException(e3.getCause());
+        }
+        this.percentileImpl = percentileImpl;
+    }
+
+    /**
+     * Returns the currently configured skewness implementation.
+     *
+     * @return the UnivariateStatistic implementing the skewness
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getSkewnessImpl() {
+        return skewnessImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the skewness.</p>
+     *
+     * @param skewnessImpl the UnivariateStatistic instance to use
+     * for computing the skewness
+     * @since 1.2
+     */
+    public synchronized void setSkewnessImpl(
+            UnivariateStatistic skewnessImpl) {
+        this.skewnessImpl = skewnessImpl;
+    }
+
+    /**
+     * Returns the currently configured variance implementation.
+     *
+     * @return the UnivariateStatistic implementing the variance
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getVarianceImpl() {
+        return varianceImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the variance.</p>
+     *
+     * @param varianceImpl the UnivariateStatistic instance to use
+     * for computing the variance
+     * @since 1.2
+     */
+    public synchronized void setVarianceImpl(
+            UnivariateStatistic varianceImpl) {
+        this.varianceImpl = varianceImpl;
+    }
+
+    /**
+     * Returns the currently configured sum of squares implementation.
+     *
+     * @return the UnivariateStatistic implementing the sum of squares
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getSumsqImpl() {
+        return sumsqImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the sum of squares.</p>
+     *
+     * @param sumsqImpl the UnivariateStatistic instance to use
+     * for computing the sum of squares
+     * @since 1.2
+     */
+    public synchronized void setSumsqImpl(UnivariateStatistic sumsqImpl) {
+        this.sumsqImpl = sumsqImpl;
+    }
+
+    /**
+     * Returns the currently configured sum implementation.
+     *
+     * @return the UnivariateStatistic implementing the sum
+     * @since 1.2
+     */
+    public synchronized UnivariateStatistic getSumImpl() {
+        return sumImpl;
+    }
+
+    /**
+     * <p>Sets the implementation for the sum.</p>
+     *
+     * @param sumImpl the UnivariateStatistic instance to use
+     * for computing the sum
+     * @since 1.2
+     */
+    public synchronized void setSumImpl(UnivariateStatistic sumImpl) {
+        this.sumImpl = sumImpl;
+    }
+
+    /**
+     * Returns a copy of this DescriptiveStatistics instance with the same internal state.
+     *
+     * @return a copy of this
+     */
+    public DescriptiveStatistics copy() {
+        DescriptiveStatistics result = new DescriptiveStatistics();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source DescriptiveStatistics to copy
+     * @param dest DescriptiveStatistics to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(DescriptiveStatistics source, DescriptiveStatistics dest) {
+        // Copy data and window size
+        dest.eDA = source.eDA.copy();
+        dest.windowSize = source.windowSize;
+
+        // Copy implementations
+        dest.maxImpl = source.maxImpl.copy();
+        dest.meanImpl = source.meanImpl.copy();
+        dest.minImpl = source.minImpl.copy();
+        dest.sumImpl = source.sumImpl.copy();
+        dest.varianceImpl = source.varianceImpl.copy();
+        dest.sumsqImpl = source.sumsqImpl.copy();
+        dest.geometricMeanImpl = source.geometricMeanImpl.copy();
+        dest.kurtosisImpl = source.kurtosisImpl;
+        dest.skewnessImpl = source.skewnessImpl;
+        dest.percentileImpl = source.percentileImpl;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java
new file mode 100644
index 0000000..8062f5b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.java
@@ -0,0 +1,637 @@
+/*
+ * 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.stat.descriptive;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.stat.descriptive.moment.GeometricMean;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.VectorialCovariance;
+import org.apache.commons.math.stat.descriptive.rank.Max;
+import org.apache.commons.math.stat.descriptive.rank.Min;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
+import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * <p>Computes summary statistics for a stream of n-tuples added using the
+ * {@link #addValue(double[]) addValue} method. The data values are not stored
+ * in memory, so this class can be used to compute statistics for very large
+ * n-tuple streams.</p>
+ *
+ * <p>The {@link StorelessUnivariateStatistic} instances used to maintain
+ * summary state and compute statistics are configurable via setters.
+ * For example, the default implementation for the mean can be overridden by
+ * calling {@link #setMeanImpl(StorelessUnivariateStatistic[])}. Actual
+ * parameters to these methods must implement the
+ * {@link StorelessUnivariateStatistic} interface and configuration must be
+ * completed before <code>addValue</code> is called. No configuration is
+ * necessary to use the default, commons-math provided implementations.</p>
+ *
+ * <p>To compute statistics for a stream of n-tuples, construct a
+ * MultivariateStatistics instance with dimension n and then use
+ * {@link #addValue(double[])} to add n-tuples. The <code>getXxx</code>
+ * methods where Xxx is a statistic return an array of <code>double</code>
+ * values, where for <code>i = 0,...,n-1</code> the i<sup>th</sup> array element is the
+ * value of the given statistic for data range consisting of the i<sup>th</sup> element of
+ * each of the input n-tuples.  For example, if <code>addValue</code> is called
+ * with actual parameters {0, 1, 2}, then {3, 4, 5} and finally {6, 7, 8},
+ * <code>getSum</code> will return a three-element array with values
+ * {0+3+6, 1+4+7, 2+5+8}</p>
+ *
+ * <p>Note: This class is not thread-safe. Use
+ * {@link SynchronizedMultivariateSummaryStatistics} if concurrent access from multiple
+ * threads is required.</p>
+ *
+ * @since 1.2
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ */
+public class MultivariateSummaryStatistics
+  implements StatisticalMultivariateSummary, Serializable {
+
+    /** Serialization UID */
+    private static final long serialVersionUID = 2271900808994826718L;
+
+    /** Dimension of the data. */
+    private int k;
+
+    /** Count of values that have been added */
+    private long n = 0;
+
+    /** Sum statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] sumImpl;
+
+    /** Sum of squares statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] sumSqImpl;
+
+    /** Minimum statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] minImpl;
+
+    /** Maximum statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] maxImpl;
+
+    /** Sum of log statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] sumLogImpl;
+
+    /** Geometric mean statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] geoMeanImpl;
+
+    /** Mean statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic[] meanImpl;
+
+    /** Covariance statistic implementation - cannot be reset. */
+    private VectorialCovariance covarianceImpl;
+
+    /**
+     * Construct a MultivariateSummaryStatistics instance
+     * @param k dimension of the data
+     * @param isCovarianceBiasCorrected if true, the unbiased sample
+     * covariance is computed, otherwise the biased population covariance
+     * is computed
+     */
+    public MultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) {
+        this.k = k;
+
+        sumImpl     = new StorelessUnivariateStatistic[k];
+        sumSqImpl   = new StorelessUnivariateStatistic[k];
+        minImpl     = new StorelessUnivariateStatistic[k];
+        maxImpl     = new StorelessUnivariateStatistic[k];
+        sumLogImpl  = new StorelessUnivariateStatistic[k];
+        geoMeanImpl = new StorelessUnivariateStatistic[k];
+        meanImpl    = new StorelessUnivariateStatistic[k];
+
+        for (int i = 0; i < k; ++i) {
+            sumImpl[i]     = new Sum();
+            sumSqImpl[i]   = new SumOfSquares();
+            minImpl[i]     = new Min();
+            maxImpl[i]     = new Max();
+            sumLogImpl[i]  = new SumOfLogs();
+            geoMeanImpl[i] = new GeometricMean();
+            meanImpl[i]    = new Mean();
+        }
+
+        covarianceImpl =
+            new VectorialCovariance(k, isCovarianceBiasCorrected);
+
+    }
+
+    /**
+     * Add an n-tuple to the data
+     *
+     * @param value  the n-tuple to add
+     * @throws DimensionMismatchException if the length of the array
+     * does not match the one used at construction
+     */
+    public void addValue(double[] value)
+      throws DimensionMismatchException {
+        checkDimension(value.length);
+        for (int i = 0; i < k; ++i) {
+            double v = value[i];
+            sumImpl[i].increment(v);
+            sumSqImpl[i].increment(v);
+            minImpl[i].increment(v);
+            maxImpl[i].increment(v);
+            sumLogImpl[i].increment(v);
+            geoMeanImpl[i].increment(v);
+            meanImpl[i].increment(v);
+        }
+        covarianceImpl.increment(value);
+        n++;
+    }
+
+    /**
+     * Returns the dimension of the data
+     * @return The dimension of the data
+     */
+    public int getDimension() {
+        return k;
+    }
+
+    /**
+     * Returns the number of available values
+     * @return The number of available values
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * Returns an array of the results of a statistic.
+     * @param stats univariate statistic array
+     * @return results array
+     */
+    private double[] getResults(StorelessUnivariateStatistic[] stats) {
+        double[] results = new double[stats.length];
+        for (int i = 0; i < results.length; ++i) {
+            results[i] = stats[i].getResult();
+        }
+        return results;
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the sum of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component sums
+     */
+    public double[] getSum() {
+        return getResults(sumImpl);
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the sum of squares of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component sums of squares
+     */
+    public double[] getSumSq() {
+        return getResults(sumSqImpl);
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the sum of logs of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component log sums
+     */
+    public double[] getSumLog() {
+        return getResults(sumLogImpl);
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the mean of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component means
+     */
+    public double[] getMean() {
+        return getResults(meanImpl);
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the standard deviation of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component standard deviations
+     */
+    public double[] getStandardDeviation() {
+        double[] stdDev = new double[k];
+        if (getN() < 1) {
+            Arrays.fill(stdDev, Double.NaN);
+        } else if (getN() < 2) {
+            Arrays.fill(stdDev, 0.0);
+        } else {
+            RealMatrix matrix = covarianceImpl.getResult();
+            for (int i = 0; i < k; ++i) {
+                stdDev[i] = FastMath.sqrt(matrix.getEntry(i, i));
+            }
+        }
+        return stdDev;
+    }
+
+    /**
+     * Returns the covariance matrix of the values that have been added.
+     *
+     * @return the covariance matrix
+     */
+    public RealMatrix getCovariance() {
+        return covarianceImpl.getResult();
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the maximum of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component maxima
+     */
+    public double[] getMax() {
+        return getResults(maxImpl);
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the minimum of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component minima
+     */
+    public double[] getMin() {
+        return getResults(minImpl);
+    }
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the geometric mean of the
+     * i<sup>th</sup> entries of the arrays that have been added using
+     * {@link #addValue(double[])}
+     *
+     * @return the array of component geometric means
+     */
+    public double[] getGeometricMean() {
+        return getResults(geoMeanImpl);
+    }
+
+    /**
+     * Generates a text report displaying
+     * summary statistics from values that
+     * have been added.
+     * @return String with line feeds displaying statistics
+     */
+    @Override
+    public String toString() {
+        final String separator = ", ";
+        final String suffix = System.getProperty("line.separator");
+        StringBuilder outBuffer = new StringBuilder();
+        outBuffer.append("MultivariateSummaryStatistics:" + suffix);
+        outBuffer.append("n: " + getN() + suffix);
+        append(outBuffer, getMin(), "min: ", separator, suffix);
+        append(outBuffer, getMax(), "max: ", separator, suffix);
+        append(outBuffer, getMean(), "mean: ", separator, suffix);
+        append(outBuffer, getGeometricMean(), "geometric mean: ", separator, suffix);
+        append(outBuffer, getSumSq(), "sum of squares: ", separator, suffix);
+        append(outBuffer, getSumLog(), "sum of logarithms: ", separator, suffix);
+        append(outBuffer, getStandardDeviation(), "standard deviation: ", separator, suffix);
+        outBuffer.append("covariance: " + getCovariance().toString() + suffix);
+        return outBuffer.toString();
+    }
+
+    /**
+     * Append a text representation of an array to a buffer.
+     * @param buffer buffer to fill
+     * @param data data array
+     * @param prefix text prefix
+     * @param separator elements separator
+     * @param suffix text suffix
+     */
+    private void append(StringBuilder buffer, double[] data,
+                        String prefix, String separator, String suffix) {
+        buffer.append(prefix);
+        for (int i = 0; i < data.length; ++i) {
+            if (i > 0) {
+                buffer.append(separator);
+            }
+            buffer.append(data[i]);
+        }
+        buffer.append(suffix);
+    }
+
+    /**
+     * Resets all statistics and storage
+     */
+    public void clear() {
+        this.n = 0;
+        for (int i = 0; i < k; ++i) {
+            minImpl[i].clear();
+            maxImpl[i].clear();
+            sumImpl[i].clear();
+            sumLogImpl[i].clear();
+            sumSqImpl[i].clear();
+            geoMeanImpl[i].clear();
+            meanImpl[i].clear();
+        }
+        covarianceImpl.clear();
+    }
+
+    /**
+     * Returns true iff <code>object</code> is a <code>MultivariateSummaryStatistics</code>
+     * instance and all statistics have the same values as this.
+     * @param object the object to test equality against.
+     * @return true if object equals this
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this ) {
+            return true;
+        }
+        if (object instanceof MultivariateSummaryStatistics == false) {
+            return false;
+        }
+        MultivariateSummaryStatistics stat = (MultivariateSummaryStatistics) object;
+        return MathUtils.equalsIncludingNaN(stat.getGeometricMean(), getGeometricMean()) &&
+               MathUtils.equalsIncludingNaN(stat.getMax(),           getMax())           &&
+               MathUtils.equalsIncludingNaN(stat.getMean(),          getMean())          &&
+               MathUtils.equalsIncludingNaN(stat.getMin(),           getMin())           &&
+               MathUtils.equalsIncludingNaN(stat.getN(),             getN())             &&
+               MathUtils.equalsIncludingNaN(stat.getSum(),           getSum())           &&
+               MathUtils.equalsIncludingNaN(stat.getSumSq(),         getSumSq())         &&
+               MathUtils.equalsIncludingNaN(stat.getSumLog(),        getSumLog())        &&
+               stat.getCovariance().equals( getCovariance());
+    }
+
+    /**
+     * Returns hash code based on values of statistics
+     *
+     * @return hash code
+     */
+    @Override
+    public int hashCode() {
+        int result = 31 + MathUtils.hash(getGeometricMean());
+        result = result * 31 + MathUtils.hash(getGeometricMean());
+        result = result * 31 + MathUtils.hash(getMax());
+        result = result * 31 + MathUtils.hash(getMean());
+        result = result * 31 + MathUtils.hash(getMin());
+        result = result * 31 + MathUtils.hash(getN());
+        result = result * 31 + MathUtils.hash(getSum());
+        result = result * 31 + MathUtils.hash(getSumSq());
+        result = result * 31 + MathUtils.hash(getSumLog());
+        result = result * 31 + getCovariance().hashCode();
+        return result;
+    }
+
+    // Getters and setters for statistics implementations
+    /**
+     * Sets statistics implementations.
+     * @param newImpl new implementations for statistics
+     * @param oldImpl old implementations for statistics
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    private void setImpl(StorelessUnivariateStatistic[] newImpl,
+                         StorelessUnivariateStatistic[] oldImpl)
+       throws DimensionMismatchException, IllegalStateException {
+        checkEmpty();
+        checkDimension(newImpl.length);
+        System.arraycopy(newImpl, 0, oldImpl, 0, newImpl.length);
+    }
+
+    /**
+     * Returns the currently configured Sum implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the sum
+     */
+    public StorelessUnivariateStatistic[] getSumImpl() {
+        return sumImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the Sum.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param sumImpl the StorelessUnivariateStatistic instance to use
+     * for computing the Sum
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setSumImpl(StorelessUnivariateStatistic[] sumImpl)
+      throws DimensionMismatchException {
+        setImpl(sumImpl, this.sumImpl);
+    }
+
+    /**
+     * Returns the currently configured sum of squares implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the sum of squares
+     */
+    public StorelessUnivariateStatistic[] getSumsqImpl() {
+        return sumSqImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the sum of squares.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param sumsqImpl the StorelessUnivariateStatistic instance to use
+     * for computing the sum of squares
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl)
+      throws DimensionMismatchException {
+        setImpl(sumsqImpl, this.sumSqImpl);
+    }
+
+    /**
+     * Returns the currently configured minimum implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the minimum
+     */
+    public StorelessUnivariateStatistic[] getMinImpl() {
+        return minImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the minimum.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param minImpl the StorelessUnivariateStatistic instance to use
+     * for computing the minimum
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setMinImpl(StorelessUnivariateStatistic[] minImpl)
+      throws DimensionMismatchException {
+        setImpl(minImpl, this.minImpl);
+    }
+
+    /**
+     * Returns the currently configured maximum implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the maximum
+     */
+    public StorelessUnivariateStatistic[] getMaxImpl() {
+        return maxImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the maximum.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param maxImpl the StorelessUnivariateStatistic instance to use
+     * for computing the maximum
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setMaxImpl(StorelessUnivariateStatistic[] maxImpl)
+      throws DimensionMismatchException {
+        setImpl(maxImpl, this.maxImpl);
+    }
+
+    /**
+     * Returns the currently configured sum of logs implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the log sum
+     */
+    public StorelessUnivariateStatistic[] getSumLogImpl() {
+        return sumLogImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the sum of logs.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param sumLogImpl the StorelessUnivariateStatistic instance to use
+     * for computing the log sum
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl)
+      throws DimensionMismatchException {
+        setImpl(sumLogImpl, this.sumLogImpl);
+    }
+
+    /**
+     * Returns the currently configured geometric mean implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the geometric mean
+     */
+    public StorelessUnivariateStatistic[] getGeoMeanImpl() {
+        return geoMeanImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the geometric mean.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param geoMeanImpl the StorelessUnivariateStatistic instance to use
+     * for computing the geometric mean
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl)
+      throws DimensionMismatchException {
+        setImpl(geoMeanImpl, this.geoMeanImpl);
+    }
+
+    /**
+     * Returns the currently configured mean implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the mean
+     */
+    public StorelessUnivariateStatistic[] getMeanImpl() {
+        return meanImpl.clone();
+    }
+
+    /**
+     * <p>Sets the implementation for the mean.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double[]) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param meanImpl the StorelessUnivariateStatistic instance to use
+     * for computing the mean
+     * @throws DimensionMismatchException if the array dimension
+     * does not match the one used at construction
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setMeanImpl(StorelessUnivariateStatistic[] meanImpl)
+      throws DimensionMismatchException {
+        setImpl(meanImpl, this.meanImpl);
+    }
+
+    /**
+     * Throws IllegalStateException if n > 0.
+     */
+    private void checkEmpty() {
+        if (n > 0) {
+            throw MathRuntimeException.createIllegalStateException(
+                    LocalizedFormats.VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC,
+                    n);
+        }
+    }
+
+    /**
+     * Throws DimensionMismatchException if dimension != k.
+     * @param dimension dimension to check
+     * @throws DimensionMismatchException if dimension != k
+     */
+    private void checkDimension(int dimension)
+      throws DimensionMismatchException {
+        if (dimension != k) {
+            throw new DimensionMismatchException(dimension, k);
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java b/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java
new file mode 100644
index 0000000..517788c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.java
@@ -0,0 +1,120 @@
+/*
+ * 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.stat.descriptive;
+
+import org.apache.commons.math.linear.RealMatrix;
+
+/**
+ *  Reporting interface for basic multivariate statistics.
+ *
+ * @since 1.2
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ */
+public interface StatisticalMultivariateSummary {
+
+    /**
+     * Returns the dimension of the data
+     * @return The dimension of the data
+     */
+    int getDimension();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * mean of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component means
+     */
+    double[] getMean();
+
+    /**
+     * Returns the covariance of the available values.
+     * @return The covariance, null if no multivariate sample
+     * have been added or a zeroed matrix for a single value set.
+     */
+    RealMatrix getCovariance();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * standard deviation of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component standard deviations
+     */
+    double[] getStandardDeviation();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * maximum of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component maxima
+     */
+    double[] getMax();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * minimum of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component minima
+     */
+    double[] getMin();
+
+    /**
+     * Returns the number of available values
+     * @return The number of available values
+     */
+    long getN();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * geometric mean of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component geometric means
+     */
+    double[] getGeometricMean();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * sum of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component sums
+     */
+    double[] getSum();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * sum of squares of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component sums of squares
+     */
+    double[] getSumSq();
+
+    /**
+     * Returns an array whose i<sup>th</sup> entry is the
+     * sum of logs of the i<sup>th</sup> entries of the arrays
+     * that correspond to each multivariate sample
+     *
+     * @return the array of component log sums
+     */
+    double[] getSumLog();
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummary.java b/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummary.java
new file mode 100644
index 0000000..5592053
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummary.java
@@ -0,0 +1,65 @@
+/*
+ * 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.stat.descriptive;
+
+/**
+ *  Reporting interface for basic univariate statistics.
+ *
+  * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ */
+public interface StatisticalSummary {
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/arithmetic_mean.htm">
+     * arithmetic mean </a> of the available values
+     * @return The mean or Double.NaN if no values have been added.
+     */
+    double getMean();
+    /**
+     * Returns the variance of the available values.
+     * @return The variance, Double.NaN if no values have been added
+     * or 0.0 for a single value set.
+     */
+    double getVariance();
+    /**
+     * Returns the standard deviation of the available values.
+     * @return The standard deviation, Double.NaN if no values have been added
+     * or 0.0 for a single value set.
+     */
+    double getStandardDeviation();
+    /**
+     * Returns the maximum of the available values
+     * @return The max or Double.NaN if no values have been added.
+     */
+    double getMax();
+    /**
+    * Returns the minimum of the available values
+    * @return The min or Double.NaN if no values have been added.
+    */
+    double getMin();
+    /**
+     * Returns the number of available values
+     * @return The number of available values
+     */
+    long getN();
+    /**
+     * Returns the sum of the values that have been added to Univariate.
+     * @return The sum or Double.NaN if no values have been added
+     */
+    double getSum();
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues.java b/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues.java
new file mode 100644
index 0000000..e72639a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues.java
@@ -0,0 +1,186 @@
+/*
+ * 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.stat.descriptive;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.util.FastMath;
+import org.apache.commons.math.util.MathUtils;
+
+/**
+ *  Value object representing the results of a univariate statistical summary.
+ *
+ * @version $Revision: 1054186 $ $Date: 2011-01-01 03:28:46 +0100 (sam. 01 janv. 2011) $
+ */
+public class StatisticalSummaryValues implements Serializable,
+    StatisticalSummary {
+
+    /** Serialization id */
+    private static final long serialVersionUID = -5108854841843722536L;
+
+    /** The sample mean */
+    private final double mean;
+
+    /** The sample variance */
+    private final double variance;
+
+    /** The number of observations in the sample */
+    private final long n;
+
+    /** The maximum value */
+    private final double max;
+
+    /** The minimum value */
+    private final double min;
+
+    /** The sum of the sample values */
+    private final double sum;
+
+    /**
+      * Constructor
+      *
+      * @param mean  the sample mean
+      * @param variance  the sample variance
+      * @param n  the number of observations in the sample
+      * @param max  the maximum value
+      * @param min  the minimum value
+      * @param sum  the sum of the values
+     */
+    public StatisticalSummaryValues(double mean, double variance, long n,
+        double max, double min, double sum) {
+        super();
+        this.mean = mean;
+        this.variance = variance;
+        this.n = n;
+        this.max = max;
+        this.min = min;
+        this.sum = sum;
+    }
+
+    /**
+     * @return Returns the max.
+     */
+    public double getMax() {
+        return max;
+    }
+
+    /**
+     * @return Returns the mean.
+     */
+    public double getMean() {
+        return mean;
+    }
+
+    /**
+     * @return Returns the min.
+     */
+    public double getMin() {
+        return min;
+    }
+
+    /**
+     * @return Returns the number of values.
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * @return Returns the sum.
+     */
+    public double getSum() {
+        return sum;
+    }
+
+    /**
+     * @return Returns the standard deviation
+     */
+    public double getStandardDeviation() {
+        return FastMath.sqrt(variance);
+    }
+
+    /**
+     * @return Returns the variance.
+     */
+    public double getVariance() {
+        return variance;
+    }
+
+    /**
+     * Returns true iff <code>object</code> is a
+     * <code>StatisticalSummaryValues</code> instance and all statistics have
+     *  the same values as this.
+     *
+     * @param object the object to test equality against.
+     * @return true if object equals this
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this ) {
+            return true;
+        }
+        if (object instanceof StatisticalSummaryValues == false) {
+            return false;
+        }
+        StatisticalSummaryValues stat = (StatisticalSummaryValues) object;
+        return MathUtils.equalsIncludingNaN(stat.getMax(),      getMax())  &&
+               MathUtils.equalsIncludingNaN(stat.getMean(),     getMean()) &&
+               MathUtils.equalsIncludingNaN(stat.getMin(),      getMin())  &&
+               MathUtils.equalsIncludingNaN(stat.getN(),        getN())    &&
+               MathUtils.equalsIncludingNaN(stat.getSum(),      getSum())  &&
+               MathUtils.equalsIncludingNaN(stat.getVariance(), getVariance());
+    }
+
+    /**
+     * Returns hash code based on values of statistics
+     *
+     * @return hash code
+     */
+    @Override
+    public int hashCode() {
+        int result = 31 + MathUtils.hash(getMax());
+        result = result * 31 + MathUtils.hash(getMean());
+        result = result * 31 + MathUtils.hash(getMin());
+        result = result * 31 + MathUtils.hash(getN());
+        result = result * 31 + MathUtils.hash(getSum());
+        result = result * 31 + MathUtils.hash(getVariance());
+        return result;
+    }
+
+    /**
+     * Generates a text report displaying values of statistics.
+     * Each statistic is displayed on a separate line.
+     *
+     * @return String with line feeds displaying statistics
+     */
+    @Override
+    public String toString() {
+        StringBuilder outBuffer = new StringBuilder();
+        String endl = "\n";
+        outBuffer.append("StatisticalSummaryValues:").append(endl);
+        outBuffer.append("n: ").append(getN()).append(endl);
+        outBuffer.append("min: ").append(getMin()).append(endl);
+        outBuffer.append("max: ").append(getMax()).append(endl);
+        outBuffer.append("mean: ").append(getMean()).append(endl);
+        outBuffer.append("std dev: ").append(getStandardDeviation())
+            .append(endl);
+        outBuffer.append("variance: ").append(getVariance()).append(endl);
+        outBuffer.append("sum: ").append(getSum()).append(endl);
+        return outBuffer.toString();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatistic.java b/src/main/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatistic.java
new file mode 100644
index 0000000..9b9fcb4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatistic.java
@@ -0,0 +1,86 @@
+/*
+ * 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.stat.descriptive;
+
+/**
+ * Extends the definition of {@link UnivariateStatistic} with
+ * {@link #increment} and {@link #incrementAll(double[])} methods for adding
+ * values and updating internal state.
+ * <p>
+ * This interface is designed to be used for calculating statistics that can be
+ * computed in one pass through the data without storing the full array of
+ * sample values.</p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface StorelessUnivariateStatistic extends UnivariateStatistic {
+
+    /**
+     * Updates the internal state of the statistic to reflect the addition of the new value.
+     * @param d  the new value.
+     */
+    void increment(double d);
+
+    /**
+     * Updates the internal state of the statistic to reflect addition of
+     * all values in the values array.  Does not clear the statistic first --
+     * i.e., the values are added <strong>incrementally</strong> to the dataset.
+     *
+     * @param values  array holding the new values to add
+     * @throws IllegalArgumentException if the array is null
+     */
+    void incrementAll(double[] values);
+
+    /**
+     * Updates the internal state of the statistic to reflect addition of
+     * the values in the designated portion of the values array.  Does not
+     * clear the statistic first -- i.e., the values are added
+     * <strong>incrementally</strong> to the dataset.
+     *
+     * @param values  array holding the new values to add
+     * @param start  the array index of the first value to add
+     * @param length  the number of elements to add
+     * @throws IllegalArgumentException if the array is null or the index
+     */
+    void incrementAll(double[] values, int start, int length);
+
+    /**
+     * Returns the current value of the Statistic.
+     * @return value of the statistic, <code>Double.NaN</code> if it
+     * has been cleared or just instantiated.
+     */
+    double getResult();
+
+    /**
+     * Returns the number of values that have been added.
+     * @return the number of values.
+     */
+    long getN();
+
+    /**
+     * Clears the internal state of the Statistic
+     */
+    void clear();
+
+    /**
+     * Returns a copy of the statistic with the same internal state.
+     *
+     * @return a copy of the statistic
+     */
+    StorelessUnivariateStatistic copy();
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/SummaryStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/SummaryStatistics.java
new file mode 100644
index 0000000..017a84d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/SummaryStatistics.java
@@ -0,0 +1,717 @@
+/*
+ * 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.stat.descriptive;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.moment.GeometricMean;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.SecondMoment;
+import org.apache.commons.math.stat.descriptive.moment.Variance;
+import org.apache.commons.math.stat.descriptive.rank.Max;
+import org.apache.commons.math.stat.descriptive.rank.Min;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
+import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
+import org.apache.commons.math.util.MathUtils;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * <p>
+ * Computes summary statistics for a stream of data values added using the
+ * {@link #addValue(double) addValue} method. The data values are not stored in
+ * memory, so this class can be used to compute statistics for very large data
+ * streams.
+ * </p>
+ * <p>
+ * The {@link StorelessUnivariateStatistic} instances used to maintain summary
+ * state and compute statistics are configurable via setters. For example, the
+ * default implementation for the variance can be overridden by calling
+ * {@link #setVarianceImpl(StorelessUnivariateStatistic)}. Actual parameters to
+ * these methods must implement the {@link StorelessUnivariateStatistic}
+ * interface and configuration must be completed before <code>addValue</code>
+ * is called. No configuration is necessary to use the default, commons-math
+ * provided implementations.
+ * </p>
+ * <p>
+ * Note: This class is not thread-safe. Use
+ * {@link SynchronizedSummaryStatistics} if concurrent access from multiple
+ * threads is required.
+ * </p>
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ */
+public class SummaryStatistics implements StatisticalSummary, Serializable {
+
+    /** Serialization UID */
+    private static final long serialVersionUID = -2021321786743555871L;
+
+    /** count of values that have been added */
+    protected long n = 0;
+
+    /** SecondMoment is used to compute the mean and variance */
+    protected SecondMoment secondMoment = new SecondMoment();
+
+    /** sum of values that have been added */
+    protected Sum sum = new Sum();
+
+    /** sum of the square of each value that has been added */
+    protected SumOfSquares sumsq = new SumOfSquares();
+
+    /** min of values that have been added */
+    protected Min min = new Min();
+
+    /** max of values that have been added */
+    protected Max max = new Max();
+
+    /** sumLog of values that have been added */
+    protected SumOfLogs sumLog = new SumOfLogs();
+
+    /** geoMean of values that have been added */
+    protected GeometricMean geoMean = new GeometricMean(sumLog);
+
+    /** mean of values that have been added */
+    protected Mean mean = new Mean();
+
+    /** variance of values that have been added */
+    protected Variance variance = new Variance();
+
+    /** Sum statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic sumImpl = sum;
+
+    /** Sum of squares statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic sumsqImpl = sumsq;
+
+    /** Minimum statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic minImpl = min;
+
+    /** Maximum statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic maxImpl = max;
+
+    /** Sum of log statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic sumLogImpl = sumLog;
+
+    /** Geometric mean statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic geoMeanImpl = geoMean;
+
+    /** Mean statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic meanImpl = mean;
+
+    /** Variance statistic implementation - can be reset by setter. */
+    private StorelessUnivariateStatistic varianceImpl = variance;
+
+    /**
+     * Construct a SummaryStatistics instance
+     */
+    public SummaryStatistics() {
+    }
+
+    /**
+     * A copy constructor. Creates a deep-copy of the {@code original}.
+     *
+     * @param original the {@code SummaryStatistics} instance to copy
+     */
+    public SummaryStatistics(SummaryStatistics original) {
+        copy(original, this);
+    }
+
+    /**
+     * Return a {@link StatisticalSummaryValues} instance reporting current
+     * statistics.
+     * @return Current values of statistics
+     */
+    public StatisticalSummary getSummary() {
+        return new StatisticalSummaryValues(getMean(), getVariance(), getN(),
+                getMax(), getMin(), getSum());
+    }
+
+    /**
+     * Add a value to the data
+     * @param value the value to add
+     */
+    public void addValue(double value) {
+        sumImpl.increment(value);
+        sumsqImpl.increment(value);
+        minImpl.increment(value);
+        maxImpl.increment(value);
+        sumLogImpl.increment(value);
+        secondMoment.increment(value);
+        // If mean, variance or geomean have been overridden,
+        // need to increment these
+        if (!(meanImpl instanceof Mean)) {
+            meanImpl.increment(value);
+        }
+        if (!(varianceImpl instanceof Variance)) {
+            varianceImpl.increment(value);
+        }
+        if (!(geoMeanImpl instanceof GeometricMean)) {
+            geoMeanImpl.increment(value);
+        }
+        n++;
+    }
+
+    /**
+     * Returns the number of available values
+     * @return The number of available values
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * Returns the sum of the values that have been added
+     * @return The sum or <code>Double.NaN</code> if no values have been added
+     */
+    public double getSum() {
+        return sumImpl.getResult();
+    }
+
+    /**
+     * Returns the sum of the squares of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return The sum of squares
+     */
+    public double getSumsq() {
+        return sumsqImpl.getResult();
+    }
+
+    /**
+     * Returns the mean of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the mean
+     */
+    public double getMean() {
+        if (mean == meanImpl) {
+            return new Mean(secondMoment).getResult();
+        } else {
+            return meanImpl.getResult();
+        }
+    }
+
+    /**
+     * Returns the standard deviation of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the standard deviation
+     */
+    public double getStandardDeviation() {
+        double stdDev = Double.NaN;
+        if (getN() > 0) {
+            if (getN() > 1) {
+                stdDev = FastMath.sqrt(getVariance());
+            } else {
+                stdDev = 0.0;
+            }
+        }
+        return stdDev;
+    }
+
+    /**
+     * Returns the variance of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the variance
+     */
+    public double getVariance() {
+        if (varianceImpl == variance) {
+            return new Variance(secondMoment).getResult();
+        } else {
+            return varianceImpl.getResult();
+        }
+    }
+
+    /**
+     * Returns the maximum of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the maximum
+     */
+    public double getMax() {
+        return maxImpl.getResult();
+    }
+
+    /**
+     * Returns the minimum of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the minimum
+     */
+    public double getMin() {
+        return minImpl.getResult();
+    }
+
+    /**
+     * Returns the geometric mean of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the geometric mean
+     */
+    public double getGeometricMean() {
+        return geoMeanImpl.getResult();
+    }
+
+    /**
+     * Returns the sum of the logs of the values that have been added.
+     * <p>
+     * Double.NaN is returned if no values have been added.
+     * </p>
+     * @return the sum of logs
+     * @since 1.2
+     */
+    public double getSumOfLogs() {
+        return sumLogImpl.getResult();
+    }
+
+    /**
+     * Returns a statistic related to the Second Central Moment.  Specifically,
+     * what is returned is the sum of squared deviations from the sample mean
+     * among the values that have been added.
+     * <p>
+     * Returns <code>Double.NaN</code> if no data values have been added and
+     * returns <code>0</code> if there is just one value in the data set.</p>
+     * <p>
+     * @return second central moment statistic
+     * @since 2.0
+     */
+    public double getSecondMoment() {
+        return secondMoment.getResult();
+    }
+
+    /**
+     * Generates a text report displaying summary statistics from values that
+     * have been added.
+     * @return String with line feeds displaying statistics
+     * @since 1.2
+     */
+    @Override
+    public String toString() {
+        StringBuilder outBuffer = new StringBuilder();
+        String endl = "\n";
+        outBuffer.append("SummaryStatistics:").append(endl);
+        outBuffer.append("n: ").append(getN()).append(endl);
+        outBuffer.append("min: ").append(getMin()).append(endl);
+        outBuffer.append("max: ").append(getMax()).append(endl);
+        outBuffer.append("mean: ").append(getMean()).append(endl);
+        outBuffer.append("geometric mean: ").append(getGeometricMean())
+            .append(endl);
+        outBuffer.append("variance: ").append(getVariance()).append(endl);
+        outBuffer.append("sum of squares: ").append(getSumsq()).append(endl);
+        outBuffer.append("standard deviation: ").append(getStandardDeviation())
+            .append(endl);
+        outBuffer.append("sum of logs: ").append(getSumOfLogs()).append(endl);
+        return outBuffer.toString();
+    }
+
+    /**
+     * Resets all statistics and storage
+     */
+    public void clear() {
+        this.n = 0;
+        minImpl.clear();
+        maxImpl.clear();
+        sumImpl.clear();
+        sumLogImpl.clear();
+        sumsqImpl.clear();
+        geoMeanImpl.clear();
+        secondMoment.clear();
+        if (meanImpl != mean) {
+            meanImpl.clear();
+        }
+        if (varianceImpl != variance) {
+            varianceImpl.clear();
+        }
+    }
+
+    /**
+     * Returns true iff <code>object</code> is a
+     * <code>SummaryStatistics</code> instance and all statistics have the
+     * same values as this.
+     * @param object the object to test equality against.
+     * @return true if object equals this
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object instanceof SummaryStatistics == false) {
+            return false;
+        }
+        SummaryStatistics stat = (SummaryStatistics)object;
+        return MathUtils.equalsIncludingNaN(stat.getGeometricMean(), getGeometricMean()) &&
+               MathUtils.equalsIncludingNaN(stat.getMax(),           getMax())           &&
+               MathUtils.equalsIncludingNaN(stat.getMean(),          getMean())          &&
+               MathUtils.equalsIncludingNaN(stat.getMin(),           getMin())           &&
+               MathUtils.equalsIncludingNaN(stat.getN(),             getN())             &&
+               MathUtils.equalsIncludingNaN(stat.getSum(),           getSum())           &&
+               MathUtils.equalsIncludingNaN(stat.getSumsq(),         getSumsq())         &&
+               MathUtils.equalsIncludingNaN(stat.getVariance(),      getVariance());
+    }
+
+    /**
+     * Returns hash code based on values of statistics
+     * @return hash code
+     */
+    @Override
+    public int hashCode() {
+        int result = 31 + MathUtils.hash(getGeometricMean());
+        result = result * 31 + MathUtils.hash(getGeometricMean());
+        result = result * 31 + MathUtils.hash(getMax());
+        result = result * 31 + MathUtils.hash(getMean());
+        result = result * 31 + MathUtils.hash(getMin());
+        result = result * 31 + MathUtils.hash(getN());
+        result = result * 31 + MathUtils.hash(getSum());
+        result = result * 31 + MathUtils.hash(getSumsq());
+        result = result * 31 + MathUtils.hash(getVariance());
+        return result;
+    }
+
+    // Getters and setters for statistics implementations
+    /**
+     * Returns the currently configured Sum implementation
+     * @return the StorelessUnivariateStatistic implementing the sum
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getSumImpl() {
+        return sumImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the Sum.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param sumImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the Sum
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setSumImpl(StorelessUnivariateStatistic sumImpl) {
+        checkEmpty();
+        this.sumImpl = sumImpl;
+    }
+
+    /**
+     * Returns the currently configured sum of squares implementation
+     * @return the StorelessUnivariateStatistic implementing the sum of squares
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getSumsqImpl() {
+        return sumsqImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the sum of squares.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param sumsqImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the sum of squares
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) {
+        checkEmpty();
+        this.sumsqImpl = sumsqImpl;
+    }
+
+    /**
+     * Returns the currently configured minimum implementation
+     * @return the StorelessUnivariateStatistic implementing the minimum
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getMinImpl() {
+        return minImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the minimum.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param minImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the minimum
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setMinImpl(StorelessUnivariateStatistic minImpl) {
+        checkEmpty();
+        this.minImpl = minImpl;
+    }
+
+    /**
+     * Returns the currently configured maximum implementation
+     * @return the StorelessUnivariateStatistic implementing the maximum
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getMaxImpl() {
+        return maxImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the maximum.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param maxImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the maximum
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setMaxImpl(StorelessUnivariateStatistic maxImpl) {
+        checkEmpty();
+        this.maxImpl = maxImpl;
+    }
+
+    /**
+     * Returns the currently configured sum of logs implementation
+     * @return the StorelessUnivariateStatistic implementing the log sum
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getSumLogImpl() {
+        return sumLogImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the sum of logs.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param sumLogImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the log sum
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) {
+        checkEmpty();
+        this.sumLogImpl = sumLogImpl;
+        geoMean.setSumLogImpl(sumLogImpl);
+    }
+
+    /**
+     * Returns the currently configured geometric mean implementation
+     * @return the StorelessUnivariateStatistic implementing the geometric mean
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getGeoMeanImpl() {
+        return geoMeanImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the geometric mean.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param geoMeanImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the geometric mean
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) {
+        checkEmpty();
+        this.geoMeanImpl = geoMeanImpl;
+    }
+
+    /**
+     * Returns the currently configured mean implementation
+     * @return the StorelessUnivariateStatistic implementing the mean
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getMeanImpl() {
+        return meanImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the mean.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param meanImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the mean
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setMeanImpl(StorelessUnivariateStatistic meanImpl) {
+        checkEmpty();
+        this.meanImpl = meanImpl;
+    }
+
+    /**
+     * Returns the currently configured variance implementation
+     * @return the StorelessUnivariateStatistic implementing the variance
+     * @since 1.2
+     */
+    public StorelessUnivariateStatistic getVarianceImpl() {
+        return varianceImpl;
+    }
+
+    /**
+     * <p>
+     * Sets the implementation for the variance.
+     * </p>
+     * <p>
+     * This method must be activated before any data has been added - i.e.,
+     * before {@link #addValue(double) addValue} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.
+     * </p>
+     * @param varianceImpl the StorelessUnivariateStatistic instance to use for
+     *        computing the variance
+     * @throws IllegalStateException if data has already been added (i.e if n >
+     *         0)
+     * @since 1.2
+     */
+    public void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) {
+        checkEmpty();
+        this.varianceImpl = varianceImpl;
+    }
+
+    /**
+     * Throws IllegalStateException if n > 0.
+     */
+    private void checkEmpty() {
+        if (n > 0) {
+            throw MathRuntimeException.createIllegalStateException(
+                    LocalizedFormats.VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC,
+                    n);
+        }
+    }
+
+    /**
+     * Returns a copy of this SummaryStatistics instance with the same internal state.
+     *
+     * @return a copy of this
+     */
+    public SummaryStatistics copy() {
+        SummaryStatistics result = new SummaryStatistics();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source SummaryStatistics to copy
+     * @param dest SummaryStatistics to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(SummaryStatistics source, SummaryStatistics dest) {
+        dest.maxImpl = source.maxImpl.copy();
+        dest.meanImpl = source.meanImpl.copy();
+        dest.minImpl = source.minImpl.copy();
+        dest.sumImpl = source.sumImpl.copy();
+        dest.varianceImpl = source.varianceImpl.copy();
+        dest.sumLogImpl = source.sumLogImpl.copy();
+        dest.sumsqImpl = source.sumsqImpl.copy();
+        if (source.getGeoMeanImpl() instanceof GeometricMean) {
+            // Keep geoMeanImpl, sumLogImpl in synch
+            dest.geoMeanImpl = new GeometricMean((SumOfLogs) dest.sumLogImpl);
+        } else {
+            dest.geoMeanImpl = source.geoMeanImpl.copy();
+        }
+        SecondMoment.copy(source.secondMoment, dest.secondMoment);
+        dest.n = source.n;
+
+        // Make sure that if stat == statImpl in source, same
+        // holds in dest; otherwise copy stat
+        if (source.geoMean == source.geoMeanImpl) {
+            dest.geoMean = (GeometricMean) dest.geoMeanImpl;
+        } else {
+            GeometricMean.copy(source.geoMean, dest.geoMean);
+        }
+        if (source.max == source.maxImpl) {
+            dest.max = (Max) dest.maxImpl;
+        } else {
+            Max.copy(source.max, dest.max);
+        }
+        if (source.mean == source.meanImpl) {
+            dest.mean = (Mean) dest.meanImpl;
+        } else {
+            Mean.copy(source.mean, dest.mean);
+        }
+        if (source.min == source.minImpl) {
+            dest.min = (Min) dest.minImpl;
+        } else {
+            Min.copy(source.min, dest.min);
+        }
+        if (source.sum == source.sumImpl) {
+            dest.sum = (Sum) dest.sumImpl;
+        } else {
+            Sum.copy(source.sum, dest.sum);
+        }
+        if (source.variance == source.varianceImpl) {
+            dest.variance = (Variance) dest.varianceImpl;
+        } else {
+            Variance.copy(source.variance, dest.variance);
+        }
+        if (source.sumLog == source.sumLogImpl) {
+            dest.sumLog = (SumOfLogs) dest.sumLogImpl;
+        } else {
+            SumOfLogs.copy(source.sumLog, dest.sumLog);
+        }
+        if (source.sumsq == source.sumsqImpl) {
+            dest.sumsq = (SumOfSquares) dest.sumsqImpl;
+        } else {
+            SumOfSquares.copy(source.sumsq, dest.sumsq);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatistics.java
new file mode 100644
index 0000000..f1a932d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatistics.java
@@ -0,0 +1,172 @@
+/*
+ * 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.stat.descriptive;
+
+/**
+ * Implementation of
+ * {@link org.apache.commons.math.stat.descriptive.DescriptiveStatistics} that
+ * is safe to use in a multithreaded environment.  Multiple threads can safely
+ * operate on a single instance without causing runtime exceptions due to race
+ * conditions.  In effect, this implementation makes modification and access
+ * methods atomic operations for a single instance.  That is to say, as one
+ * thread is computing a statistic from the instance, no other thread can modify
+ * the instance nor compute another statistic.
+ *
+ * @since 1.2
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class SynchronizedDescriptiveStatistics extends DescriptiveStatistics {
+
+    /** Serialization UID */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Construct an instance with infinite window
+     */
+    public SynchronizedDescriptiveStatistics() {
+        this(INFINITE_WINDOW);
+    }
+
+    /**
+     * Construct an instance with finite window
+     * @param window the finite window size.
+     */
+    public SynchronizedDescriptiveStatistics(int window) {
+        super(window);
+    }
+
+    /**
+     * A copy constructor. Creates a deep-copy of the {@code original}.
+     *
+     * @param original the {@code SynchronizedDescriptiveStatistics} instance to copy
+     */
+    public SynchronizedDescriptiveStatistics(SynchronizedDescriptiveStatistics original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addValue(double v) {
+        super.addValue(v);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double apply(UnivariateStatistic stat) {
+        return super.apply(stat);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void clear() {
+        super.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getElement(int index) {
+        return super.getElement(index);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized long getN() {
+        return super.getN();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getStandardDeviation() {
+        return super.getStandardDeviation();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getValues() {
+        return super.getValues();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized int getWindowSize() {
+        return super.getWindowSize();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setWindowSize(int windowSize) {
+        super.setWindowSize(windowSize);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized String toString() {
+        return super.toString();
+    }
+
+    /**
+     * Returns a copy of this SynchronizedDescriptiveStatistics instance with the
+     * same internal state.
+     *
+     * @return a copy of this
+     */
+    @Override
+    public synchronized SynchronizedDescriptiveStatistics copy() {
+        SynchronizedDescriptiveStatistics result =
+            new SynchronizedDescriptiveStatistics();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     * <p>Acquires synchronization lock on source, then dest before copying.</p>
+     *
+     * @param source SynchronizedDescriptiveStatistics to copy
+     * @param dest SynchronizedDescriptiveStatistics to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(SynchronizedDescriptiveStatistics source,
+            SynchronizedDescriptiveStatistics dest) {
+        synchronized (source) {
+            synchronized (dest) {
+                DescriptiveStatistics.copy(source, dest);
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java
new file mode 100644
index 0000000..190e092
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.java
@@ -0,0 +1,299 @@
+/*
+ * 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.stat.descriptive;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.linear.RealMatrix;
+
+/**
+ * Implementation of
+ * {@link org.apache.commons.math.stat.descriptive.MultivariateSummaryStatistics} that
+ * is safe to use in a multithreaded environment.  Multiple threads can safely
+ * operate on a single instance without causing runtime exceptions due to race
+ * conditions.  In effect, this implementation makes modification and access
+ * methods atomic operations for a single instance.  That is to say, as one
+ * thread is computing a statistic from the instance, no other thread can modify
+ * the instance nor compute another statistic.
+ * @since 1.2
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class SynchronizedMultivariateSummaryStatistics
+  extends MultivariateSummaryStatistics {
+
+    /** Serialization UID */
+    private static final long serialVersionUID = 7099834153347155363L;
+
+    /**
+     * Construct a SynchronizedMultivariateSummaryStatistics instance
+     * @param k dimension of the data
+     * @param isCovarianceBiasCorrected if true, the unbiased sample
+     * covariance is computed, otherwise the biased population covariance
+     * is computed
+     */
+    public SynchronizedMultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) {
+        super(k, isCovarianceBiasCorrected);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addValue(double[] value)
+      throws DimensionMismatchException {
+      super.addValue(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized int getDimension() {
+        return super.getDimension();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized long getN() {
+        return super.getN();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getSum() {
+        return super.getSum();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getSumSq() {
+        return super.getSumSq();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getSumLog() {
+        return super.getSumLog();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getMean() {
+        return super.getMean();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getStandardDeviation() {
+        return super.getStandardDeviation();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized RealMatrix getCovariance() {
+        return super.getCovariance();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getMax() {
+        return super.getMax();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getMin() {
+        return super.getMin();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double[] getGeometricMean() {
+        return super.getGeometricMean();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized String toString() {
+        return super.toString();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void clear() {
+        super.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized boolean equals(Object object) {
+        return super.equals(object);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getSumImpl() {
+        return super.getSumImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setSumImpl(StorelessUnivariateStatistic[] sumImpl)
+      throws DimensionMismatchException {
+        super.setSumImpl(sumImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getSumsqImpl() {
+        return super.getSumsqImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl)
+      throws DimensionMismatchException {
+        super.setSumsqImpl(sumsqImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getMinImpl() {
+        return super.getMinImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setMinImpl(StorelessUnivariateStatistic[] minImpl)
+      throws DimensionMismatchException {
+        super.setMinImpl(minImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getMaxImpl() {
+        return super.getMaxImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setMaxImpl(StorelessUnivariateStatistic[] maxImpl)
+      throws DimensionMismatchException {
+        super.setMaxImpl(maxImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getSumLogImpl() {
+        return super.getSumLogImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl)
+      throws DimensionMismatchException {
+        super.setSumLogImpl(sumLogImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getGeoMeanImpl() {
+        return super.getGeoMeanImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl)
+      throws DimensionMismatchException {
+        super.setGeoMeanImpl(geoMeanImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic[] getMeanImpl() {
+        return super.getMeanImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setMeanImpl(StorelessUnivariateStatistic[] meanImpl)
+      throws DimensionMismatchException {
+        super.setMeanImpl(meanImpl);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatistics.java b/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatistics.java
new file mode 100644
index 0000000..07bfbf2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatistics.java
@@ -0,0 +1,333 @@
+/*
+ * 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.stat.descriptive;
+
+/**
+ * Implementation of
+ * {@link org.apache.commons.math.stat.descriptive.SummaryStatistics} that
+ * is safe to use in a multithreaded environment.  Multiple threads can safely
+ * operate on a single instance without causing runtime exceptions due to race
+ * conditions.  In effect, this implementation makes modification and access
+ * methods atomic operations for a single instance.  That is to say, as one
+ * thread is computing a statistic from the instance, no other thread can modify
+ * the instance nor compute another statistic.
+ *
+ * @since 1.2
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class SynchronizedSummaryStatistics extends SummaryStatistics {
+
+    /** Serialization UID */
+    private static final long serialVersionUID = 1909861009042253704L;
+
+    /**
+     * Construct a SynchronizedSummaryStatistics instance
+     */
+    public SynchronizedSummaryStatistics() {
+        super();
+    }
+
+    /**
+     * A copy constructor. Creates a deep-copy of the {@code original}.
+     *
+     * @param original the {@code SynchronizedSummaryStatistics} instance to copy
+     */
+    public SynchronizedSummaryStatistics(SynchronizedSummaryStatistics original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StatisticalSummary getSummary() {
+        return super.getSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void addValue(double value) {
+        super.addValue(value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized long getN() {
+        return super.getN();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getSum() {
+        return super.getSum();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getSumsq() {
+        return super.getSumsq();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getMean() {
+        return super.getMean();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getStandardDeviation() {
+        return super.getStandardDeviation();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getVariance() {
+        return super.getVariance();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getMax() {
+        return super.getMax();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getMin() {
+        return super.getMin();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized double getGeometricMean() {
+        return super.getGeometricMean();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized String toString() {
+        return super.toString();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void clear() {
+        super.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized boolean equals(Object object) {
+        return super.equals(object);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized int hashCode() {
+        return super.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getSumImpl() {
+        return super.getSumImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setSumImpl(StorelessUnivariateStatistic sumImpl) {
+        super.setSumImpl(sumImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getSumsqImpl() {
+        return super.getSumsqImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) {
+        super.setSumsqImpl(sumsqImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getMinImpl() {
+        return super.getMinImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setMinImpl(StorelessUnivariateStatistic minImpl) {
+        super.setMinImpl(minImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getMaxImpl() {
+        return super.getMaxImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setMaxImpl(StorelessUnivariateStatistic maxImpl) {
+        super.setMaxImpl(maxImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getSumLogImpl() {
+        return super.getSumLogImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) {
+        super.setSumLogImpl(sumLogImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getGeoMeanImpl() {
+        return super.getGeoMeanImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) {
+        super.setGeoMeanImpl(geoMeanImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getMeanImpl() {
+        return super.getMeanImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setMeanImpl(StorelessUnivariateStatistic meanImpl) {
+        super.setMeanImpl(meanImpl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized StorelessUnivariateStatistic getVarianceImpl() {
+        return super.getVarianceImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public synchronized void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) {
+        super.setVarianceImpl(varianceImpl);
+    }
+
+    /**
+     * Returns a copy of this SynchronizedSummaryStatistics instance with the
+     * same internal state.
+     *
+     * @return a copy of this
+     */
+    @Override
+    public synchronized SynchronizedSummaryStatistics copy() {
+        SynchronizedSummaryStatistics result =
+            new SynchronizedSummaryStatistics();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     * <p>Acquires synchronization lock on source, then dest before copying.</p>
+     *
+     * @param source SynchronizedSummaryStatistics to copy
+     * @param dest SynchronizedSummaryStatistics to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(SynchronizedSummaryStatistics source,
+            SynchronizedSummaryStatistics dest) {
+        synchronized (source) {
+            synchronized (dest) {
+                SummaryStatistics.copy(source, dest);
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/UnivariateStatistic.java b/src/main/java/org/apache/commons/math/stat/descriptive/UnivariateStatistic.java
new file mode 100644
index 0000000..92c9ee2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/UnivariateStatistic.java
@@ -0,0 +1,53 @@
+/*
+ * 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.stat.descriptive;
+
+
+/**
+ * Base interface implemented by all statistics.
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface UnivariateStatistic {
+
+    /**
+     * Returns the result of evaluating the statistic over the input array.
+     *
+     * @param values input array
+     * @return the value of the statistic applied to the input array
+     */
+    double evaluate(double[] values);
+
+    /**
+     * Returns the result of evaluating the statistic over the specified entries
+     * in the input array.
+     *
+     * @param values the input array
+     * @param begin the index of the first element to include
+     * @param length the number of elements to include
+     * @return the value of the statistic applied to the included array entries
+     */
+    double evaluate(double[] values, int begin, int length);
+
+    /**
+     * Returns a copy of the statistic with the same internal state.
+     *
+     * @return a copy of the statistic
+     */
+    UnivariateStatistic copy();
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java b/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
new file mode 100644
index 0000000..54a0216
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/WeightedEvaluation.java
@@ -0,0 +1,49 @@
+/*
+ * 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.stat.descriptive;
+
+/**
+ * Weighted evaluation for statistics.
+ *
+ * @since 2.1
+ * @version $Revision: 894474 $ $Date: 2009-12-29 21:02:37 +0100 (mar. 29 déc. 2009) $
+ */
+public interface WeightedEvaluation {
+
+    /**
+     * Returns the result of evaluating the statistic over the input array,
+     * using the supplied weights.
+     *
+     * @param values input array
+     * @param weights array of weights
+     * @return the value of the weighted statistic applied to the input array
+     */
+    double evaluate(double[] values, double[] weights);
+
+    /**
+     * Returns the result of evaluating the statistic over the specified entries
+     * in the input array, using corresponding entries in the supplied weights array.
+     *
+     * @param values the input array
+     * @param weights array of weights
+     * @param begin the index of the first element to include
+     * @param length the number of elements to include
+     * @return the value of the weighted statistic applied to the included array entries
+     */
+    double evaluate(double[] values, double[] weights, int begin, int length);
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/FirstMoment.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/FirstMoment.java
new file mode 100644
index 0000000..4103e50
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/FirstMoment.java
@@ -0,0 +1,160 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+
+/**
+ * Computes the first moment (arithmetic mean).  Uses the definitional formula:
+ * <p>
+ * mean = sum(x_i) / n </p>
+ * <p>
+ * where <code>n</code> is the number of observations. </p>
+ * <p>
+ * To limit numeric errors, the value of the statistic is computed using the
+ * following recursive updating algorithm: </p>
+ * <p>
+ * <ol>
+ * <li>Initialize <code>m = </code> the first value</li>
+ * <li>For each additional value, update using <br>
+ *   <code>m = m + (new value - m) / (number of observations)</code></li>
+ * </ol></p>
+ * <p>
+ *  Returns <code>Double.NaN</code> if the dataset is empty.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class FirstMoment extends AbstractStorelessUnivariateStatistic
+    implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 6112755307178490473L;
+
+
+    /** Count of values that have been added */
+    protected long n;
+
+    /** First moment of values that have been added */
+    protected double m1;
+
+    /**
+     * Deviation of most recently added value from previous first moment.
+     * Retained to prevent repeated computation in higher order moments.
+     */
+    protected double dev;
+
+    /**
+     * Deviation of most recently added value from previous first moment,
+     * normalized by previous sample size.  Retained to prevent repeated
+     * computation in higher order moments
+     */
+    protected double nDev;
+
+    /**
+     * Create a FirstMoment instance
+     */
+    public FirstMoment() {
+        n = 0;
+        m1 = Double.NaN;
+        dev = Double.NaN;
+        nDev = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code FirstMoment} identical
+     * to the {@code original}
+     *
+     * @param original the {@code FirstMoment} instance to copy
+     */
+     public FirstMoment(FirstMoment original) {
+         super();
+         copy(original, this);
+     }
+
+    /**
+     * {@inheritDoc}
+     */
+     @Override
+    public void increment(final double d) {
+        if (n == 0) {
+            m1 = 0.0;
+        }
+        n++;
+        double n0 = n;
+        dev = d - m1;
+        nDev = dev / n0;
+        m1 += nDev;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        m1 = Double.NaN;
+        n = 0;
+        dev = Double.NaN;
+        nDev = Double.NaN;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return m1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FirstMoment copy() {
+        FirstMoment result = new FirstMoment();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source FirstMoment to copy
+     * @param dest FirstMoment to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(FirstMoment source, FirstMoment dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.m1 = source.m1;
+        dest.dev = source.dev;
+        dest.nDev = source.nDev;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/FourthMoment.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/FourthMoment.java
new file mode 100644
index 0000000..6e7d8d2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/FourthMoment.java
@@ -0,0 +1,142 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+/**
+ * Computes a statistic related to the Fourth Central Moment.  Specifically,
+ * what is computed is the sum of
+ * <p>
+ * (x_i - xbar) ^ 4, </p>
+ * <p>
+ * where the x_i are the
+ * sample observations and xbar is the sample mean. </p>
+ * <p>
+ * The following recursive updating formula is used: </p>
+ * <p>
+ * Let <ul>
+ * <li> dev = (current obs - previous mean) </li>
+ * <li> m2 = previous value of {@link SecondMoment} </li>
+ * <li> m2 = previous value of {@link ThirdMoment} </li>
+ * <li> n = number of observations (including current obs) </li>
+ * </ul>
+ * Then </p>
+ * <p>
+ * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 + <br>
+ * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3 </p>
+ * <p>
+ * Returns <code>Double.NaN</code> if no data values have been added and
+ * returns <code>0</code> if there is just one value in the data set. </p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally. </p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class FourthMoment extends ThirdMoment implements Serializable{
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4763990447117157611L;
+
+    /** fourth moment of values that have been added */
+    protected double m4;
+
+    /**
+     * Create a FourthMoment instance
+     */
+    public FourthMoment() {
+        super();
+        m4 = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code FourthMoment} identical
+     * to the {@code original}
+     *
+     * @param original the {@code FourthMoment} instance to copy
+     */
+     public FourthMoment(FourthMoment original) {
+         super();
+         copy(original, this);
+     }
+
+    /**
+     * {@inheritDoc}
+     */
+     @Override
+    public void increment(final double d) {
+        if (n < 1) {
+            m4 = 0.0;
+            m3 = 0.0;
+            m2 = 0.0;
+            m1 = 0.0;
+        }
+
+        double prevM3 = m3;
+        double prevM2 = m2;
+
+        super.increment(d);
+
+        double n0 = n;
+
+        m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 +
+            ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return m4;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        super.clear();
+        m4 = Double.NaN;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FourthMoment copy() {
+        FourthMoment result = new FourthMoment();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source FourthMoment to copy
+     * @param dest FourthMoment to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(FourthMoment source, FourthMoment dest) {
+        ThirdMoment.copy(source, dest);
+        dest.m4 = source.m4;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/GeometricMean.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/GeometricMean.java
new file mode 100644
index 0000000..a24a3c8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/GeometricMean.java
@@ -0,0 +1,205 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Returns the <a href="http://www.xycoon.com/geometric_mean.htm">
+ * geometric mean </a> of the available values.
+ * <p>
+ * Uses a {@link SumOfLogs} instance to compute sum of logs and returns
+ * <code> exp( 1/n  (sum of logs) ).</code>  Therefore, </p>
+ * <ul>
+ * <li>If any of values are < 0, the result is <code>NaN.</code></li>
+ * <li>If all values are non-negative and less than
+ * <code>Double.POSITIVE_INFINITY</code>,  but at least one value is 0, the
+ * result is <code>0.</code></li>
+ * <li>If both <code>Double.POSITIVE_INFINITY</code> and
+ * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is
+ * <code>NaN.</code></li>
+ * </ul> </p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class GeometricMean extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -8178734905303459453L;
+
+    /** Wrapped SumOfLogs instance */
+    private StorelessUnivariateStatistic sumOfLogs;
+
+    /**
+     * Create a GeometricMean instance
+     */
+    public GeometricMean() {
+        sumOfLogs = new SumOfLogs();
+    }
+
+    /**
+     * Copy constructor, creates a new {@code GeometricMean} identical
+     * to the {@code original}
+     *
+     * @param original the {@code GeometricMean} instance to copy
+     */
+    public GeometricMean(GeometricMean original) {
+        super();
+        copy(original, this);
+    }
+
+    /**
+     * Create a GeometricMean instance using the given SumOfLogs instance
+     * @param sumOfLogs sum of logs instance to use for computation
+     */
+    public GeometricMean(SumOfLogs sumOfLogs) {
+        this.sumOfLogs = sumOfLogs;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GeometricMean copy() {
+        GeometricMean result = new GeometricMean();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        sumOfLogs.increment(d);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        if (sumOfLogs.getN() > 0) {
+            return FastMath.exp(sumOfLogs.getResult() / sumOfLogs.getN());
+        } else {
+            return Double.NaN;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        sumOfLogs.clear();
+    }
+
+    /**
+     * Returns the geometric mean of the entries in the specified portion
+     * of the input array.
+     * <p>
+     * See {@link GeometricMean} for details on the computing algorithm.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values input array containing the values
+     * @param begin first array element to include
+     * @param length the number of elements to include
+     * @return the geometric mean or Double.NaN if length = 0 or
+     * any of the values are &lt;= 0.
+     * @throws IllegalArgumentException if the input array is null or the array
+     * index parameters are not valid
+     */
+    @Override
+    public double evaluate(
+        final double[] values, final int begin, final int length) {
+        return FastMath.exp(
+            sumOfLogs.evaluate(values, begin, length) / length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return sumOfLogs.getN();
+    }
+
+    /**
+     * <p>Sets the implementation for the sum of logs.</p>
+     * <p>This method must be activated before any data has been added - i.e.,
+     * before {@link #increment(double) increment} has been used to add data;
+     * otherwise an IllegalStateException will be thrown.</p>
+     *
+     * @param sumLogImpl the StorelessUnivariateStatistic instance to use
+     * for computing the log sum
+     * @throws IllegalStateException if data has already been added
+     *  (i.e if n > 0)
+     */
+    public void setSumLogImpl(
+            StorelessUnivariateStatistic sumLogImpl) {
+        checkEmpty();
+        this.sumOfLogs = sumLogImpl;
+    }
+
+    /**
+     * Returns the currently configured sum of logs implementation
+     *
+     * @return the StorelessUnivariateStatistic implementing the log sum
+     */
+    public StorelessUnivariateStatistic getSumLogImpl() {
+        return sumOfLogs;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source GeometricMean to copy
+     * @param dest GeometricMean to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(GeometricMean source, GeometricMean dest) {
+        dest.setData(source.getDataRef());
+        dest.sumOfLogs = source.sumOfLogs.copy();
+    }
+
+
+    /**
+     * Throws IllegalStateException if n > 0.
+     */
+    private void checkEmpty() {
+        if (getN() > 0) {
+            throw MathRuntimeException.createIllegalStateException(
+                    LocalizedFormats.VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC,
+                    getN());
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/Kurtosis.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Kurtosis.java
new file mode 100644
index 0000000..f648051
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Kurtosis.java
@@ -0,0 +1,222 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * Computes the Kurtosis of the available values.
+ * <p>
+ * We use the following (unbiased) formula to define kurtosis:</p>
+ *  <p>
+ *  kurtosis = { [n(n+1) / (n -1)(n - 2)(n-3)] sum[(x_i - mean)^4] / std^4 } - [3(n-1)^2 / (n-2)(n-3)]
+ *  </p><p>
+ *  where n is the number of values, mean is the {@link Mean} and std is the
+ * {@link StandardDeviation}</p>
+ * <p>
+ *  Note that this statistic is undefined for n < 4.  <code>Double.Nan</code>
+ *  is returned when there is not sufficient data to compute the statistic.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Kurtosis extends AbstractStorelessUnivariateStatistic  implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 2784465764798260919L;
+
+    /**Fourth Moment on which this statistic is based */
+    protected FourthMoment moment;
+
+    /**
+     * Determines whether or not this statistic can be incremented or cleared.
+     * <p>
+     * Statistics based on (constructed from) external moments cannot
+     * be incremented or cleared.</p>
+    */
+    protected boolean incMoment;
+
+    /**
+     * Construct a Kurtosis
+     */
+    public Kurtosis() {
+        incMoment = true;
+        moment = new FourthMoment();
+    }
+
+    /**
+     * Construct a Kurtosis from an external moment
+     *
+     * @param m4 external Moment
+     */
+    public Kurtosis(final FourthMoment m4) {
+        incMoment = false;
+        this.moment = m4;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Kurtosis} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Kurtosis} instance to copy
+     */
+    public Kurtosis(Kurtosis original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (incMoment) {
+            moment.increment(d);
+        }  else  {
+            throw MathRuntimeException.createIllegalStateException(
+                    LocalizedFormats.CANNOT_INCREMENT_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        double kurtosis = Double.NaN;
+        if (moment.getN() > 3) {
+            double variance = moment.m2 / (moment.n - 1);
+                if (moment.n <= 3 || variance < 10E-20) {
+                    kurtosis = 0.0;
+                } else {
+                    double n = moment.n;
+                    kurtosis =
+                        (n * (n + 1) * moment.m4 -
+                                3 * moment.m2 * moment.m2 * (n - 1)) /
+                                ((n - 1) * (n -2) * (n -3) * variance * variance);
+                }
+        }
+        return kurtosis;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        if (incMoment) {
+            moment.clear();
+        } else  {
+            throw MathRuntimeException.createIllegalStateException(
+                    LocalizedFormats.CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return moment.getN();
+    }
+
+    /* UnvariateStatistic Approach  */
+
+    /**
+     * Returns the kurtosis of the entries in the specified portion of the
+     * input array.
+     * <p>
+     * See {@link Kurtosis} for details on the computing algorithm.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the kurtosis of the values or Double.NaN if length is less than
+     * 4
+     * @throws IllegalArgumentException if the input array is null or the array
+     * index parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values,final int begin, final int length) {
+        // Initialize the kurtosis
+        double kurt = Double.NaN;
+
+        if (test(values, begin, length) && length > 3) {
+
+            // Compute the mean and standard deviation
+            Variance variance = new Variance();
+            variance.incrementAll(values, begin, length);
+            double mean = variance.moment.m1;
+            double stdDev = FastMath.sqrt(variance.getResult());
+
+            // Sum the ^4 of the distance from the mean divided by the
+            // standard deviation
+            double accum3 = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                accum3 += FastMath.pow(values[i] - mean, 4.0);
+            }
+            accum3 /= FastMath.pow(stdDev, 4.0d);
+
+            // Get N
+            double n0 = length;
+
+            double coefficientOne =
+                (n0 * (n0 + 1)) / ((n0 - 1) * (n0 - 2) * (n0 - 3));
+            double termTwo =
+                (3 * FastMath.pow(n0 - 1, 2.0)) / ((n0 - 2) * (n0 - 3));
+
+            // Calculate kurtosis
+            kurt = (coefficientOne * accum3) - termTwo;
+        }
+        return kurt;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Kurtosis copy() {
+        Kurtosis result = new Kurtosis();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Kurtosis to copy
+     * @param dest Kurtosis to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Kurtosis source, Kurtosis dest) {
+        dest.setData(source.getDataRef());
+        dest.moment = source.moment.copy();
+        dest.incMoment = source.incMoment;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java
new file mode 100644
index 0000000..c5aa9da
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Mean.java
@@ -0,0 +1,272 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+
+/**
+ * <p>Computes the arithmetic mean of a set of values. Uses the definitional
+ * formula:</p>
+ * <p>
+ * mean = sum(x_i) / n
+ * </p>
+ * <p>where <code>n</code> is the number of observations.
+ * </p>
+ * <p>When {@link #increment(double)} is used to add data incrementally from a
+ * stream of (unstored) values, the value of the statistic that
+ * {@link #getResult()} returns is computed using the following recursive
+ * updating algorithm: </p>
+ * <ol>
+ * <li>Initialize <code>m = </code> the first value</li>
+ * <li>For each additional value, update using <br>
+ *   <code>m = m + (new value - m) / (number of observations)</code></li>
+ * </ol>
+ * <p> If {@link #evaluate(double[])} is used to compute the mean of an array
+ * of stored values, a two-pass, corrected algorithm is used, starting with
+ * the definitional formula computed using the array of stored values and then
+ * correcting this by adding the mean deviation of the data values from the
+ * arithmetic mean. See, e.g. "Comparison of Several Algorithms for Computing
+ * Sample Means and Variances," Robert F. Ling, Journal of the American
+ * Statistical Association, Vol. 69, No. 348 (Dec., 1974), pp. 859-866. </p>
+ * <p>
+ *  Returns <code>Double.NaN</code> if the dataset is empty.
+ * </p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Mean extends AbstractStorelessUnivariateStatistic
+    implements Serializable, WeightedEvaluation {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -1296043746617791564L;
+
+    /** First moment on which this statistic is based. */
+    protected FirstMoment moment;
+
+    /**
+     * Determines whether or not this statistic can be incremented or cleared.
+     * <p>
+     * Statistics based on (constructed from) external moments cannot
+     * be incremented or cleared.</p>
+     */
+    protected boolean incMoment;
+
+    /** Constructs a Mean. */
+    public Mean() {
+        incMoment = true;
+        moment = new FirstMoment();
+    }
+
+    /**
+     * Constructs a Mean with an External Moment.
+     *
+     * @param m1 the moment
+     */
+    public Mean(final FirstMoment m1) {
+        this.moment = m1;
+        incMoment = false;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Mean} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Mean} instance to copy
+     */
+    public Mean(Mean original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (incMoment) {
+            moment.increment(d);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        if (incMoment) {
+            moment.clear();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return moment.m1;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return moment.getN();
+    }
+
+    /**
+     * Returns the arithmetic mean of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link Mean} for details on the computing algorithm.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the mean of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values,final int begin, final int length) {
+        if (test(values, begin, length)) {
+            Sum sum = new Sum();
+            double sampleSize = length;
+
+            // Compute initial estimate using definitional formula
+            double xbar = sum.evaluate(values, begin, length) / sampleSize;
+
+            // Compute correction factor in second pass
+            double correction = 0;
+            for (int i = begin; i < begin + length; i++) {
+                correction += values[i] - xbar;
+            }
+            return xbar + (correction/sampleSize);
+        }
+        return Double.NaN;
+    }
+
+    /**
+     * Returns the weighted arithmetic mean of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if either array is null.</p>
+     * <p>
+     * See {@link Mean} for details on the computing algorithm. The two-pass algorithm
+     * described above is used here, with weights applied in computing both the original
+     * estimate and the correction factor.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     *     <li>the start and length arguments do not determine a valid array</li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the mean of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights,
+                           final int begin, final int length) {
+        if (test(values, weights, begin, length)) {
+            Sum sum = new Sum();
+
+            // Compute initial estimate using definitional formula
+            double sumw = sum.evaluate(weights,begin,length);
+            double xbarw = sum.evaluate(values, weights, begin, length) / sumw;
+
+            // Compute correction factor in second pass
+            double correction = 0;
+            for (int i = begin; i < begin + length; i++) {
+                correction += weights[i] * (values[i] - xbarw);
+            }
+            return xbarw + (correction/sumw);
+        }
+        return Double.NaN;
+    }
+
+    /**
+     * Returns the weighted arithmetic mean of the entries in the input array.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if either array is null.</p>
+     * <p>
+     * See {@link Mean} for details on the computing algorithm. The two-pass algorithm
+     * described above is used here, with weights applied in computing both the original
+     * estimate and the correction factor.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the mean of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Mean copy() {
+        Mean result = new Mean();
+        copy(this, result);
+        return result;
+    }
+
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Mean to copy
+     * @param dest Mean to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Mean source, Mean dest) {
+        dest.setData(source.getDataRef());
+        dest.incMoment = source.incMoment;
+        dest.moment = source.moment.copy();
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/SecondMoment.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/SecondMoment.java
new file mode 100644
index 0000000..ae8ef8e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/SecondMoment.java
@@ -0,0 +1,124 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+/**
+ * Computes a statistic related to the Second Central Moment.  Specifically,
+ * what is computed is the sum of squared deviations from the sample mean.
+ * <p>
+ * The following recursive updating formula is used:</p>
+ * <p>
+ * Let <ul>
+ * <li> dev = (current obs - previous mean) </li>
+ * <li> n = number of observations (including current obs) </li>
+ * </ul>
+ * Then</p>
+ * <p>
+ * new value = old value + dev^2 * (n -1) / n.</p>
+ * <p>
+ * Returns <code>Double.NaN</code> if no data values have been added and
+ * returns <code>0</code> if there is just one value in the data set.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class SecondMoment extends FirstMoment implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 3942403127395076445L;
+
+    /** second moment of values that have been added */
+    protected double m2;
+
+    /**
+     * Create a SecondMoment instance
+     */
+    public SecondMoment() {
+        super();
+        m2 = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code SecondMoment} identical
+     * to the {@code original}
+     *
+     * @param original the {@code SecondMoment} instance to copy
+     */
+    public SecondMoment(SecondMoment original) {
+        super(original);
+        this.m2 = original.m2;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (n < 1) {
+            m1 = m2 = 0.0;
+        }
+        super.increment(d);
+        m2 += ((double) n - 1) * dev * nDev;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        super.clear();
+        m2 = Double.NaN;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return m2;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SecondMoment copy() {
+        SecondMoment result = new SecondMoment();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source SecondMoment to copy
+     * @param dest SecondMoment to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(SecondMoment source, SecondMoment dest) {
+        FirstMoment.copy(source, dest);
+        dest.m2 = source.m2;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/SemiVariance.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/SemiVariance.java
new file mode 100644
index 0000000..04aa456
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/SemiVariance.java
@@ -0,0 +1,379 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic;
+
+/**
+ * <p>Computes the semivariance of a set of values with respect to a given cutoff value.
+ * We define the <i>downside semivariance</i> of a set of values <code>x</code>
+ * against the <i>cutoff value</i> <code>cutoff</code> to be <br/>
+ * <code>&Sigma; (x[i] - target)<sup>2</sup> / df</code> <br/>
+ * where the sum is taken over all <code>i</code> such that <code>x[i] < cutoff</code>
+ * and <code>df</code> is the length of <code>x</code> (non-bias-corrected) or
+ * one less than this number (bias corrected).  The <i>upside semivariance</i>
+ * is defined similarly, with the sum taken over values of <code>x</code> that
+ * exceed the cutoff value.</p>
+ *
+ * <p>The cutoff value defaults to the mean, bias correction defaults to <code>true</code>
+ * and the "variance direction" (upside or downside) defaults to downside.  The variance direction
+ * and bias correction may be set using property setters or their values can provided as
+ * parameters to {@link #evaluate(double[], double, Direction, boolean, int, int)}.</p>
+ *
+ * <p>If the input array is null, <code>evaluate</code> methods throw
+ * <code>IllegalArgumentException.</code>  If the array has length 1, <code>0</code>
+ * is returned, regardless of the value of the <code>cutoff.</code>
+ *
+ * <p><strong>Note that this class is not intended to be threadsafe.</strong> If
+ * multiple threads access an instance of this class concurrently, and one or
+ * more of these threads invoke property setters, external synchronization must
+ * be provided to ensure correct results.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ * @since 2.1
+ */
+
+public class SemiVariance extends AbstractUnivariateStatistic implements Serializable {
+
+    /**
+     * The UPSIDE Direction is used to specify that the observations above the
+     * cutoff point will be used to calculate SemiVariance.
+     */
+    public static final Direction UPSIDE_VARIANCE = Direction.UPSIDE;
+
+    /**
+     * The DOWNSIDE Direction is used to specify that the observations below
+     * the cutoff point will be used to calculate SemiVariance
+     */
+    public static final Direction DOWNSIDE_VARIANCE = Direction.DOWNSIDE;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -2653430366886024994L;
+
+    /**
+     * Determines whether or not bias correction is applied when computing the
+     * value of the statisic.  True means that bias is corrected.
+     */
+    private boolean biasCorrected = true;
+
+    /**
+     * Determines whether to calculate downside or upside SemiVariance.
+     */
+    private Direction varianceDirection = Direction.DOWNSIDE;
+
+    /**
+     * Constructs a SemiVariance with default (true) <code>biasCorrected</code>
+     * property and default (Downside) <code>varianceDirection</code> property.
+     */
+    public SemiVariance() {
+    }
+
+    /**
+     * Constructs a SemiVariance with the specified <code>biasCorrected</code>
+     * property and default (Downside) <code>varianceDirection</code> property.
+     *
+     * @param biasCorrected  setting for bias correction - true means
+     * bias will be corrected and is equivalent to using the argumentless
+     * constructor
+     */
+    public SemiVariance(final boolean biasCorrected) {
+        this.biasCorrected = biasCorrected;
+    }
+
+
+    /**
+     * Constructs a SemiVariance with the specified <code>Direction</code> property
+     * and default (true) <code>biasCorrected</code> property
+     *
+     * @param direction  setting for the direction of the SemiVariance
+     * to calculate
+     */
+    public SemiVariance(final Direction direction) {
+        this.varianceDirection = direction;
+    }
+
+
+    /**
+     * Constructs a SemiVariance with the specified <code>isBiasCorrected</code>
+     * property and the specified <code>Direction</code> property.
+     *
+     * @param corrected  setting for bias correction - true means
+     * bias will be corrected and is equivalent to using the argumentless
+     * constructor
+     *
+     * @param direction  setting for the direction of the SemiVariance
+     * to calculate
+     */
+    public SemiVariance(final boolean corrected, final Direction direction) {
+        this.biasCorrected = corrected;
+        this.varianceDirection = direction;
+    }
+
+
+    /**
+     * Copy constructor, creates a new {@code SemiVariance} identical
+     * to the {@code original}
+     *
+     * @param original the {@code SemiVariance} instance to copy
+     */
+    public SemiVariance(final SemiVariance original) {
+        copy(original, this);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SemiVariance copy() {
+        SemiVariance result = new SemiVariance();
+        copy(this, result);
+        return result;
+    }
+
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source SemiVariance to copy
+     * @param dest SemiVariance to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(final SemiVariance source, SemiVariance dest) {
+        dest.setData(source.getDataRef());
+        dest.biasCorrected = source.biasCorrected;
+        dest.varianceDirection = source.varianceDirection;
+    }
+
+
+    /**
+     * This method calculates {@link SemiVariance} for the entire array against the mean, using
+     * instance properties varianceDirection and biasCorrection.
+     *
+     * @param values the input array
+     * @return the SemiVariance
+     * @throws IllegalArgumentException if values is null
+     *
+     */
+    @Override
+    public double evaluate(final double[] values) {
+        if (values == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+         }
+        return evaluate(values, 0, values.length);
+    }
+
+
+    /**
+      * <p>Returns the {@link SemiVariance} of the designated values against the mean, using
+      * instance properties varianceDirection and biasCorrection.</p>
+      *
+      * <p>Returns <code>NaN</code> if the array is empty and throws
+      * <code>IllegalArgumentException</code> if the array is null.</p>
+      *
+      * @param values the input array
+      * @param start index of the first array element to include
+      * @param length the number of elements to include
+      * @return the SemiVariance
+      * @throws IllegalArgumentException if the parameters are not valid
+      *
+      */
+      @Override
+      public double evaluate(final double[] values, final int start, final int length) {
+        double m = (new Mean()).evaluate(values, start, length);
+        return evaluate(values, m, varianceDirection, biasCorrected, 0, values.length);
+      }
+
+
+      /**
+       * This method calculates {@link SemiVariance} for the entire array against the mean, using
+       * the current value of the biasCorrection instance property.
+       *
+       * @param values the input array
+       * @param direction the {@link Direction} of the semivariance
+       * @return the SemiVariance
+       * @throws IllegalArgumentException if values is null
+       *
+       */
+      public double evaluate(final double[] values, Direction direction) {
+          double m = (new Mean()).evaluate(values);
+          return evaluate (values, m, direction, biasCorrected, 0, values.length);
+      }
+
+      /**
+       * <p>Returns the {@link SemiVariance} of the designated values against the cutoff, using
+       * instance properties variancDirection and biasCorrection.</p>
+       *
+       * <p>Returns <code>NaN</code> if the array is empty and throws
+       * <code>IllegalArgumentException</code> if the array is null.</p>
+       *
+       * @param values the input array
+       * @param cutoff the reference point
+       * @return the SemiVariance
+       * @throws IllegalArgumentException if values is null
+       */
+      public double evaluate(final double[] values, final double cutoff) {
+          return evaluate(values, cutoff, varianceDirection, biasCorrected, 0, values.length);
+      }
+
+      /**
+       * <p>Returns the {@link SemiVariance} of the designated values against the cutoff in the
+       * given direction, using the current value of the biasCorrection instance property.</p>
+       *
+       * <p>Returns <code>NaN</code> if the array is empty and throws
+       * <code>IllegalArgumentException</code> if the array is null.</p>
+       *
+       * @param values the input array
+       * @param cutoff the reference point
+       * @param direction the {@link Direction} of the semivariance
+       * @return the SemiVariance
+       * @throws IllegalArgumentException if values is null
+       */
+      public double evaluate(final double[] values, final double cutoff, final Direction direction) {
+          return evaluate(values, cutoff, direction, biasCorrected, 0, values.length);
+      }
+
+
+     /**
+      * <p>Returns the {@link SemiVariance} of the designated values against the cutoff
+      * in the given direction with the provided bias correction.</p>
+      *
+      * <p>Returns <code>NaN</code> if the array is empty and throws
+      * <code>IllegalArgumentException</code> if the array is null.</p>
+      *
+      * @param values the input array
+      * @param cutoff the reference point
+      * @param direction the {@link Direction} of the semivariance
+      * @param corrected the BiasCorrection flag
+      * @param start index of the first array element to include
+      * @param length the number of elements to include
+      * @return the SemiVariance
+      * @throws IllegalArgumentException if the parameters are not valid
+      *
+      */
+    public double evaluate (final double[] values, final double cutoff, final Direction direction,
+            final boolean corrected, final int start, final int length) {
+
+        test(values, start, length);
+        if (values.length == 0) {
+            return Double.NaN;
+        } else {
+            if (values.length == 1) {
+                return 0.0;
+            } else {
+                final boolean booleanDirection = direction.getDirection();
+
+                double dev = 0.0;
+                double sumsq = 0.0;
+                for (int i = start; i < length; i++) {
+                    if ((values[i] > cutoff) == booleanDirection) {
+                       dev = values[i] - cutoff;
+                       sumsq += dev * dev;
+                    }
+                }
+
+                if (corrected) {
+                    return sumsq / (length - 1.0);
+                } else {
+                    return sumsq / length;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true iff biasCorrected property is set to true.
+     *
+     * @return the value of biasCorrected.
+     */
+    public boolean isBiasCorrected() {
+        return biasCorrected;
+    }
+
+    /**
+     * Sets the biasCorrected property.
+     *
+     * @param biasCorrected new biasCorrected property value
+     */
+    public void setBiasCorrected(boolean biasCorrected) {
+        this.biasCorrected = biasCorrected;
+    }
+
+    /**
+     * Returns the varianceDirection property.
+     *
+     * @return the varianceDirection
+     */
+    public Direction getVarianceDirection () {
+        return varianceDirection;
+    }
+
+    /**
+     * Sets the variance direction
+     *
+     * @param varianceDirection the direction of the semivariance
+     */
+    public void setVarianceDirection(Direction varianceDirection) {
+        this.varianceDirection = varianceDirection;
+    }
+
+    /**
+     * The direction of the semivariance - either upside or downside. The direction
+     * is represented by boolean, with true corresponding to UPSIDE semivariance.
+     */
+    public enum Direction {
+        /**
+         * The UPSIDE Direction is used to specify that the observations above the
+         * cutoff point will be used to calculate SemiVariance
+         */
+        UPSIDE (true),
+
+        /**
+         * The DOWNSIDE Direction is used to specify that the observations below
+         * the cutoff point will be used to calculate SemiVariance
+         */
+        DOWNSIDE (false);
+
+        /**
+         *   boolean value  UPSIDE <-> true
+         */
+        private boolean direction;
+
+        /**
+         * Create a Direction with the given value.
+         *
+         * @param b boolean value representing the Direction. True corresponds to UPSIDE.
+         */
+        Direction (boolean b) {
+            direction = b;
+        }
+
+        /**
+         * Returns the value of this Direction. True corresponds to UPSIDE.
+         *
+         * @return true if direction is UPSIDE; false otherwise
+         */
+        boolean getDirection () {
+            return direction;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/Skewness.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Skewness.java
new file mode 100644
index 0000000..d16f956
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Skewness.java
@@ -0,0 +1,213 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Computes the skewness of the available values.
+ * <p>
+ * We use the following (unbiased) formula to define skewness:</p>
+ * <p>
+ * skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3 </p>
+ * <p>
+ * where n is the number of values, mean is the {@link Mean} and std is the
+ * {@link StandardDeviation} </p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally. </p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Skewness extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 7101857578996691352L;
+
+    /** Third moment on which this statistic is based */
+    protected ThirdMoment moment = null;
+
+     /**
+     * Determines whether or not this statistic can be incremented or cleared.
+     * <p>
+     * Statistics based on (constructed from) external moments cannot
+     * be incremented or cleared.</p>
+    */
+    protected boolean incMoment;
+
+    /**
+     * Constructs a Skewness
+     */
+    public Skewness() {
+        incMoment = true;
+        moment = new ThirdMoment();
+    }
+
+    /**
+     * Constructs a Skewness with an external moment
+     * @param m3 external moment
+     */
+    public Skewness(final ThirdMoment m3) {
+        incMoment = false;
+        this.moment = m3;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Skewness} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Skewness} instance to copy
+     */
+    public Skewness(Skewness original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (incMoment) {
+            moment.increment(d);
+        }
+    }
+
+    /**
+     * Returns the value of the statistic based on the values that have been added.
+     * <p>
+     * See {@link Skewness} for the definition used in the computation.</p>
+     *
+     * @return the skewness of the available values.
+     */
+    @Override
+    public double getResult() {
+
+        if (moment.n < 3) {
+            return Double.NaN;
+        }
+        double variance = moment.m2 / (moment.n - 1);
+        if (variance < 10E-20) {
+            return 0.0d;
+        } else {
+            double n0 = moment.getN();
+            return  (n0 * moment.m3) /
+            ((n0 - 1) * (n0 -2) * FastMath.sqrt(variance) * variance);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return moment.getN();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        if (incMoment) {
+            moment.clear();
+        }
+    }
+
+    /**
+     * Returns the Skewness of the entries in the specifed portion of the
+     * input array.
+     * <p>
+     * See {@link Skewness} for the definition used in the computation.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin the index of the first array element to include
+     * @param length the number of elements to include
+     * @return the skewness of the values or Double.NaN if length is less than
+     * 3
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values,final int begin,
+            final int length) {
+
+        // Initialize the skewness
+        double skew = Double.NaN;
+
+        if (test(values, begin, length) && length > 2 ){
+            Mean mean = new Mean();
+            // Get the mean and the standard deviation
+            double m = mean.evaluate(values, begin, length);
+
+            // Calc the std, this is implemented here instead
+            // of using the standardDeviation method eliminate
+            // a duplicate pass to get the mean
+            double accum = 0.0;
+            double accum2 = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                final double d = values[i] - m;
+                accum  += d * d;
+                accum2 += d;
+            }
+            final double variance = (accum - (accum2 * accum2 / length)) / (length - 1);
+
+            double accum3 = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                final double d = values[i] - m;
+                accum3 += d * d * d;
+            }
+            accum3 /= variance * FastMath.sqrt(variance);
+
+            // Get N
+            double n0 = length;
+
+            // Calculate skewness
+            skew = (n0 / ((n0 - 1) * (n0 - 2))) * accum3;
+        }
+        return skew;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Skewness copy() {
+        Skewness result = new Skewness();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Skewness to copy
+     * @param dest Skewness to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Skewness source, Skewness dest) {
+        dest.setData(source.getDataRef());
+        dest.moment = new ThirdMoment(source.moment.copy());
+        dest.incMoment = source.incMoment;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviation.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviation.java
new file mode 100644
index 0000000..837ae3b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/StandardDeviation.java
@@ -0,0 +1,271 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Computes the sample standard deviation.  The standard deviation
+ * is the positive square root of the variance.  This implementation wraps a
+ * {@link Variance} instance.  The <code>isBiasCorrected</code> property of the
+ * wrapped Variance instance is exposed, so that this class can be used to
+ * compute both the "sample standard deviation" (the square root of the
+ * bias-corrected "sample variance") or the "population standard deviation"
+ * (the square root of the non-bias-corrected "population variance"). See
+ * {@link Variance} for more information.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class StandardDeviation extends AbstractStorelessUnivariateStatistic
+    implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 5728716329662425188L;
+
+    /** Wrapped Variance instance */
+    private Variance variance = null;
+
+    /**
+     * Constructs a StandardDeviation.  Sets the underlying {@link Variance}
+     * instance's <code>isBiasCorrected</code> property to true.
+     */
+    public StandardDeviation() {
+        variance = new Variance();
+    }
+
+    /**
+     * Constructs a StandardDeviation from an external second moment.
+     *
+     * @param m2 the external moment
+     */
+    public StandardDeviation(final SecondMoment m2) {
+        variance = new Variance(m2);
+    }
+
+    /**
+     * Copy constructor, creates a new {@code StandardDeviation} identical
+     * to the {@code original}
+     *
+     * @param original the {@code StandardDeviation} instance to copy
+     */
+    public StandardDeviation(StandardDeviation original) {
+        copy(original, this);
+    }
+
+    /**
+     * Contructs a StandardDeviation with the specified value for the
+     * <code>isBiasCorrected</code> property.  If this property is set to
+     * <code>true</code>, the {@link Variance} used in computing results will
+     * use the bias-corrected, or "sample" formula.  See {@link Variance} for
+     * details.
+     *
+     * @param isBiasCorrected  whether or not the variance computation will use
+     * the bias-corrected formula
+     */
+    public StandardDeviation(boolean isBiasCorrected) {
+        variance = new Variance(isBiasCorrected);
+    }
+
+    /**
+     * Contructs a StandardDeviation with the specified value for the
+     * <code>isBiasCorrected</code> property and the supplied external moment.
+     * If <code>isBiasCorrected</code> is set to <code>true</code>, the
+     * {@link Variance} used in computing results will use the bias-corrected,
+     * or "sample" formula.  See {@link Variance} for details.
+     *
+     * @param isBiasCorrected  whether or not the variance computation will use
+     * the bias-corrected formula
+      * @param m2 the external moment
+     */
+    public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) {
+        variance = new Variance(isBiasCorrected, m2);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        variance.increment(d);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return variance.getN();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return FastMath.sqrt(variance.getResult());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        variance.clear();
+    }
+
+    /**
+     * Returns the Standard Deviation of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @return the standard deviation of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null
+     */
+    @Override
+    public double evaluate(final double[] values)  {
+        return FastMath.sqrt(variance.evaluate(values));
+    }
+
+    /**
+     * Returns the Standard Deviation of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample. </p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the standard deviation of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length)  {
+       return FastMath.sqrt(variance.evaluate(values, begin, length));
+    }
+
+    /**
+     * Returns the Standard Deviation of the entries in the specified portion of
+     * the input array, using the precomputed mean value.  Returns
+     * <code>Double.NaN</code> if the designated subarray is empty.
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the arithmetic
+     * mean of the sample data, not a known population parameter.  This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the standard deviation of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    public double evaluate(final double[] values, final double mean,
+            final int begin, final int length)  {
+        return FastMath.sqrt(variance.evaluate(values, mean, begin, length));
+    }
+
+    /**
+     * Returns the Standard Deviation of the entries in the input array, using
+     * the precomputed mean value.  Returns
+     * <code>Double.NaN</code> if the designated subarray is empty.
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the arithmetic
+     * mean of the sample data, not a known population parameter.  This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @return the standard deviation of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null
+     */
+    public double evaluate(final double[] values, final double mean)  {
+        return FastMath.sqrt(variance.evaluate(values, mean));
+    }
+
+    /**
+     * @return Returns the isBiasCorrected.
+     */
+    public boolean isBiasCorrected() {
+        return variance.isBiasCorrected();
+    }
+
+    /**
+     * @param isBiasCorrected The isBiasCorrected to set.
+     */
+    public void setBiasCorrected(boolean isBiasCorrected) {
+        variance.setBiasCorrected(isBiasCorrected);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public StandardDeviation copy() {
+        StandardDeviation result = new StandardDeviation();
+        copy(this, result);
+        return result;
+    }
+
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source StandardDeviation to copy
+     * @param dest StandardDeviation to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(StandardDeviation source, StandardDeviation dest) {
+        dest.setData(source.getDataRef());
+        dest.variance = source.variance.copy();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/ThirdMoment.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/ThirdMoment.java
new file mode 100644
index 0000000..5c50989
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/ThirdMoment.java
@@ -0,0 +1,139 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+
+/**
+ * Computes a statistic related to the Third Central Moment.  Specifically,
+ * what is computed is the sum of cubed deviations from the sample mean.
+ * <p>
+ * The following recursive updating formula is used:</p>
+ * <p>
+ * Let <ul>
+ * <li> dev = (current obs - previous mean) </li>
+ * <li> m2 = previous value of {@link SecondMoment} </li>
+ * <li> n = number of observations (including current obs) </li>
+ * </ul>
+ * Then</p>
+ * <p>
+ * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)</p>
+ * <p>
+ * Returns <code>Double.NaN</code> if no data values have been added and
+ * returns <code>0</code> if there is just one value in the data set.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class ThirdMoment extends SecondMoment implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -7818711964045118679L;
+
+    /** third moment of values that have been added */
+    protected double m3;
+
+     /**
+     * Square of deviation of most recently added value from previous first
+     * moment, normalized by previous sample size.  Retained to prevent
+     * repeated computation in higher order moments.  nDevSq = nDev * nDev.
+     */
+    protected double nDevSq;
+
+    /**
+     * Create a FourthMoment instance
+     */
+    public ThirdMoment() {
+        super();
+        m3 = Double.NaN;
+        nDevSq = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code ThirdMoment} identical
+     * to the {@code original}
+     *
+     * @param original the {@code ThirdMoment} instance to copy
+     */
+    public ThirdMoment(ThirdMoment original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (n < 1) {
+            m3 = m2 = m1 = 0.0;
+        }
+
+        double prevM2 = m2;
+        super.increment(d);
+        nDevSq = nDev * nDev;
+        double n0 = n;
+        m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return m3;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        super.clear();
+        m3 = Double.NaN;
+        nDevSq = Double.NaN;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ThirdMoment copy() {
+        ThirdMoment result = new ThirdMoment();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source ThirdMoment to copy
+     * @param dest ThirdMoment to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(ThirdMoment source, ThirdMoment dest) {
+        SecondMoment.copy(source, dest);
+        dest.m3 = source.m3;
+        dest.nDevSq = source.nDevSq;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
new file mode 100644
index 0000000..6ce6835
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
@@ -0,0 +1,610 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.exception.NullArgumentException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+
+/**
+ * Computes the variance of the available values.  By default, the unbiased
+ * "sample variance" definitional formula is used:
+ * <p>
+ * variance = sum((x_i - mean)^2) / (n - 1) </p>
+ * <p>
+ * where mean is the {@link Mean} and <code>n</code> is the number
+ * of sample observations.</p>
+ * <p>
+ * The definitional formula does not have good numerical properties, so
+ * this implementation does not compute the statistic using the definitional
+ * formula. <ul>
+ * <li> The <code>getResult</code> method computes the variance using
+ * updating formulas based on West's algorithm, as described in
+ * <a href="http://doi.acm.org/10.1145/359146.359152"> Chan, T. F. and
+ * J. G. Lewis 1979, <i>Communications of the ACM</i>,
+ * vol. 22 no. 9, pp. 526-531.</a></li>
+ * <li> The <code>evaluate</code> methods leverage the fact that they have the
+ * full array of values in memory to execute a two-pass algorithm.
+ * Specifically, these methods use the "corrected two-pass algorithm" from
+ * Chan, Golub, Levesque, <i>Algorithms for Computing the Sample Variance</i>,
+ * American Statistician, vol. 37, no. 3 (1983) pp. 242-247.</li></ul>
+ * Note that adding values using <code>increment</code> or
+ * <code>incrementAll</code> and then executing <code>getResult</code> will
+ * sometimes give a different, less accurate, result than executing
+ * <code>evaluate</code> with the full array of values. The former approach
+ * should only be used when the full array of values is not available.</p>
+ * <p>
+ * The "population variance"  ( sum((x_i - mean)^2) / n ) can also
+ * be computed using this statistic.  The <code>isBiasCorrected</code>
+ * property determines whether the "population" or "sample" value is
+ * returned by the <code>evaluate</code> and <code>getResult</code> methods.
+ * To compute population variances, set this property to <code>false.</code>
+ * </p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -9111962718267217978L;
+
+    /** SecondMoment is used in incremental calculation of Variance*/
+    protected SecondMoment moment = null;
+
+    /**
+     * Boolean test to determine if this Variance should also increment
+     * the second moment, this evaluates to false when this Variance is
+     * constructed with an external SecondMoment as a parameter.
+     */
+    protected boolean incMoment = true;
+
+    /**
+     * Determines whether or not bias correction is applied when computing the
+     * value of the statisic.  True means that bias is corrected.  See
+     * {@link Variance} for details on the formula.
+     */
+    private boolean isBiasCorrected = true;
+
+    /**
+     * Constructs a Variance with default (true) <code>isBiasCorrected</code>
+     * property.
+     */
+    public Variance() {
+        moment = new SecondMoment();
+    }
+
+    /**
+     * Constructs a Variance based on an external second moment.
+     *
+     * @param m2 the SecondMoment (Third or Fourth moments work
+     * here as well.)
+     */
+    public Variance(final SecondMoment m2) {
+        incMoment = false;
+        this.moment = m2;
+    }
+
+    /**
+     * Constructs a Variance with the specified <code>isBiasCorrected</code>
+     * property
+     *
+     * @param isBiasCorrected  setting for bias correction - true means
+     * bias will be corrected and is equivalent to using the argumentless
+     * constructor
+     */
+    public Variance(boolean isBiasCorrected) {
+        moment = new SecondMoment();
+        this.isBiasCorrected = isBiasCorrected;
+    }
+
+    /**
+     * Constructs a Variance with the specified <code>isBiasCorrected</code>
+     * property and the supplied external second moment.
+     *
+     * @param isBiasCorrected  setting for bias correction - true means
+     * bias will be corrected
+     * @param m2 the SecondMoment (Third or Fourth moments work
+     * here as well.)
+     */
+    public Variance(boolean isBiasCorrected, SecondMoment m2) {
+        incMoment = false;
+        this.moment = m2;
+        this.isBiasCorrected = isBiasCorrected;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Variance} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Variance} instance to copy
+     */
+    public Variance(Variance original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>If all values are available, it is more accurate to use
+     * {@link #evaluate(double[])} rather than adding values one at a time
+     * using this method and then executing {@link #getResult}, since
+     * <code>evaluate</code> leverages the fact that is has the full
+     * list of values together to execute a two-pass algorithm.
+     * See {@link Variance}.</p>
+     */
+    @Override
+    public void increment(final double d) {
+        if (incMoment) {
+            moment.increment(d);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+            if (moment.n == 0) {
+                return Double.NaN;
+            } else if (moment.n == 1) {
+                return 0d;
+            } else {
+                if (isBiasCorrected) {
+                    return moment.m2 / (moment.n - 1d);
+                } else {
+                    return moment.m2 / (moment.n);
+                }
+            }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return moment.getN();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        if (incMoment) {
+            moment.clear();
+        }
+    }
+
+    /**
+     * Returns the variance of the entries in the input array, or
+     * <code>Double.NaN</code> if the array is empty.
+     * <p>
+     * See {@link Variance} for details on the computing algorithm.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null
+     */
+    @Override
+    public double evaluate(final double[] values) {
+        if (values == null) {
+            throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
+        }
+        return evaluate(values, 0, values.length);
+    }
+
+    /**
+     * Returns the variance of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * See {@link Variance} for details on the computing algorithm.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length) {
+
+        double var = Double.NaN;
+
+        if (test(values, begin, length)) {
+            clear();
+            if (length == 1) {
+                var = 0.0;
+            } else if (length > 1) {
+                Mean mean = new Mean();
+                double m = mean.evaluate(values, begin, length);
+                var = evaluate(values, m, begin, length);
+            }
+        }
+        return var;
+    }
+
+    /**
+     * <p>Returns the weighted variance of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.</p>
+     * <p>
+     * Uses the formula <pre>
+     *   &Sigma;(weights[i]*(values[i] - weightedMean)<sup>2</sup>)/(&Sigma;(weights[i]) - 1)
+     * </pre>
+     * where weightedMean is the weighted mean</p>
+     * <p>
+     * This formula will not return the same result as the unweighted variance when all
+     * weights are equal, unless all weights are equal to 1. The formula assumes that
+     * weights are to be treated as "expansion values," as will be the case if for example
+     * the weights represent frequency counts. To normalize weights so that the denominator
+     * in the variance computation equals the length of the input vector minus one, use <pre>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length)); </code>
+     * </pre>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     *     <li>the start and length arguments do not determine a valid array</li>
+     * </ul></p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if either array is null.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the weighted variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights,
+                           final int begin, final int length) {
+
+        double var = Double.NaN;
+
+        if (test(values, weights,begin, length)) {
+            clear();
+            if (length == 1) {
+                var = 0.0;
+            } else if (length > 1) {
+                Mean mean = new Mean();
+                double m = mean.evaluate(values, weights, begin, length);
+                var = evaluate(values, weights, m, begin, length);
+            }
+        }
+        return var;
+    }
+
+    /**
+     * <p>
+     * Returns the weighted variance of the entries in the the input array.</p>
+     * <p>
+     * Uses the formula <pre>
+     *   &Sigma;(weights[i]*(values[i] - weightedMean)<sup>2</sup>)/(&Sigma;(weights[i]) - 1)
+     * </pre>
+     * where weightedMean is the weighted mean</p>
+     * <p>
+     * This formula will not return the same result as the unweighted variance when all
+     * weights are equal, unless all weights are equal to 1. The formula assumes that
+     * weights are to be treated as "expansion values," as will be the case if for example
+     * the weights represent frequency counts. To normalize weights so that the denominator
+     * in the variance computation equals the length of the input vector minus one, use <pre>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length)); </code>
+     * </pre>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if either array is null.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the weighted variance of the values
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
+
+    /**
+     * Returns the variance of the entries in the specified portion of
+     * the input array, using the precomputed mean value.  Returns
+     * <code>Double.NaN</code> if the designated subarray is empty.
+     * <p>
+     * See {@link Variance} for details on the computing algorithm.</p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the arithmetic
+     * mean of the sample data, not a known population parameter.  This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    public double evaluate(final double[] values, final double mean,
+            final int begin, final int length) {
+
+        double var = Double.NaN;
+
+        if (test(values, begin, length)) {
+            if (length == 1) {
+                var = 0.0;
+            } else if (length > 1) {
+                double accum = 0.0;
+                double dev = 0.0;
+                double accum2 = 0.0;
+                for (int i = begin; i < begin + length; i++) {
+                    dev = values[i] - mean;
+                    accum += dev * dev;
+                    accum2 += dev;
+                }
+                double len = length;
+                if (isBiasCorrected) {
+                    var = (accum - (accum2 * accum2 / len)) / (len - 1.0);
+                } else {
+                    var = (accum - (accum2 * accum2 / len)) / len;
+                }
+            }
+        }
+        return var;
+    }
+
+    /**
+     * Returns the variance of the entries in the input array, using the
+     * precomputed mean value.  Returns <code>Double.NaN</code> if the array
+     * is empty.
+     * <p>
+     * See {@link Variance} for details on the computing algorithm.</p>
+     * <p>
+     * If <code>isBiasCorrected</code> is <code>true</code> the formula used
+     * assumes that the supplied mean value is the arithmetic mean of the
+     * sample data, not a known population parameter.  If the mean is a known
+     * population parameter, or if the "population" version of the variance is
+     * desired, set <code>isBiasCorrected</code> to <code>false</code> before
+     * invoking this method.</p>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param mean the precomputed mean value
+     * @return the variance of the values or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if the array is null
+     */
+    public double evaluate(final double[] values, final double mean) {
+        return evaluate(values, mean, 0, values.length);
+    }
+
+    /**
+     * Returns the weighted variance of the entries in the specified portion of
+     * the input array, using the precomputed weighted mean value.  Returns
+     * <code>Double.NaN</code> if the designated subarray is empty.
+     * <p>
+     * Uses the formula <pre>
+     *   &Sigma;(weights[i]*(values[i] - mean)<sup>2</sup>)/(&Sigma;(weights[i]) - 1)
+     * </pre></p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the weighted arithmetic
+     * mean of the sample data, not a known population parameter. This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * This formula will not return the same result as the unweighted variance when all
+     * weights are equal, unless all weights are equal to 1. The formula assumes that
+     * weights are to be treated as "expansion values," as will be the case if for example
+     * the weights represent frequency counts. To normalize weights so that the denominator
+     * in the variance computation equals the length of the input vector minus one, use <pre>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length), mean); </code>
+     * </pre>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     *     <li>the start and length arguments do not determine a valid array</li>
+     * </ul></p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param mean the precomputed weighted mean value
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights,
+                           final double mean, final int begin, final int length) {
+
+        double var = Double.NaN;
+
+        if (test(values, weights, begin, length)) {
+            if (length == 1) {
+                var = 0.0;
+            } else if (length > 1) {
+                double accum = 0.0;
+                double dev = 0.0;
+                double accum2 = 0.0;
+                for (int i = begin; i < begin + length; i++) {
+                    dev = values[i] - mean;
+                    accum += weights[i] * (dev * dev);
+                    accum2 += weights[i] * dev;
+                }
+
+                double sumWts = 0;
+                for (int i = 0; i < weights.length; i++) {
+                    sumWts += weights[i];
+                }
+
+                if (isBiasCorrected) {
+                    var = (accum - (accum2 * accum2 / sumWts)) / (sumWts - 1.0);
+                } else {
+                    var = (accum - (accum2 * accum2 / sumWts)) / sumWts;
+                }
+            }
+        }
+        return var;
+    }
+
+    /**
+     * <p>Returns the weighted variance of the values in the input array, using
+     * the precomputed weighted mean value.</p>
+     * <p>
+     * Uses the formula <pre>
+     *   &Sigma;(weights[i]*(values[i] - mean)<sup>2</sup>)/(&Sigma;(weights[i]) - 1)
+     * </pre></p>
+     * <p>
+     * The formula used assumes that the supplied mean value is the weighted arithmetic
+     * mean of the sample data, not a known population parameter. This method
+     * is supplied only to save computation when the mean has already been
+     * computed.</p>
+     * <p>
+     * This formula will not return the same result as the unweighted variance when all
+     * weights are equal, unless all weights are equal to 1. The formula assumes that
+     * weights are to be treated as "expansion values," as will be the case if for example
+     * the weights represent frequency counts. To normalize weights so that the denominator
+     * in the variance computation equals the length of the input vector minus one, use <pre>
+     *   <code>evaluate(values, MathUtils.normalizeArray(weights, values.length), mean); </code>
+     * </pre>
+     * <p>
+     * Returns 0 for a single-value (i.e. length = 1) sample.</p>
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     * <p>
+     * Does not change the internal state of the statistic.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param mean the precomputed weighted mean value
+     * @return the variance of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights, final double mean) {
+        return evaluate(values, weights, mean, 0, values.length);
+    }
+
+    /**
+     * @return Returns the isBiasCorrected.
+     */
+    public boolean isBiasCorrected() {
+        return isBiasCorrected;
+    }
+
+    /**
+     * @param biasCorrected The isBiasCorrected to set.
+     */
+    public void setBiasCorrected(boolean biasCorrected) {
+        this.isBiasCorrected = biasCorrected;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Variance copy() {
+        Variance result = new Variance();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Variance to copy
+     * @param dest Variance to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Variance source, Variance dest) {
+        if (source == null ||
+            dest == null) {
+            throw new NullArgumentException();
+        }
+        dest.setData(source.getDataRef());
+        dest.moment = source.moment.copy();
+        dest.isBiasCorrected = source.isBiasCorrected;
+        dest.incMoment = source.incMoment;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java
new file mode 100644
index 0000000..71afc68
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.java
@@ -0,0 +1,152 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.linear.MatrixUtils;
+import org.apache.commons.math.linear.RealMatrix;
+
+/**
+ * Returns the covariance matrix of the available vectors.
+ * @since 1.2
+ * @version $Revision: 922714 $ $Date: 2010-03-14 02:35:14 +0100 (dim. 14 mars 2010) $
+ */
+public class VectorialCovariance implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4118372414238930270L;
+
+    /** Sums for each component. */
+    private final double[] sums;
+
+    /** Sums of products for each component. */
+    private final double[] productsSums;
+
+    /** Indicator for bias correction. */
+    private final boolean isBiasCorrected;
+
+    /** Number of vectors in the sample. */
+    private long n;
+
+    /** Constructs a VectorialCovariance.
+     * @param dimension vectors dimension
+     * @param isBiasCorrected if true, computed the unbiased sample covariance,
+     * otherwise computes the biased population covariance
+     */
+    public VectorialCovariance(int dimension, boolean isBiasCorrected) {
+        sums         = new double[dimension];
+        productsSums = new double[dimension * (dimension + 1) / 2];
+        n            = 0;
+        this.isBiasCorrected = isBiasCorrected;
+    }
+
+    /**
+     * Add a new vector to the sample.
+     * @param v vector to add
+     * @exception DimensionMismatchException if the vector does not have the right dimension
+     */
+    public void increment(double[] v) throws DimensionMismatchException {
+        if (v.length != sums.length) {
+            throw new DimensionMismatchException(v.length, sums.length);
+        }
+        int k = 0;
+        for (int i = 0; i < v.length; ++i) {
+            sums[i] += v[i];
+            for (int j = 0; j <= i; ++j) {
+                productsSums[k++] += v[i] * v[j];
+            }
+        }
+        n++;
+    }
+
+    /**
+     * Get the covariance matrix.
+     * @return covariance matrix
+     */
+    public RealMatrix getResult() {
+
+        int dimension = sums.length;
+        RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension);
+
+        if (n > 1) {
+            double c = 1.0 / (n * (isBiasCorrected ? (n - 1) : n));
+            int k = 0;
+            for (int i = 0; i < dimension; ++i) {
+                for (int j = 0; j <= i; ++j) {
+                    double e = c * (n * productsSums[k++] - sums[i] * sums[j]);
+                    result.setEntry(i, j, e);
+                    result.setEntry(j, i, e);
+                }
+            }
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Get the number of vectors in the sample.
+     * @return number of vectors in the sample
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * Clears the internal state of the Statistic
+     */
+    public void clear() {
+        n = 0;
+        Arrays.fill(sums, 0.0);
+        Arrays.fill(productsSums, 0.0);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (isBiasCorrected ? 1231 : 1237);
+        result = prime * result + (int) (n ^ (n >>> 32));
+        result = prime * result + Arrays.hashCode(productsSums);
+        result = prime * result + Arrays.hashCode(sums);
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof VectorialCovariance))
+            return false;
+        VectorialCovariance other = (VectorialCovariance) obj;
+        if (isBiasCorrected != other.isBiasCorrected)
+            return false;
+        if (n != other.n)
+            return false;
+        if (!Arrays.equals(productsSums, other.productsSums))
+            return false;
+        if (!Arrays.equals(sums, other.sums))
+            return false;
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java b/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java
new file mode 100644
index 0000000..ef57657
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/VectorialMean.java
@@ -0,0 +1,103 @@
+/*
+ * 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.stat.descriptive.moment;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.DimensionMismatchException;
+
+/**
+ * Returns the arithmetic mean of the available vectors.
+ * @since 1.2
+ * @version $Revision: 922714 $ $Date: 2010-03-14 02:35:14 +0100 (dim. 14 mars 2010) $
+ */
+public class VectorialMean implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 8223009086481006892L;
+
+    /** Means for each component. */
+    private final Mean[] means;
+
+    /** Constructs a VectorialMean.
+     * @param dimension vectors dimension
+     */
+    public VectorialMean(int dimension) {
+        means = new Mean[dimension];
+        for (int i = 0; i < dimension; ++i) {
+            means[i] = new Mean();
+        }
+    }
+
+    /**
+     * Add a new vector to the sample.
+     * @param v vector to add
+     * @exception DimensionMismatchException if the vector does not have the right dimension
+     */
+    public void increment(double[] v) throws DimensionMismatchException {
+        if (v.length != means.length) {
+            throw new DimensionMismatchException(v.length, means.length);
+        }
+        for (int i = 0; i < v.length; ++i) {
+            means[i].increment(v[i]);
+        }
+    }
+
+    /**
+     * Get the mean vector.
+     * @return mean vector
+     */
+    public double[] getResult() {
+        double[] result = new double[means.length];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = means[i].getResult();
+        }
+        return result;
+    }
+
+    /**
+     * Get the number of vectors in the sample.
+     * @return number of vectors in the sample
+     */
+    public long getN() {
+        return (means.length == 0) ? 0 : means[0].getN();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode(means);
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!(obj instanceof VectorialMean))
+            return false;
+        VectorialMean other = (VectorialMean) obj;
+        if (!Arrays.equals(means, other.means))
+            return false;
+        return true;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/moment/package.html b/src/main/java/org/apache/commons/math/stat/descriptive/moment/package.html
new file mode 100644
index 0000000..e024095
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/moment/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Summary statistics based on moments.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/package.html b/src/main/java/org/apache/commons/math/stat/descriptive/package.html
new file mode 100644
index 0000000..981fda4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/package.html
@@ -0,0 +1,41 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ -->
+    <body>
+        Generic univariate summary statistic objects.
+
+        <h3>UnivariateStatistic API Usage Examples:</h3>
+        <h4>UnivariateStatistic:</h4>
+        <code>/* evaluation approach */<br/> double[] values = new double[] { 1, 2,
+            3, 4, 5 };<br/> <span style="font-weight: bold;">UnivariateStatistic stat
+            = new Mean();</span><br/> System.out.println("mean = " + <span
+            style="font-weight: bold;">stat.evaluate(values)</span>);<br/> </code>
+        <h4>StorelessUnivariateStatistic:</h4>
+        <code>/* incremental approach */<br/> double[] values = new double[] { 1, 2,
+            3, 4, 5 };<br/> <span style="font-weight: bold;">
+            StorelessUnivariateStatistic stat = new Mean();</span><br/>
+            System.out.println("mean before adding a value is NaN = " + <span
+            style="font-weight: bold;">stat.getResult()</span>);<br/> for (int i = 0;
+            i &lt; values.length; i++) {<br/> &nbsp;&nbsp;&nbsp; <span
+            style="font-weight: bold;">stat.increment(values[i]);</span><br/> &nbsp;&nbsp;&nbsp;
+            System.out.println("current mean = " + <span style="font-weight: bold;">
+            stat2.getResult()</span>);<br/> }<br/> <span style="font-weight: bold;">
+            stat.clear();</span><br/> System.out.println("mean after clear is NaN = "
+            + <span style="font-weight: bold;">stat.getResult()</span>);</code>
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/rank/Max.java b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Max.java
new file mode 100644
index 0000000..1b15750
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Max.java
@@ -0,0 +1,163 @@
+/*
+ * 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.stat.descriptive.rank;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+
+/**
+ * Returns the maximum of the available values.
+ * <p>
+ * <ul>
+ * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+ * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+ * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
+ * the result is <code>Double.POSITIVE_INFINITY.</code></li>
+ * </ul></p>
+* <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Max extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -5593383832225844641L;
+
+    /** Number of values that have been added */
+    private long n;
+
+    /** Current value of the statistic */
+    private double value;
+
+    /**
+     * Create a Max instance
+     */
+    public Max() {
+        n = 0;
+        value = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Max} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Max} instance to copy
+     */
+    public Max(Max original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (d > value || Double.isNaN(value)) {
+            value = d;
+        }
+        n++;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        value = Double.NaN;
+        n = 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * Returns the maximum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null or
+     * the array index parameters are not valid.</p>
+     * <p>
+     * <ul>
+     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+     * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
+     * the result is <code>Double.POSITIVE_INFINITY.</code></li>
+     * </ul></p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the maximum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length) {
+        double max = Double.NaN;
+        if (test(values, begin, length)) {
+            max = values[begin];
+            for (int i = begin; i < begin + length; i++) {
+                if (!Double.isNaN(values[i])) {
+                    max = (max > values[i]) ? max : values[i];
+                }
+            }
+        }
+        return max;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Max copy() {
+        Max result = new Max();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Max to copy
+     * @param dest Max to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Max source, Max dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.value = source.value;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/rank/Median.java b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Median.java
new file mode 100644
index 0000000..6e13b13
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Median.java
@@ -0,0 +1,55 @@
+/*
+ * 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.stat.descriptive.rank;
+
+import java.io.Serializable;
+
+
+/**
+ * Returns the median of the available values.  This is the same as the 50th percentile.
+ * See {@link Percentile} for a description of the algorithm used.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public class Median extends Percentile implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3961477041290915687L;
+
+    /**
+     * Default constructor.
+     */
+    public Median() {
+        super(50.0);
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Median} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Median} instance to copy
+     */
+    public Median(Median original) {
+        super(original);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/rank/Min.java b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Min.java
new file mode 100644
index 0000000..1c264c6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Min.java
@@ -0,0 +1,163 @@
+/*
+ * 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.stat.descriptive.rank;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+
+/**
+ * Returns the minimum of the available values.
+ * <p>
+ * <ul>
+ * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+ * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+ * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
+ * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
+ * </ul></p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Min extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -2941995784909003131L;
+
+    /**Number of values that have been added */
+    private long n;
+
+    /**Current value of the statistic */
+    private double value;
+
+    /**
+     * Create a Min instance
+     */
+    public Min() {
+        n = 0;
+        value = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Min} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Min} instance to copy
+     */
+    public Min(Min original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (d < value || Double.isNaN(value)) {
+            value = d;
+        }
+        n++;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        value = Double.NaN;
+        n = 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * Returns the minimum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null or
+     * the array index parameters are not valid.</p>
+     * <p>
+     * <ul>
+     * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
+     * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
+     * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
+     * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
+     * </ul> </p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the minimum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values,final int begin, final int length) {
+        double min = Double.NaN;
+        if (test(values, begin, length)) {
+            min = values[begin];
+            for (int i = begin; i < begin + length; i++) {
+                if (!Double.isNaN(values[i])) {
+                    min = (min < values[i]) ? min : values[i];
+                }
+            }
+        }
+        return min;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Min copy() {
+        Min result = new Min();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Min to copy
+     * @param dest Min to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Min source, Min dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.value = source.value;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/rank/Percentile.java b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Percentile.java
new file mode 100644
index 0000000..0c8a90f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/rank/Percentile.java
@@ -0,0 +1,497 @@
+/*
+ * 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.stat.descriptive.rank;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Provides percentile computation.
+ * <p>
+ * There are several commonly used methods for estimating percentiles (a.k.a.
+ * quantiles) based on sample data.  For large samples, the different methods
+ * agree closely, but when sample sizes are small, different methods will give
+ * significantly different results.  The algorithm implemented here works as follows:
+ * <ol>
+ * <li>Let <code>n</code> be the length of the (sorted) array and
+ * <code>0 < p <= 100</code> be the desired percentile.</li>
+ * <li>If <code> n = 1 </code> return the unique array element (regardless of
+ * the value of <code>p</code>); otherwise </li>
+ * <li>Compute the estimated percentile position
+ * <code> pos = p * (n + 1) / 100</code> and the difference, <code>d</code>
+ * between <code>pos</code> and <code>floor(pos)</code> (i.e. the fractional
+ * part of <code>pos</code>).  If <code>pos >= n</code> return the largest
+ * element in the array; otherwise</li>
+ * <li>Let <code>lower</code> be the element in position
+ * <code>floor(pos)</code> in the array and let <code>upper</code> be the
+ * next element in the array.  Return <code>lower + d * (upper - lower)</code>
+ * </li>
+ * </ol></p>
+ * <p>
+ * To compute percentiles, the data must be at least partially ordered.  Input
+ * arrays are copied and recursively partitioned using an ordering definition.
+ * The ordering used by <code>Arrays.sort(double[])</code> is the one determined
+ * by {@link java.lang.Double#compareTo(Double)}.  This ordering makes
+ * <code>Double.NaN</code> larger than any other value (including
+ * <code>Double.POSITIVE_INFINITY</code>).  Therefore, for example, the median
+ * (50th percentile) of
+ * <code>{0, 1, 2, 3, 4, Double.NaN}</code> evaluates to <code>2.5.</code></p>
+ * <p>
+ * Since percentile estimation usually involves interpolation between array
+ * elements, arrays containing  <code>NaN</code> or infinite values will often
+ * result in <code>NaN<code> or infinite values returned.</p>
+ * <p>
+ * Since 2.2, Percentile implementation uses only selection instead of complete
+ * sorting and caches selection algorithm state between calls to the various
+ * {@code evaluate} methods when several percentiles are to be computed on the same data.
+ * This greatly improves efficiency, both for single percentile and multiple
+ * percentiles computations. However, it also induces a need to be sure the data
+ * at one call to {@code evaluate} is the same as the data with the cached algorithm
+ * state from the previous calls. Percentile does this by checking the array reference
+ * itself and a checksum of its content by default. If the user already knows he calls
+ * {@code evaluate} on an immutable array, he can save the checking time by calling the
+ * {@code evaluate} methods that do <em>not</em>
+ * </p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Percentile extends AbstractUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -8091216485095130416L;
+
+    /** Minimum size under which we use a simple insertion sort rather than Hoare's select. */
+    private static final int MIN_SELECT_SIZE = 15;
+
+    /** Maximum number of partitioning pivots cached (each level double the number of pivots). */
+    private static final int MAX_CACHED_LEVELS = 10;
+
+    /** Determines what percentile is computed when evaluate() is activated
+     * with no quantile argument */
+    private double quantile = 0.0;
+
+    /** Cached pivots. */
+    private int[] cachedPivots;
+
+    /**
+     * Constructs a Percentile with a default quantile
+     * value of 50.0.
+     */
+    public Percentile() {
+        this(50.0);
+    }
+
+    /**
+     * Constructs a Percentile with the specific quantile value.
+     * @param p the quantile
+     * @throws IllegalArgumentException  if p is not greater than 0 and less
+     * than or equal to 100
+     */
+    public Percentile(final double p) {
+        setQuantile(p);
+        cachedPivots = null;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Percentile} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Percentile} instance to copy
+     */
+    public Percentile(Percentile original) {
+        copy(original, this);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setData(final double[] values) {
+        if (values == null) {
+            cachedPivots = null;
+        } else {
+            cachedPivots = new int[(0x1 << MAX_CACHED_LEVELS) - 1];
+            Arrays.fill(cachedPivots, -1);
+        }
+        super.setData(values);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setData(final double[] values, final int begin, final int length) {
+        if (values == null) {
+            cachedPivots = null;
+        } else {
+            cachedPivots = new int[(0x1 << MAX_CACHED_LEVELS) - 1];
+            Arrays.fill(cachedPivots, -1);
+        }
+        super.setData(values, begin, length);
+    }
+
+    /**
+     * Returns the result of evaluating the statistic over the stored data.
+     * <p>
+     * The stored array is the one which was set by previous calls to
+     * </p>
+     * @param p the percentile value to compute
+     * @return the value of the statistic applied to the stored data
+     */
+    public double evaluate(final double p) {
+        return evaluate(getDataRef(), p);
+    }
+
+    /**
+     * Returns an estimate of the <code>p</code>th percentile of the values
+     * in the <code>values</code> array.
+     * <p>
+     * Calls to this method do not modify the internal <code>quantile</code>
+     * state of this statistic.</p>
+     * <p>
+     * <ul>
+     * <li>Returns <code>Double.NaN</code> if <code>values</code> has length
+     * <code>0</code></li>
+     * <li>Returns (for any value of <code>p</code>) <code>values[0]</code>
+     *  if <code>values</code> has length <code>1</code></li>
+     * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
+     * is null or p is not a valid quantile value (p must be greater than 0
+     * and less than or equal to 100) </li>
+     * </ul></p>
+     * <p>
+     * See {@link Percentile} for a description of the percentile estimation
+     * algorithm used.</p>
+     *
+     * @param values input array of values
+     * @param p the percentile value to compute
+     * @return the percentile value or Double.NaN if the array is empty
+     * @throws IllegalArgumentException if <code>values</code> is null
+     *     or p is invalid
+     */
+    public double evaluate(final double[] values, final double p) {
+        test(values, 0, 0);
+        return evaluate(values, 0, values.length, p);
+    }
+
+    /**
+     * Returns an estimate of the <code>quantile</code>th percentile of the
+     * designated values in the <code>values</code> array.  The quantile
+     * estimated is determined by the <code>quantile</code> property.
+     * <p>
+     * <ul>
+     * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li>
+     * <li>Returns (for any value of <code>quantile</code>)
+     * <code>values[begin]</code> if <code>length = 1 </code></li>
+     * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
+     * is null,  or <code>start</code> or <code>length</code>
+     * is invalid</li>
+     * </ul></p>
+     * <p>
+     * See {@link Percentile} for a description of the percentile estimation
+     * algorithm used.</p>
+     *
+     * @param values the input array
+     * @param start index of the first array element to include
+     * @param length the number of elements to include
+     * @return the percentile value
+     * @throws IllegalArgumentException if the parameters are not valid
+     *
+     */
+    @Override
+    public double evaluate( final double[] values, final int start, final int length) {
+        return evaluate(values, start, length, quantile);
+    }
+
+     /**
+     * Returns an estimate of the <code>p</code>th percentile of the values
+     * in the <code>values</code> array, starting with the element in (0-based)
+     * position <code>begin</code> in the array and including <code>length</code>
+     * values.
+     * <p>
+     * Calls to this method do not modify the internal <code>quantile</code>
+     * state of this statistic.</p>
+     * <p>
+     * <ul>
+     * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li>
+     * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code>
+     *  if <code>length = 1 </code></li>
+     * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
+     *  is null , <code>begin</code> or <code>length</code> is invalid, or
+     * <code>p</code> is not a valid quantile value (p must be greater than 0
+     * and less than or equal to 100)</li>
+     * </ul></p>
+     * <p>
+     * See {@link Percentile} for a description of the percentile estimation
+     * algorithm used.</p>
+     *
+     * @param values array of input values
+     * @param p  the percentile to compute
+     * @param begin  the first (0-based) element to include in the computation
+     * @param length  the number of array elements to include
+     * @return  the percentile value
+     * @throws IllegalArgumentException if the parameters are not valid or the
+     * input array is null
+     */
+    public double evaluate(final double[] values, final int begin,
+            final int length, final double p) {
+
+        test(values, begin, length);
+
+        if ((p > 100) || (p <= 0)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, p);
+        }
+        if (length == 0) {
+            return Double.NaN;
+        }
+        if (length == 1) {
+            return values[begin]; // always return single value for n = 1
+        }
+        double n = length;
+        double pos = p * (n + 1) / 100;
+        double fpos = FastMath.floor(pos);
+        int intPos = (int) fpos;
+        double dif = pos - fpos;
+        double[] work;
+        int[] pivotsHeap;
+        if (values == getDataRef()) {
+            work = getDataRef();
+            pivotsHeap = cachedPivots;
+        } else {
+            work = new double[length];
+            System.arraycopy(values, begin, work, 0, length);
+            pivotsHeap = new int[(0x1 << MAX_CACHED_LEVELS) - 1];
+            Arrays.fill(pivotsHeap, -1);
+        }
+
+        if (pos < 1) {
+            return select(work, pivotsHeap, 0);
+        }
+        if (pos >= n) {
+            return select(work, pivotsHeap, length - 1);
+        }
+        double lower = select(work, pivotsHeap, intPos - 1);
+        double upper = select(work, pivotsHeap, intPos);
+        return lower + dif * (upper - lower);
+    }
+
+    /**
+     * Select the k<sup>th</sup> smallest element from work array
+     * @param work work array (will be reorganized during the call)
+     * @param pivotsHeap set of pivot index corresponding to elements that
+     * are already at their sorted location, stored as an implicit heap
+     * (i.e. a sorted binary tree stored in a flat array, where the
+     * children of a node at index n are at indices 2n+1 for the left
+     * child and 2n+2 for the right child, with 0-based indices)
+     * @param k index of the desired element
+     * @return k<sup>th</sup> smallest element
+     */
+    private double select(final double[] work, final int[] pivotsHeap, final int k) {
+
+        int begin = 0;
+        int end   = work.length;
+        int node  = 0;
+
+        while (end - begin > MIN_SELECT_SIZE) {
+
+            final int pivot;
+            if ((node < pivotsHeap.length) && (pivotsHeap[node] >= 0)) {
+                // the pivot has already been found in a previous call
+                // and the array has already been partitioned around it
+                pivot = pivotsHeap[node];
+            } else {
+                // select a pivot and partition work array around it
+                pivot = partition(work, begin, end, medianOf3(work, begin, end));
+                if (node < pivotsHeap.length) {
+                    pivotsHeap[node] =  pivot;
+                }
+            }
+
+            if (k == pivot) {
+                // the pivot was exactly the element we wanted
+                return work[k];
+            } else if (k < pivot) {
+                // the element is in the left partition
+                end  = pivot;
+                node = Math.min(2 * node + 1, pivotsHeap.length); // the min is here to avoid integer overflow
+            } else {
+                // the element is in the right partition
+                begin = pivot + 1;
+                node  = Math.min(2 * node + 2, pivotsHeap.length); // the min is here to avoid integer overflow
+            }
+
+        }
+
+        // the element is somewhere in the small sub-array
+        // sort the sub-array using insertion sort
+        insertionSort(work, begin, end);
+        return work[k];
+
+    }
+
+    /** Select a pivot index as the median of three
+     * @param work data array
+     * @param begin index of the first element of the slice
+     * @param end index after the last element of the slice
+     * @return the index of the median element chosen between the
+     * first, the middle and the last element of the array slice
+     */
+    int medianOf3(final double[] work, final int begin, final int end) {
+
+        final int inclusiveEnd = end - 1;
+        final int    middle    = begin + (inclusiveEnd - begin) / 2;
+        final double wBegin    = work[begin];
+        final double wMiddle   = work[middle];
+        final double wEnd      = work[inclusiveEnd];
+
+        if (wBegin < wMiddle) {
+            if (wMiddle < wEnd) {
+                return middle;
+            } else {
+                return (wBegin < wEnd) ? inclusiveEnd : begin;
+            }
+        } else {
+            if (wBegin < wEnd) {
+                return begin;
+            } else {
+                return (wMiddle < wEnd) ? inclusiveEnd : middle;
+            }
+        }
+
+    }
+
+    /**
+     * Partition an array slice around a pivot
+     * <p>
+     * Partitioning exchanges array elements such that all elements
+     * smaller than pivot are before it and all elements larger than
+     * pivot are after it
+     * </p>
+     * @param work data array
+     * @param begin index of the first element of the slice
+     * @param end index after the last element of the slice
+     * @param pivot initial index of the pivot
+     * @return index of the pivot after partition
+     */
+    private int partition(final double[] work, final int begin, final int end, final int pivot) {
+
+        final double value = work[pivot];
+        work[pivot] = work[begin];
+
+        int i = begin + 1;
+        int j = end - 1;
+        while (i < j) {
+            while ((i < j) && (work[j] >= value)) {
+                --j;
+            }
+            while ((i < j) && (work[i] <= value)) {
+                ++i;
+            }
+
+            if (i < j) {
+                final double tmp = work[i];
+                work[i++] = work[j];
+                work[j--] = tmp;
+            }
+        }
+
+        if ((i >= end) || (work[i] > value)) {
+            --i;
+        }
+        work[begin] = work[i];
+        work[i]     = value;
+        return i;
+
+    }
+
+    /**
+     * Sort in place a (small) array slice using insertion sort
+     * @param work array to sort
+     * @param begin index of the first element of the slice to sort
+     * @param end index after the last element of the slice to sort
+     */
+    private void insertionSort(final double[] work, final int begin, final int end) {
+        for (int j = begin + 1; j < end; j++) {
+            final double saved = work[j];
+            int i = j - 1;
+            while ((i >= begin) && (saved < work[i])) {
+                work[i + 1] = work[i];
+                i--;
+            }
+            work[i + 1] = saved;
+        }
+    }
+
+    /**
+     * Returns the value of the quantile field (determines what percentile is
+     * computed when evaluate() is called with no quantile argument).
+     *
+     * @return quantile
+     */
+    public double getQuantile() {
+        return quantile;
+    }
+
+    /**
+     * Sets the value of the quantile field (determines what percentile is
+     * computed when evaluate() is called with no quantile argument).
+     *
+     * @param p a value between 0 < p <= 100
+     * @throws IllegalArgumentException  if p is not greater than 0 and less
+     * than or equal to 100
+     */
+    public void setQuantile(final double p) {
+        if (p <= 0 || p > 100) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, p);
+        }
+        quantile = p;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Percentile copy() {
+        Percentile result = new Percentile();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Percentile to copy
+     * @param dest Percentile to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Percentile source, Percentile dest) {
+        dest.setData(source.getDataRef());
+        if (source.cachedPivots != null) {
+            System.arraycopy(source.cachedPivots, 0, dest.cachedPivots, 0, source.cachedPivots.length);
+        }
+        dest.quantile = source.quantile;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/rank/package.html b/src/main/java/org/apache/commons/math/stat/descriptive/rank/package.html
new file mode 100644
index 0000000..c69107b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/rank/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Summary statistics based on ranks.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java
new file mode 100644
index 0000000..c7d1d76
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Product.java
@@ -0,0 +1,224 @@
+/*
+ * 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.stat.descriptive.summary;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.stat.descriptive.WeightedEvaluation;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Returns the product of the available values.
+ * <p>
+ * If there are no values in the dataset, or any of the values are
+ * <code>NaN</code>, then <code>NaN</code> is returned.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Product extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 2824226005990582538L;
+
+    /**The number of values that have been added */
+    private long n;
+
+    /**
+     * The current Running Product.
+     */
+    private double value;
+
+    /**
+     * Create a Product instance
+     */
+    public Product() {
+        n = 0;
+        value = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Product} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Product} instance to copy
+     */
+    public Product(Product original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (n == 0) {
+            value = d;
+        } else {
+            value *= d;
+        }
+        n++;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        value = Double.NaN;
+        n = 0;
+    }
+
+    /**
+     * Returns the product of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the product of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length) {
+        double product = Double.NaN;
+        if (test(values, begin, length)) {
+            product = 1.0;
+            for (int i = begin; i < begin + length; i++) {
+                product *= values[i];
+            }
+        }
+        return product;
+    }
+
+    /**
+     * <p>Returns the weighted product of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.</p>
+     *
+     * <p>Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     *     <li>the start and length arguments do not determine a valid array</li>
+     * </ul></p>
+     *
+     * <p>Uses the formula, <pre>
+     *    weighted product = &prod;values[i]<sup>weights[i]</sup>
+     * </pre>
+     * that is, the weights are applied as exponents when computing the weighted product.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the product of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights,
+                           final int begin, final int length) {
+        double product = Double.NaN;
+        if (test(values, weights, begin, length)) {
+            product = 1.0;
+            for (int i = begin; i < begin + length; i++) {
+                product *= FastMath.pow(values[i], weights[i]);
+            }
+        }
+        return product;
+    }
+
+    /**
+     * <p>Returns the weighted product of the entries in the input array.</p>
+     *
+     * <p>Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     *
+     * <p>Uses the formula, <pre>
+     *    weighted product = &prod;values[i]<sup>weights[i]</sup>
+     * </pre>
+     * that is, the weights are applied as exponents when computing the weighted product.</p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the product of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Product copy() {
+        Product result = new Product();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Product to copy
+     * @param dest Product to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Product source, Product dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.value = source.value;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java
new file mode 100644
index 0000000..7188ea8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/Sum.java
@@ -0,0 +1,220 @@
+/*
+ * 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.stat.descriptive.summary;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+
+
+/**
+  * Returns the sum of the available values.
+ * <p>
+ * If there are no values in the dataset, or any of the values are
+ * <code>NaN</code>, then <code>NaN</code> is returned.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class Sum extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -8231831954703408316L;
+
+    /** */
+    private long n;
+
+    /**
+     * The currently running sum.
+     */
+    private double value;
+
+    /**
+     * Create a Sum instance
+     */
+    public Sum() {
+        n = 0;
+        value = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code Sum} identical
+     * to the {@code original}
+     *
+     * @param original the {@code Sum} instance to copy
+     */
+    public Sum(Sum original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (n == 0) {
+            value = d;
+        } else {
+            value += d;
+        }
+        n++;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        value = Double.NaN;
+        n = 0;
+    }
+
+    /**
+     * The sum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length) {
+        double sum = Double.NaN;
+        if (test(values, begin, length)) {
+            sum = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                sum += values[i];
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * The weighted sum of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     *     <li>the start and length arguments do not determine a valid array</li>
+     * </ul></p>
+     * <p>
+     * Uses the formula, <pre>
+     *    weighted sum = &Sigma;(values[i] * weights[i])
+     * </pre></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights,
+                           final int begin, final int length) {
+        double sum = Double.NaN;
+        if (test(values, weights, begin, length)) {
+            sum = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                sum += values[i] * weights[i];
+            }
+        }
+        return sum;
+    }
+
+    /**
+     * The weighted sum of the entries in the the input array.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if any of the following are true:
+     * <ul><li>the values array is null</li>
+     *     <li>the weights array is null</li>
+     *     <li>the weights array does not have the same length as the values array</li>
+     *     <li>the weights array contains one or more infinite values</li>
+     *     <li>the weights array contains one or more NaN values</li>
+     *     <li>the weights array contains negative values</li>
+     * </ul></p>
+     * <p>
+     * Uses the formula, <pre>
+     *    weighted sum = &Sigma;(values[i] * weights[i])
+     * </pre></p>
+     *
+     * @param values the input array
+     * @param weights the weights array
+     * @return the sum of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the parameters are not valid
+     * @since 2.1
+     */
+    public double evaluate(final double[] values, final double[] weights) {
+        return evaluate(values, weights, 0, values.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Sum copy() {
+        Sum result = new Sum();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source Sum to copy
+     * @param dest Sum to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(Sum source, Sum dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.value = source.value;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java
new file mode 100644
index 0000000..331d5d2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.java
@@ -0,0 +1,165 @@
+/*
+ * 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.stat.descriptive.summary;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Returns the sum of the natural logs for this collection of values.
+ * <p>
+ * Uses {@link java.lang.Math#log(double)} to compute the logs.  Therefore,
+ * <ul>
+ * <li>If any of values are < 0, the result is <code>NaN.</code></li>
+ * <li>If all values are non-negative and less than
+ * <code>Double.POSITIVE_INFINITY</code>,  but at least one value is 0, the
+ * result is <code>Double.NEGATIVE_INFINITY.</code></li>
+ * <li>If both <code>Double.POSITIVE_INFINITY</code> and
+ * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is
+ * <code>NaN.</code></li>
+ * </ul></p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class SumOfLogs extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -370076995648386763L;
+
+    /**Number of values that have been added */
+    private int n;
+
+    /**
+     * The currently running value
+     */
+    private double value;
+
+    /**
+     * Create a SumOfLogs instance
+     */
+    public SumOfLogs() {
+       value = 0d;
+       n = 0;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code SumOfLogs} identical
+     * to the {@code original}
+     *
+     * @param original the {@code SumOfLogs} instance to copy
+     */
+    public SumOfLogs(SumOfLogs original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        value += FastMath.log(d);
+        n++;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        if (n > 0) {
+            return value;
+        } else {
+            return Double.NaN;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        value = 0d;
+        n = 0;
+    }
+
+    /**
+     * Returns the sum of the natural logs of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     * <p>
+     * See {@link SumOfLogs}.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the natural logs of the values or Double.NaN if
+     * length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values, final int begin, final int length) {
+        double sumLog = Double.NaN;
+        if (test(values, begin, length)) {
+            sumLog = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                sumLog += FastMath.log(values[i]);
+            }
+        }
+        return sumLog;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SumOfLogs copy() {
+        SumOfLogs result = new SumOfLogs();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source SumOfLogs to copy
+     * @param dest SumOfLogs to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(SumOfLogs source, SumOfLogs dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.value = source.value;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.java b/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.java
new file mode 100644
index 0000000..a632bf6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.java
@@ -0,0 +1,154 @@
+/*
+ * 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.stat.descriptive.summary;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
+
+/**
+ * Returns the sum of the squares of the available values.
+ * <p>
+ * If there are no values in the dataset, or any of the values are
+ * <code>NaN</code>, then <code>NaN</code> is returned.</p>
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong> If
+ * multiple threads access an instance of this class concurrently, and at least
+ * one of the threads invokes the <code>increment()</code> or
+ * <code>clear()</code> method, it must be synchronized externally.</p>
+ *
+ * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
+ */
+public class SumOfSquares extends AbstractStorelessUnivariateStatistic implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 1460986908574398008L;
+
+    /** */
+    private long n;
+
+    /**
+     * The currently running sumSq
+     */
+    private double value;
+
+    /**
+     * Create a SumOfSquares instance
+     */
+    public SumOfSquares() {
+        n = 0;
+        value = Double.NaN;
+    }
+
+    /**
+     * Copy constructor, creates a new {@code SumOfSquares} identical
+     * to the {@code original}
+     *
+     * @param original the {@code SumOfSquares} instance to copy
+     */
+    public SumOfSquares(SumOfSquares original) {
+        copy(original, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void increment(final double d) {
+        if (n == 0) {
+            value = d * d;
+        } else {
+            value += d * d;
+        }
+        n++;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public double getResult() {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clear() {
+        value = Double.NaN;
+        n = 0;
+    }
+
+    /**
+     * Returns the sum of the squares of the entries in the specified portion of
+     * the input array, or <code>Double.NaN</code> if the designated subarray
+     * is empty.
+     * <p>
+     * Throws <code>IllegalArgumentException</code> if the array is null.</p>
+     *
+     * @param values the input array
+     * @param begin index of the first array element to include
+     * @param length the number of elements to include
+     * @return the sum of the squares of the values or Double.NaN if length = 0
+     * @throws IllegalArgumentException if the array is null or the array index
+     *  parameters are not valid
+     */
+    @Override
+    public double evaluate(final double[] values,final int begin, final int length) {
+        double sumSq = Double.NaN;
+        if (test(values, begin, length)) {
+            sumSq = 0.0;
+            for (int i = begin; i < begin + length; i++) {
+                sumSq += values[i] * values[i];
+            }
+        }
+        return sumSq;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public SumOfSquares copy() {
+        SumOfSquares result = new SumOfSquares();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Copies source to dest.
+     * <p>Neither source nor dest can be null.</p>
+     *
+     * @param source SumOfSquares to copy
+     * @param dest SumOfSquares to copy to
+     * @throws NullPointerException if either source or dest is null
+     */
+    public static void copy(SumOfSquares source, SumOfSquares dest) {
+        dest.setData(source.getDataRef());
+        dest.n = source.n;
+        dest.value = source.value;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/descriptive/summary/package.html b/src/main/java/org/apache/commons/math/stat/descriptive/summary/package.html
new file mode 100644
index 0000000..db7f731
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/descriptive/summary/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Other summary statistics.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTest.java b/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTest.java
new file mode 100644
index 0000000..6a3ecac
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.stat.inference;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * An interface for Chi-Square tests.
+ * <p>This interface handles only known distributions. If the distribution is
+ * unknown and should be provided by a sample, then the {@link UnknownDistributionChiSquareTest
+ * UnknownDistributionChiSquareTest} extended interface should be used instead.</p>
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface ChiSquareTest {
+
+     /**
+     * Computes the <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm">
+     * Chi-Square statistic</a> comparing <code>observed</code> and <code>expected</code>
+     * frequency counts.
+     * <p>
+     * This statistic can be used to perform a Chi-Square test evaluating the null hypothesis that
+     *  the observed counts follow the expected distribution.</p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Expected counts must all be positive.
+     * </li>
+     * <li>Observed counts must all be >= 0.
+     * </li>
+     * <li>The observed and expected arrays must have the same length and
+     * their common length must be at least 2.
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param observed array of observed frequency counts
+     * @param expected array of expected frequency counts
+     * @return chiSquare statistic
+     * @throws IllegalArgumentException if preconditions are not met
+     */
+    double chiSquare(double[] expected, long[] observed)
+        throws IllegalArgumentException;
+
+    /**
+     * Returns the <i>observed significance level</i>, or <a href=
+     * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+     * p-value</a>, associated with a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm">
+     * Chi-square goodness of fit test</a> comparing the <code>observed</code>
+     * frequency counts to those in the <code>expected</code> array.
+     * <p>
+     * The number returned is the smallest significance level at which one can reject
+     * the null hypothesis that the observed counts conform to the frequency distribution
+     * described by the expected counts.</p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Expected counts must all be positive.
+     * </li>
+     * <li>Observed counts must all be >= 0.
+     * </li>
+     * <li>The observed and expected arrays must have the same length and
+     * their common length must be at least 2.
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param observed array of observed frequency counts
+     * @param expected array of expected frequency counts
+     * @return p-value
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double chiSquareTest(double[] expected, long[] observed)
+        throws IllegalArgumentException, MathException;
+
+    /**
+     * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm">
+     * Chi-square goodness of fit test</a> evaluating the null hypothesis that the observed counts
+     * conform to the frequency distribution described by the expected counts, with
+     * significance level <code>alpha</code>.  Returns true iff the null hypothesis can be rejected
+     * with 100 * (1 - alpha) percent confidence.
+     * <p>
+     * <strong>Example:</strong><br>
+     * To test the hypothesis that <code>observed</code> follows
+     * <code>expected</code> at the 99% level, use </p><p>
+     * <code>chiSquareTest(expected, observed, 0.01) </code></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Expected counts must all be positive.
+     * </li>
+     * <li>Observed counts must all be >= 0.
+     * </li>
+     * <li>The observed and expected arrays must have the same length and
+     * their common length must be at least 2.
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param observed array of observed frequency counts
+     * @param expected array of expected frequency counts
+     * @param alpha significance level of the test
+     * @return true iff null hypothesis can be rejected with confidence
+     * 1 - alpha
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean chiSquareTest(double[] expected, long[] observed, double alpha)
+        throws IllegalArgumentException, MathException;
+
+    /**
+     *  Computes the Chi-Square statistic associated with a
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section4/prc45.htm">
+     *  chi-square test of independence</a> based on the input <code>counts</code>
+     *  array, viewed as a two-way table.
+     * <p>
+     * The rows of the 2-way table are
+     * <code>count[0], ... , count[count.length - 1] </code></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>All counts must be >= 0.
+     * </li>
+     * <li>The count array must be rectangular (i.e. all count[i] subarrays
+     *  must have the same length).
+     * </li>
+     * <li>The 2-way table represented by <code>counts</code> must have at
+     *  least 2 columns and at least 2 rows.
+     * </li>
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param counts array representation of 2-way table
+     * @return chiSquare statistic
+     * @throws IllegalArgumentException if preconditions are not met
+     */
+    double chiSquare(long[][] counts)
+    throws IllegalArgumentException;
+
+    /**
+     * Returns the <i>observed significance level</i>, or <a href=
+     * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+     * p-value</a>, associated with a
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section4/prc45.htm">
+     * chi-square test of independence</a> based on the input <code>counts</code>
+     * array, viewed as a two-way table.
+     * <p>
+     * The rows of the 2-way table are
+     * <code>count[0], ... , count[count.length - 1] </code></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>All counts must be >= 0.
+     * </li>
+     * <li>The count array must be rectangular (i.e. all count[i] subarrays must have the same length).
+     * </li>
+     * <li>The 2-way table represented by <code>counts</code> must have at least 2 columns and
+     *        at least 2 rows.
+     * </li>
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param counts array representation of 2-way table
+     * @return p-value
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double chiSquareTest(long[][] counts)
+    throws IllegalArgumentException, MathException;
+
+    /**
+     * Performs a <a href="http://www.itl.nist.gov/div898/handbook/prc/section4/prc45.htm">
+     * chi-square test of independence</a> evaluating the null hypothesis that the classifications
+     * represented by the counts in the columns of the input 2-way table are independent of the rows,
+     * with significance level <code>alpha</code>.  Returns true iff the null hypothesis can be rejected
+     * with 100 * (1 - alpha) percent confidence.
+     * <p>
+     * The rows of the 2-way table are
+     * <code>count[0], ... , count[count.length - 1] </code></p>
+     * <p>
+     * <strong>Example:</strong><br>
+     * To test the null hypothesis that the counts in
+     * <code>count[0], ... , count[count.length - 1] </code>
+     *  all correspond to the same underlying probability distribution at the 99% level, use </p><p>
+     * <code>chiSquareTest(counts, 0.01) </code></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>All counts must be >= 0.
+     * </li>
+     * <li>The count array must be rectangular (i.e. all count[i] subarrays must have the same length).
+     * </li>
+     * <li>The 2-way table represented by <code>counts</code> must have at least 2 columns and
+     *        at least 2 rows.
+     * </li>
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param counts array representation of 2-way table
+     * @param alpha significance level of the test
+     * @return true iff null hypothesis can be rejected with confidence
+     * 1 - alpha
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean chiSquareTest(long[][] counts, double alpha)
+    throws IllegalArgumentException, MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTestImpl.java b/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTestImpl.java
new file mode 100644
index 0000000..abb32a5
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/ChiSquareTestImpl.java
@@ -0,0 +1,424 @@
+/*
+ * 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.stat.inference;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.distribution.ChiSquaredDistribution;
+import org.apache.commons.math.distribution.ChiSquaredDistributionImpl;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements Chi-Square test statistics defined in the
+ * {@link UnknownDistributionChiSquareTest} interface.
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public class ChiSquareTestImpl implements UnknownDistributionChiSquareTest {
+
+    /** Distribution used to compute inference statistics. */
+    private ChiSquaredDistribution distribution;
+
+    /**
+     * Construct a ChiSquareTestImpl
+     */
+    public ChiSquareTestImpl() {
+        this(new ChiSquaredDistributionImpl(1.0));
+    }
+
+    /**
+     * Create a test instance using the given distribution for computing
+     * inference statistics.
+     * @param x distribution used to compute inference statistics.
+     * @since 1.2
+     */
+    public ChiSquareTestImpl(ChiSquaredDistribution x) {
+        super();
+        setDistribution(x);
+    }
+     /**
+     * {@inheritDoc}
+     * <p><strong>Note: </strong>This implementation rescales the
+     * <code>expected</code> array if necessary to ensure that the sum of the
+     * expected and observed counts are equal.</p>
+     *
+     * @param observed array of observed frequency counts
+     * @param expected array of expected frequency counts
+     * @return chi-square test statistic
+     * @throws IllegalArgumentException if preconditions are not met
+     * or length is less than 2
+     */
+    public double chiSquare(double[] expected, long[] observed)
+        throws IllegalArgumentException {
+        if (expected.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, expected.length, 2);
+        }
+        if (expected.length != observed.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, expected.length, observed.length);
+        }
+        checkPositive(expected);
+        checkNonNegative(observed);
+        double sumExpected = 0d;
+        double sumObserved = 0d;
+        for (int i = 0; i < observed.length; i++) {
+            sumExpected += expected[i];
+            sumObserved += observed[i];
+        }
+        double ratio = 1.0d;
+        boolean rescale = false;
+        if (FastMath.abs(sumExpected - sumObserved) > 10E-6) {
+            ratio = sumObserved / sumExpected;
+            rescale = true;
+        }
+        double sumSq = 0.0d;
+        for (int i = 0; i < observed.length; i++) {
+            if (rescale) {
+                final double dev = observed[i] - ratio * expected[i];
+                sumSq += dev * dev / (ratio * expected[i]);
+            } else {
+                final double dev = observed[i] - expected[i];
+                sumSq += dev * dev / expected[i];
+            }
+        }
+        return sumSq;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p><strong>Note: </strong>This implementation rescales the
+     * <code>expected</code> array if necessary to ensure that the sum of the
+     * expected and observed counts are equal.</p>
+     *
+     * @param observed array of observed frequency counts
+     * @param expected array of expected frequency counts
+     * @return p-value
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double chiSquareTest(double[] expected, long[] observed)
+        throws IllegalArgumentException, MathException {
+        distribution.setDegreesOfFreedom(expected.length - 1.0);
+        return 1.0 - distribution.cumulativeProbability(
+            chiSquare(expected, observed));
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p><strong>Note: </strong>This implementation rescales the
+     * <code>expected</code> array if necessary to ensure that the sum of the
+     * expected and observed counts are equal.</p>
+     *
+     * @param observed array of observed frequency counts
+     * @param expected array of expected frequency counts
+     * @param alpha significance level of the test
+     * @return true iff null hypothesis can be rejected with confidence
+     * 1 - alpha
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    public boolean chiSquareTest(double[] expected, long[] observed,
+            double alpha) throws IllegalArgumentException, MathException {
+        if ((alpha <= 0) || (alpha > 0.5)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL,
+                  alpha, 0, 0.5);
+        }
+        return chiSquareTest(expected, observed) < alpha;
+    }
+
+    /**
+     * @param counts array representation of 2-way table
+     * @return chi-square test statistic
+     * @throws IllegalArgumentException if preconditions are not met
+     */
+    public double chiSquare(long[][] counts) throws IllegalArgumentException {
+
+        checkArray(counts);
+        int nRows = counts.length;
+        int nCols = counts[0].length;
+
+        // compute row, column and total sums
+        double[] rowSum = new double[nRows];
+        double[] colSum = new double[nCols];
+        double total = 0.0d;
+        for (int row = 0; row < nRows; row++) {
+            for (int col = 0; col < nCols; col++) {
+                rowSum[row] += counts[row][col];
+                colSum[col] += counts[row][col];
+                total += counts[row][col];
+            }
+        }
+
+        // compute expected counts and chi-square
+        double sumSq = 0.0d;
+        double expected = 0.0d;
+        for (int row = 0; row < nRows; row++) {
+            for (int col = 0; col < nCols; col++) {
+                expected = (rowSum[row] * colSum[col]) / total;
+                sumSq += ((counts[row][col] - expected) *
+                        (counts[row][col] - expected)) / expected;
+            }
+        }
+        return sumSq;
+    }
+
+    /**
+     * @param counts array representation of 2-way table
+     * @return p-value
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double chiSquareTest(long[][] counts)
+    throws IllegalArgumentException, MathException {
+        checkArray(counts);
+        double df = ((double) counts.length -1) * ((double) counts[0].length - 1);
+        distribution.setDegreesOfFreedom(df);
+        return 1 - distribution.cumulativeProbability(chiSquare(counts));
+    }
+
+    /**
+     * @param counts array representation of 2-way table
+     * @param alpha significance level of the test
+     * @return true iff null hypothesis can be rejected with confidence
+     * 1 - alpha
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    public boolean chiSquareTest(long[][] counts, double alpha)
+    throws IllegalArgumentException, MathException {
+        if ((alpha <= 0) || (alpha > 0.5)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL,
+                  alpha, 0.0, 0.5);
+        }
+        return chiSquareTest(counts) < alpha;
+    }
+
+    /**
+     * @param observed1 array of observed frequency counts of the first data set
+     * @param observed2 array of observed frequency counts of the second data set
+     * @return chi-square test statistic
+     * @throws IllegalArgumentException if preconditions are not met
+     * @since 1.2
+     */
+    public double chiSquareDataSetsComparison(long[] observed1, long[] observed2)
+        throws IllegalArgumentException {
+
+        // Make sure lengths are same
+        if (observed1.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, observed1.length, 2);
+        }
+        if (observed1.length != observed2.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                  observed1.length, observed2.length);
+        }
+
+        // Ensure non-negative counts
+        checkNonNegative(observed1);
+        checkNonNegative(observed2);
+
+        // Compute and compare count sums
+        long countSum1 = 0;
+        long countSum2 = 0;
+        boolean unequalCounts = false;
+        double weight = 0.0;
+        for (int i = 0; i < observed1.length; i++) {
+            countSum1 += observed1[i];
+            countSum2 += observed2[i];
+        }
+        // Ensure neither sample is uniformly 0
+        if (countSum1 == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OBSERVED_COUNTS_ALL_ZERO, 1);
+        }
+        if (countSum2 == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OBSERVED_COUNTS_ALL_ZERO, 2);
+        }
+        // Compare and compute weight only if different
+        unequalCounts = countSum1 != countSum2;
+        if (unequalCounts) {
+            weight = FastMath.sqrt((double) countSum1 / (double) countSum2);
+        }
+        // Compute ChiSquare statistic
+        double sumSq = 0.0d;
+        double dev = 0.0d;
+        double obs1 = 0.0d;
+        double obs2 = 0.0d;
+        for (int i = 0; i < observed1.length; i++) {
+            if (observed1[i] == 0 && observed2[i] == 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.OBSERVED_COUNTS_BOTTH_ZERO_FOR_ENTRY, i);
+            } else {
+                obs1 = observed1[i];
+                obs2 = observed2[i];
+                if (unequalCounts) { // apply weights
+                    dev = obs1/weight - obs2 * weight;
+                } else {
+                    dev = obs1 - obs2;
+                }
+                sumSq += (dev * dev) / (obs1 + obs2);
+            }
+        }
+        return sumSq;
+    }
+
+    /**
+     * @param observed1 array of observed frequency counts of the first data set
+     * @param observed2 array of observed frequency counts of the second data set
+     * @return p-value
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs computing the p-value
+     * @since 1.2
+     */
+    public double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2)
+        throws IllegalArgumentException, MathException {
+        distribution.setDegreesOfFreedom((double) observed1.length - 1);
+        return 1 - distribution.cumulativeProbability(
+                chiSquareDataSetsComparison(observed1, observed2));
+    }
+
+    /**
+     * @param observed1 array of observed frequency counts of the first data set
+     * @param observed2 array of observed frequency counts of the second data set
+     * @param alpha significance level of the test
+     * @return true iff null hypothesis can be rejected with confidence
+     * 1 - alpha
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     * @since 1.2
+     */
+    public boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2,
+            double alpha) throws IllegalArgumentException, MathException {
+        if ((alpha <= 0) || (alpha > 0.5)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL,
+                  alpha, 0.0, 0.5);
+        }
+        return chiSquareTestDataSetsComparison(observed1, observed2) < alpha;
+    }
+
+    /**
+     * Checks to make sure that the input long[][] array is rectangular,
+     * has at least 2 rows and 2 columns, and has all non-negative entries,
+     * throwing IllegalArgumentException if any of these checks fail.
+     *
+     * @param in input 2-way table to check
+     * @throws IllegalArgumentException if the array is not valid
+     */
+    private void checkArray(long[][] in) throws IllegalArgumentException {
+
+        if (in.length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, in.length, 2);
+        }
+
+        if (in[0].length < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DIMENSION, in[0].length, 2);
+        }
+
+        checkRectangular(in);
+        checkNonNegative(in);
+
+    }
+
+    //---------------------  Private array methods -- should find a utility home for these
+
+    /**
+     * Throws IllegalArgumentException if the input array is not rectangular.
+     *
+     * @param in array to be tested
+     * @throws NullPointerException if input array is null
+     * @throws IllegalArgumentException if input array is not rectangular
+     */
+    private void checkRectangular(long[][] in) {
+        for (int i = 1; i < in.length; i++) {
+            if (in[i].length != in[0].length) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                      in[i].length, in[0].length);
+            }
+        }
+    }
+
+    /**
+     * Check all entries of the input array are > 0.
+     *
+     * @param in array to be tested
+     * @exception IllegalArgumentException if one entry is not positive
+     */
+    private void checkPositive(double[] in) throws IllegalArgumentException {
+        for (int i = 0; i < in.length; i++) {
+            if (in[i] <= 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.NOT_POSITIVE_ELEMENT_AT_INDEX,
+                      i, in[i]);
+            }
+        }
+    }
+
+    /**
+     * Check all entries of the input array are >= 0.
+     *
+     * @param in array to be tested
+     * @exception IllegalArgumentException if one entry is negative
+     */
+    private void checkNonNegative(long[] in) throws IllegalArgumentException {
+        for (int i = 0; i < in.length; i++) {
+            if (in[i] < 0) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.NEGATIVE_ELEMENT_AT_INDEX,
+                      i, in[i]);
+            }
+        }
+    }
+
+    /**
+     * Check all entries of the input array are >= 0.
+     *
+     * @param in array to be tested
+     * @exception IllegalArgumentException if one entry is negative
+     */
+    private void checkNonNegative(long[][] in) throws IllegalArgumentException {
+        for (int i = 0; i < in.length; i ++) {
+            for (int j = 0; j < in[i].length; j++) {
+                if (in[i][j] < 0) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                          LocalizedFormats.NEGATIVE_ELEMENT_AT_2D_INDEX,
+                          i, j, in[i][j]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Modify the distribution used to compute inference statistics.
+     *
+     * @param value
+     *            the new distribution
+     * @since 1.2
+     */
+    public void setDistribution(ChiSquaredDistribution value) {
+        distribution = value;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/OneWayAnova.java b/src/main/java/org/apache/commons/math/stat/inference/OneWayAnova.java
new file mode 100644
index 0000000..a2cde47
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/OneWayAnova.java
@@ -0,0 +1,103 @@
+/*
+ * 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.stat.inference;
+
+import org.apache.commons.math.MathException;
+import java.util.Collection;
+
+/**
+ * An interface for one-way ANOVA (analysis of variance).
+ *
+ * <p> Tests for differences between two or more categories of univariate data
+ * (for example, the body mass index of accountants, lawyers, doctors and
+ * computer programmers).  When two categories are given, this is equivalent to
+ * the {@link org.apache.commons.math.stat.inference.TTest}.
+ * </p>
+ *
+ * @since 1.2
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ */
+public interface OneWayAnova {
+
+    /**
+     * Computes the ANOVA F-value for a collection of <code>double[]</code>
+     * arrays.
+     *
+     * <p><strong>Preconditions</strong>: <ul>
+     * <li>The categoryData <code>Collection</code> must contain
+     * <code>double[]</code> arrays.</li>
+     * <li> There must be at least two <code>double[]</code> arrays in the
+     * <code>categoryData</code> collection and each of these arrays must
+     * contain at least two values.</li></ul></p>
+     *
+     * @param categoryData <code>Collection</code> of <code>double[]</code>
+     * arrays each containing data for one category
+     * @return Fvalue
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if the statistic can not be computed do to a
+     *         convergence or other numerical error.
+     */
+    double anovaFValue(Collection<double[]> categoryData)
+        throws IllegalArgumentException, MathException;
+
+    /**
+     * Computes the ANOVA P-value for a collection of <code>double[]</code>
+     * arrays.
+     *
+     * <p><strong>Preconditions</strong>: <ul>
+     * <li>The categoryData <code>Collection</code> must contain
+     * <code>double[]</code> arrays.</li>
+     * <li> There must be at least two <code>double[]</code> arrays in the
+     * <code>categoryData</code> collection and each of these arrays must
+     * contain at least two values.</li></ul></p>
+     *
+     * @param categoryData <code>Collection</code> of <code>double[]</code>
+     * arrays each containing data for one category
+     * @return Pvalue
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if the statistic can not be computed do to a
+     *         convergence or other numerical error.
+     */
+    double anovaPValue(Collection<double[]> categoryData)
+        throws IllegalArgumentException, MathException;
+
+    /**
+     * Performs an ANOVA test, evaluating the null hypothesis that there
+     * is no difference among the means of the data categories.
+     *
+     * <p><strong>Preconditions</strong>: <ul>
+     * <li>The categoryData <code>Collection</code> must contain
+     * <code>double[]</code> arrays.</li>
+     * <li> There must be at least two <code>double[]</code> arrays in the
+     * <code>categoryData</code> collection and each of these arrays must
+     * contain at least two values.</li>
+     * <li>alpha must be strictly greater than 0 and less than or equal to 0.5.
+     * </li></ul></p>
+     *
+     * @param categoryData <code>Collection</code> of <code>double[]</code>
+     * arrays each containing data for one category
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if the statistic can not be computed do to a
+     *         convergence or other numerical error.
+     */
+    boolean anovaTest(Collection<double[]> categoryData, double alpha)
+        throws IllegalArgumentException, MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/OneWayAnovaImpl.java b/src/main/java/org/apache/commons/math/stat/inference/OneWayAnovaImpl.java
new file mode 100644
index 0000000..a47d0cf
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/OneWayAnovaImpl.java
@@ -0,0 +1,210 @@
+/*
+ * 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.stat.inference;
+
+import java.util.Collection;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.distribution.FDistribution;
+import org.apache.commons.math.distribution.FDistributionImpl;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.descriptive.summary.Sum;
+import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
+
+
+/**
+ * Implements one-way ANOVA statistics defined in the {@link OneWayAnovaImpl}
+ * interface.
+ *
+ * <p>Uses the
+ * {@link org.apache.commons.math.distribution.FDistribution
+ *  commons-math F Distribution implementation} to estimate exact p-values.</p>
+ *
+ * <p>This implementation is based on a description at
+ * http://faculty.vassar.edu/lowry/ch13pt1.html</p>
+ * <pre>
+ * Abbreviations: bg = between groups,
+ *                wg = within groups,
+ *                ss = sum squared deviations
+ * </pre>
+ *
+ * @since 1.2
+ * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $
+ */
+public class OneWayAnovaImpl implements OneWayAnova  {
+
+    /**
+     * Default constructor.
+     */
+    public OneWayAnovaImpl() {
+    }
+
+    /**
+     * {@inheritDoc}<p>
+     * This implementation computes the F statistic using the definitional
+     * formula<pre>
+     *   F = msbg/mswg</pre>
+     * where<pre>
+     *  msbg = between group mean square
+     *  mswg = within group mean square</pre>
+     * are as defined <a href="http://faculty.vassar.edu/lowry/ch13pt1.html">
+     * here</a></p>
+     */
+    public double anovaFValue(Collection<double[]> categoryData)
+        throws IllegalArgumentException, MathException {
+        AnovaStats a = anovaStats(categoryData);
+        return a.F;
+    }
+
+    /**
+     * {@inheritDoc}<p>
+     * This implementation uses the
+     * {@link org.apache.commons.math.distribution.FDistribution
+     * commons-math F Distribution implementation} to estimate the exact
+     * p-value, using the formula<pre>
+     *   p = 1 - cumulativeProbability(F)</pre>
+     * where <code>F</code> is the F value and <code>cumulativeProbability</code>
+     * is the commons-math implementation of the F distribution.</p>
+     */
+    public double anovaPValue(Collection<double[]> categoryData)
+        throws IllegalArgumentException, MathException {
+        AnovaStats a = anovaStats(categoryData);
+        FDistribution fdist = new FDistributionImpl(a.dfbg, a.dfwg);
+        return 1.0 - fdist.cumulativeProbability(a.F);
+    }
+
+    /**
+     * {@inheritDoc}<p>
+     * This implementation uses the
+     * {@link org.apache.commons.math.distribution.FDistribution
+     * commons-math F Distribution implementation} to estimate the exact
+     * p-value, using the formula<pre>
+     *   p = 1 - cumulativeProbability(F)</pre>
+     * where <code>F</code> is the F value and <code>cumulativeProbability</code>
+     * is the commons-math implementation of the F distribution.</p>
+     * <p>True is returned iff the estimated p-value is less than alpha.</p>
+     */
+    public boolean anovaTest(Collection<double[]> categoryData, double alpha)
+        throws IllegalArgumentException, MathException {
+        if ((alpha <= 0) || (alpha > 0.5)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL,
+                  alpha, 0, 0.5);
+        }
+        return anovaPValue(categoryData) < alpha;
+    }
+
+
+    /**
+     * This method actually does the calculations (except P-value).
+     *
+     * @param categoryData <code>Collection</code> of <code>double[]</code>
+     * arrays each containing data for one category
+     * @return computed AnovaStats
+     * @throws IllegalArgumentException if categoryData does not meet
+     * preconditions specified in the interface definition
+     * @throws MathException if an error occurs computing the Anova stats
+     */
+    private AnovaStats anovaStats(Collection<double[]> categoryData)
+        throws IllegalArgumentException, MathException {
+
+        // check if we have enough categories
+        if (categoryData.size() < 2) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.TWO_OR_MORE_CATEGORIES_REQUIRED,
+                  categoryData.size());
+        }
+
+        // check if each category has enough data and all is double[]
+        for (double[] array : categoryData) {
+            if (array.length <= 1) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                      LocalizedFormats.TWO_OR_MORE_VALUES_IN_CATEGORY_REQUIRED,
+                      array.length);
+            }
+        }
+
+        int dfwg = 0;
+        double sswg = 0;
+        Sum totsum = new Sum();
+        SumOfSquares totsumsq = new SumOfSquares();
+        int totnum = 0;
+
+        for (double[] data : categoryData) {
+
+            Sum sum = new Sum();
+            SumOfSquares sumsq = new SumOfSquares();
+            int num = 0;
+
+            for (int i = 0; i < data.length; i++) {
+                double val = data[i];
+
+                // within category
+                num++;
+                sum.increment(val);
+                sumsq.increment(val);
+
+                // for all categories
+                totnum++;
+                totsum.increment(val);
+                totsumsq.increment(val);
+            }
+            dfwg += num - 1;
+            double ss = sumsq.getResult() - sum.getResult() * sum.getResult() / num;
+            sswg += ss;
+        }
+        double sst = totsumsq.getResult() - totsum.getResult() *
+            totsum.getResult()/totnum;
+        double ssbg = sst - sswg;
+        int dfbg = categoryData.size() - 1;
+        double msbg = ssbg/dfbg;
+        double mswg = sswg/dfwg;
+        double F = msbg/mswg;
+
+        return new AnovaStats(dfbg, dfwg, F);
+    }
+
+    /**
+        Convenience class to pass dfbg,dfwg,F values around within AnovaImpl.
+        No get/set methods provided.
+    */
+    private static class AnovaStats {
+
+        /** Degrees of freedom in numerator (between groups). */
+        private int dfbg;
+
+        /** Degrees of freedom in denominator (within groups). */
+        private int dfwg;
+
+        /** Statistic. */
+        private double F;
+
+        /**
+         * Constructor
+         * @param dfbg degrees of freedom in numerator (between groups)
+         * @param dfwg degrees of freedom in denominator (within groups)
+         * @param F statistic
+         */
+        private AnovaStats(int dfbg, int dfwg, double F) {
+            this.dfbg = dfbg;
+            this.dfwg = dfwg;
+            this.F = F;
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/TTest.java b/src/main/java/org/apache/commons/math/stat/inference/TTest.java
new file mode 100644
index 0000000..0ccb0c0
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/TTest.java
@@ -0,0 +1,771 @@
+/*
+ * 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.stat.inference;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.stat.descriptive.StatisticalSummary;
+
+/**
+ * An interface for Student's t-tests.
+ * <p>
+ * Tests can be:<ul>
+ * <li>One-sample or two-sample</li>
+ * <li>One-sided or two-sided</li>
+ * <li>Paired or unpaired (for two-sample tests)</li>
+ * <li>Homoscedastic (equal variance assumption) or heteroscedastic
+ * (for two sample tests)</li>
+ * <li>Fixed significance level (boolean-valued) or returning p-values.
+ * </li></ul></p>
+ * <p>
+ * Test statistics are available for all tests.  Methods including "Test" in
+ * in their names perform tests, all other methods return t-statistics.  Among
+ * the "Test" methods, <code>double-</code>valued methods return p-values;
+ * <code>boolean-</code>valued methods perform fixed significance level tests.
+ * Significance levels are always specified as numbers between 0 and 0.5
+ * (e.g. tests at the 95% level  use <code>alpha=0.05</code>).</p>
+ * <p>
+ * Input to tests can be either <code>double[]</code> arrays or
+ * {@link StatisticalSummary} instances.</p>
+ *
+ *
+ * @version $Revision: 811786 $ $Date: 2009-09-06 11:36:08 +0200 (dim. 06 sept. 2009) $
+ */
+public interface TTest {
+    /**
+     * Computes a paired, 2-sample t-statistic based on the data in the input
+     * arrays.  The t-statistic returned is equivalent to what would be returned by
+     * computing the one-sample t-statistic {@link #t(double, double[])}, with
+     * <code>mu = 0</code> and the sample array consisting of the (signed)
+     * differences between corresponding entries in <code>sample1</code> and
+     * <code>sample2.</code>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The input arrays must have the same length and their common length
+     * must be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if the statistic can not be computed do to a
+     *         convergence or other numerical error.
+     */
+    double pairedT(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i> p-value</i>, associated with a paired, two-sample, two-tailed t-test
+     * based on the data in the input arrays.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the mean of the paired
+     * differences is 0 in favor of the two-sided alternative that the mean paired
+     * difference is not equal to 0. For a one-sided test, divide the returned
+     * value by 2.</p>
+     * <p>
+     * This test is equivalent to a one-sample t-test computed using
+     * {@link #tTest(double, double[])} with <code>mu = 0</code> and the sample
+     * array consisting of the signed differences between corresponding elements of
+     * <code>sample1</code> and <code>sample2.</code></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The input array lengths must be the same and their common length must
+     * be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double pairedTTest(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Performs a paired t-test evaluating the null hypothesis that the
+     * mean of the paired differences between <code>sample1</code> and
+     * <code>sample2</code> is 0 in favor of the two-sided alternative that the
+     * mean paired difference is not equal to 0, with significance level
+     * <code>alpha</code>.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis can be rejected with
+     * confidence <code>1 - alpha</code>.  To perform a 1-sided test, use
+     * <code>alpha * 2</code></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The input array lengths must be the same and their common length
+     * must be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean pairedTTest(
+        double[] sample1,
+        double[] sample2,
+        double alpha)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
+     * t statistic </a> given observed values and a comparison constant.
+     * <p>
+     * This statistic can be used to perform a one sample t-test for the mean.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array length must be at least 2.
+     * </li></ul></p>
+     *
+     * @param mu comparison constant
+     * @param observed array of values
+     * @return t statistic
+     * @throws IllegalArgumentException if input array length is less than 2
+     */
+    double t(double mu, double[] observed)
+        throws IllegalArgumentException;
+    /**
+     * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
+     * t statistic </a> to use in comparing the mean of the dataset described by
+     * <code>sampleStats</code> to <code>mu</code>.
+     * <p>
+     * This statistic can be used to perform a one sample t-test for the mean.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li><code>observed.getN() > = 2</code>.
+     * </li></ul></p>
+     *
+     * @param mu comparison constant
+     * @param sampleStats DescriptiveStatistics holding sample summary statitstics
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    double t(double mu, StatisticalSummary sampleStats)
+        throws IllegalArgumentException;
+    /**
+     * Computes a 2-sample t statistic,  under the hypothesis of equal
+     * subpopulation variances.  To compute a t-statistic without the
+     * equal variances hypothesis, use {@link #t(double[], double[])}.
+     * <p>
+     * This statistic can be used to perform a (homoscedastic) two-sample
+     * t-test to compare sample means.</p>
+     * <p>
+     * The t-statisitc is</p>
+     * <p>
+     * &nbsp;&nbsp;<code>  t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
+     * </p><p>
+     * where <strong><code>n1</code></strong> is the size of first sample;
+     * <strong><code> n2</code></strong> is the size of second sample;
+     * <strong><code> m1</code></strong> is the mean of first sample;
+     * <strong><code> m2</code></strong> is the mean of second sample</li>
+     * </ul>
+     * and <strong><code>var</code></strong> is the pooled variance estimate:
+     * </p><p>
+     * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
+     * </p><p>
+     * with <strong><code>var1<code></strong> the variance of the first sample and
+     * <strong><code>var2</code></strong> the variance of the second sample.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    double homoscedasticT(double[] sample1, double[] sample2)
+        throws IllegalArgumentException;
+    /**
+     * Computes a 2-sample t statistic, without the hypothesis of equal
+     * subpopulation variances.  To compute a t-statistic assuming equal
+     * variances, use {@link #homoscedasticT(double[], double[])}.
+     * <p>
+     * This statistic can be used to perform a two-sample t-test to compare
+     * sample means.</p>
+     * <p>
+     * The t-statisitc is</p>
+     * <p>
+     * &nbsp;&nbsp; <code>  t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
+     * </p><p>
+     *  where <strong><code>n1</code></strong> is the size of the first sample
+     * <strong><code> n2</code></strong> is the size of the second sample;
+     * <strong><code> m1</code></strong> is the mean of the first sample;
+     * <strong><code> m2</code></strong> is the mean of the second sample;
+     * <strong><code> var1</code></strong> is the variance of the first sample;
+     * <strong><code> var2</code></strong> is the variance of the second sample;
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    double t(double[] sample1, double[] sample2)
+        throws IllegalArgumentException;
+    /**
+     * Computes a 2-sample t statistic </a>, comparing the means of the datasets
+     * described by two {@link StatisticalSummary} instances, without the
+     * assumption of equal subpopulation variances.  Use
+     * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to
+     * compute a t-statistic under the equal variances assumption.
+     * <p>
+     * This statistic can be used to perform a two-sample t-test to compare
+     * sample means.</p>
+     * <p>
+      * The returned  t-statisitc is</p>
+     * <p>
+     * &nbsp;&nbsp; <code>  t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
+     * </p><p>
+     * where <strong><code>n1</code></strong> is the size of the first sample;
+     * <strong><code> n2</code></strong> is the size of the second sample;
+     * <strong><code> m1</code></strong> is the mean of the first sample;
+     * <strong><code> m2</code></strong> is the mean of the second sample
+     * <strong><code> var1</code></strong> is the variance of the first sample;
+     * <strong><code> var2</code></strong> is the variance of the second sample
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1 StatisticalSummary describing data from the first sample
+     * @param sampleStats2 StatisticalSummary describing data from the second sample
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    double t(
+        StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException;
+    /**
+     * Computes a 2-sample t statistic, comparing the means of the datasets
+     * described by two {@link StatisticalSummary} instances, under the
+     * assumption of equal subpopulation variances.  To compute a t-statistic
+     * without the equal variances assumption, use
+     * {@link #t(StatisticalSummary, StatisticalSummary)}.
+     * <p>
+     * This statistic can be used to perform a (homoscedastic) two-sample
+     * t-test to compare sample means.</p>
+     * <p>
+     * The t-statisitc returned is</p>
+     * <p>
+     * &nbsp;&nbsp;<code>  t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
+     * </p><p>
+     * where <strong><code>n1</code></strong> is the size of first sample;
+     * <strong><code> n2</code></strong> is the size of second sample;
+     * <strong><code> m1</code></strong> is the mean of first sample;
+     * <strong><code> m2</code></strong> is the mean of second sample
+     * and <strong><code>var</code></strong> is the pooled variance estimate:
+     * </p><p>
+     * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
+     * </p><p>
+     * with <strong><code>var1<code></strong> the variance of the first sample and
+     * <strong><code>var2</code></strong> the variance of the second sample.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1 StatisticalSummary describing data from the first sample
+     * @param sampleStats2 StatisticalSummary describing data from the second sample
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    double homoscedasticT(
+        StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a one-sample, two-tailed t-test
+     * comparing the mean of the input array with the constant <code>mu</code>.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the mean equals
+     * <code>mu</code> in favor of the two-sided alternative that the mean
+     * is different from <code>mu</code>. For a one-sided test, divide the
+     * returned value by 2.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array length must be at least 2.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sample array of sample data values
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double tTest(double mu, double[] sample)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that the mean of the population from
+     * which <code>sample</code> is drawn equals <code>mu</code>.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis can be
+     * rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2</code></p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
+     * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
+     * at the 99% level, first verify that the measured sample mean is less
+     * than <code>mu</code> and then use
+     * <br><code>tTest(mu, sample, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the one-sample
+     * parametric t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array length must be at least 2.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sample array of sample data values
+     * @param alpha significance level of the test
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error computing the p-value
+     */
+    boolean tTest(double mu, double[] sample, double alpha)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a one-sample, two-tailed t-test
+     * comparing the mean of the dataset described by <code>sampleStats</code>
+     * with the constant <code>mu</code>.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the mean equals
+     * <code>mu</code> in favor of the two-sided alternative that the mean
+     * is different from <code>mu</code>. For a one-sided test, divide the
+     * returned value by 2.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The sample must contain at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sampleStats StatisticalSummary describing sample data
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double tTest(double mu, StatisticalSummary sampleStats)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that the mean of the
+     * population from which the dataset described by <code>stats</code> is
+     * drawn equals <code>mu</code>.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis can be rejected with
+     * confidence <code>1 - alpha</code>.  To  perform a 1-sided test, use
+     * <code>alpha * 2.</code></p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
+     * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
+     * at the 99% level, first verify that the measured sample mean is less
+     * than <code>mu</code> and then use
+     * <br><code>tTest(mu, sampleStats, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the one-sample
+     * parametric t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The sample must include at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sampleStats StatisticalSummary describing sample data values
+     * @param alpha significance level of the test
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    boolean tTest(
+        double mu,
+        StatisticalSummary sampleStats,
+        double alpha)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the input arrays.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * The test does not assume that the underlying popuation variances are
+     * equal  and it uses approximated degrees of freedom computed from the
+     * sample data to compute the p-value.  The t-statistic used is as defined in
+     * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation
+     * to the degrees of freedom is used,
+     * as described
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
+     * here.</a>  To perform the test under the assumption of equal subpopulation
+     * variances, use {@link #homoscedasticTTest(double[], double[])}.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double tTest(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the input arrays, under the assumption that
+     * the two samples are drawn from subpopulations with equal variances.
+     * To perform the test without the equal variances assumption, use
+     * {@link #tTest(double[], double[])}.</p>
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * A pooled variance estimate is used to compute the t-statistic.  See
+     * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes
+     * minus 2 is used as the degrees of freedom.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double homoscedasticTTest(
+        double[] sample1,
+        double[] sample2)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Performs a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
+     * and <code>sample2</code> are drawn from populations with the same mean,
+     * with significance level <code>alpha</code>.  This test does not assume
+     * that the subpopulation variances are equal.  To perform the test assuming
+     * equal variances, use
+     * {@link #homoscedasticTTest(double[], double[], double)}.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis that the means are
+     * equal can be rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2</code></p>
+     * <p>
+     * See {@link #t(double[], double[])} for the formula used to compute the
+     * t-statistic.  Degrees of freedom are approximated using the
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
+     * Welch-Satterthwaite approximation.</a></p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+     * the 95% level,  use
+     * <br><code>tTest(sample1, sample2, 0.05). </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>,
+     * at the 99% level, first verify that the measured  mean of <code>sample 1</code>
+     * is less than the mean of <code>sample 2</code> and then use
+     * <br><code>tTest(sample1, sample2, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean tTest(
+        double[] sample1,
+        double[] sample2,
+        double alpha)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Performs a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
+     * and <code>sample2</code> are drawn from populations with the same mean,
+     * with significance level <code>alpha</code>,  assuming that the
+     * subpopulation variances are equal.  Use
+     * {@link #tTest(double[], double[], double)} to perform the test without
+     * the assumption of equal variances.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis that the means are
+     * equal can be rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2.</code>  To perform the test
+     * without the assumption of equal subpopulation variances, use
+     * {@link #tTest(double[], double[], double)}.</p>
+     * <p>
+     * A pooled variance estimate is used to compute the t-statistic. See
+     * {@link #t(double[], double[])} for the formula. The sum of the sample
+     * sizes minus 2 is used as the degrees of freedom.</p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+     * the 95% level, use <br><code>tTest(sample1, sample2, 0.05). </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2, </code>
+     * at the 99% level, first verify that the measured mean of
+     * <code>sample 1</code> is less than the mean of <code>sample 2</code>
+     * and then use
+     * <br><code>tTest(sample1, sample2, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean homoscedasticTTest(
+        double[] sample1,
+        double[] sample2,
+        double alpha)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the datasets described by two StatisticalSummary
+     * instances.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * The test does not assume that the underlying popuation variances are
+     * equal  and it uses approximated degrees of freedom computed from the
+     * sample data to compute the p-value.   To perform the test assuming
+     * equal variances, use
+     * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1  StatisticalSummary describing data from the first sample
+     * @param sampleStats2  StatisticalSummary describing data from the second sample
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double tTest(
+        StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the datasets described by two StatisticalSummary
+     * instances, under the hypothesis of equal subpopulation variances. To
+     * perform a test without the equal variances assumption, use
+     * {@link #tTest(StatisticalSummary, StatisticalSummary)}.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * See {@link #homoscedasticT(double[], double[])} for the formula used to
+     * compute the t-statistic. The sum of the  sample sizes minus 2 is used as
+     * the degrees of freedom.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1  StatisticalSummary describing data from the first sample
+     * @param sampleStats2  StatisticalSummary describing data from the second sample
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double homoscedasticTTest(
+        StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException, MathException;
+    /**
+     * Performs a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that
+     * <code>sampleStats1</code> and <code>sampleStats2</code> describe
+     * datasets drawn from populations with the same mean, with significance
+     * level <code>alpha</code>.   This test does not assume that the
+     * subpopulation variances are equal.  To perform the test under the equal
+     * variances assumption, use
+     * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis that the means are
+     * equal can be rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2</code></p>
+     * <p>
+     * See {@link #t(double[], double[])} for the formula used to compute the
+     * t-statistic.  Degrees of freedom are approximated using the
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
+     * Welch-Satterthwaite approximation.</a></p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+     * the 95%, use
+     * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>
+     * at the 99% level,  first verify that the measured mean of
+     * <code>sample 1</code> is less than  the mean of <code>sample 2</code>
+     * and then use
+     * <br><code>tTest(sampleStats1, sampleStats2, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sampleStats1 StatisticalSummary describing sample data values
+     * @param sampleStats2 StatisticalSummary describing sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean tTest(
+        StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2,
+        double alpha)
+        throws IllegalArgumentException, MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java b/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java
new file mode 100644
index 0000000..d4d1a12
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/TTestImpl.java
@@ -0,0 +1,1069 @@
+/*
+ * 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.stat.inference;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.distribution.TDistribution;
+import org.apache.commons.math.distribution.TDistributionImpl;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.stat.StatUtils;
+import org.apache.commons.math.stat.descriptive.StatisticalSummary;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements t-test statistics defined in the {@link TTest} interface.
+ * <p>
+ * Uses commons-math {@link org.apache.commons.math.distribution.TDistributionImpl}
+ * implementation to estimate exact p-values.</p>
+ *
+ * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $
+ */
+public class TTestImpl implements TTest  {
+
+    /** Distribution used to compute inference statistics.
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    private TDistribution distribution;
+
+    /**
+     * Default constructor.
+     */
+    public TTestImpl() {
+        this(new TDistributionImpl(1.0));
+    }
+
+    /**
+     * Create a test instance using the given distribution for computing
+     * inference statistics.
+     * @param t distribution used to compute inference statistics.
+     * @since 1.2
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public TTestImpl(TDistribution t) {
+        super();
+        setDistribution(t);
+    }
+
+    /**
+     * Computes a paired, 2-sample t-statistic based on the data in the input
+     * arrays.  The t-statistic returned is equivalent to what would be returned by
+     * computing the one-sample t-statistic {@link #t(double, double[])}, with
+     * <code>mu = 0</code> and the sample array consisting of the (signed)
+     * differences between corresponding entries in <code>sample1</code> and
+     * <code>sample2.</code>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The input arrays must have the same length and their common length
+     * must be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if the statistic can not be computed do to a
+     *         convergence or other numerical error.
+     */
+    public double pairedT(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException {
+        checkSampleData(sample1);
+        checkSampleData(sample2);
+        double meanDifference = StatUtils.meanDifference(sample1, sample2);
+        return t(meanDifference, 0,
+                StatUtils.varianceDifference(sample1, sample2, meanDifference),
+                sample1.length);
+    }
+
+     /**
+     * Returns the <i>observed significance level</i>, or
+     * <i> p-value</i>, associated with a paired, two-sample, two-tailed t-test
+     * based on the data in the input arrays.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the mean of the paired
+     * differences is 0 in favor of the two-sided alternative that the mean paired
+     * difference is not equal to 0. For a one-sided test, divide the returned
+     * value by 2.</p>
+     * <p>
+     * This test is equivalent to a one-sample t-test computed using
+     * {@link #tTest(double, double[])} with <code>mu = 0</code> and the sample
+     * array consisting of the signed differences between corresponding elements of
+     * <code>sample1</code> and <code>sample2.</code></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The input array lengths must be the same and their common length must
+     * be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double pairedTTest(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException {
+        double meanDifference = StatUtils.meanDifference(sample1, sample2);
+        return tTest(meanDifference, 0,
+                StatUtils.varianceDifference(sample1, sample2, meanDifference),
+                sample1.length);
+    }
+
+     /**
+     * Performs a paired t-test evaluating the null hypothesis that the
+     * mean of the paired differences between <code>sample1</code> and
+     * <code>sample2</code> is 0 in favor of the two-sided alternative that the
+     * mean paired difference is not equal to 0, with significance level
+     * <code>alpha</code>.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis can be rejected with
+     * confidence <code>1 - alpha</code>.  To perform a 1-sided test, use
+     * <code>alpha * 2</code></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The input array lengths must be the same and their common length
+     * must be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    public boolean pairedTTest(double[] sample1, double[] sample2, double alpha)
+        throws IllegalArgumentException, MathException {
+        checkSignificanceLevel(alpha);
+        return pairedTTest(sample1, sample2) < alpha;
+    }
+
+    /**
+     * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
+     * t statistic </a> given observed values and a comparison constant.
+     * <p>
+     * This statistic can be used to perform a one sample t-test for the mean.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array length must be at least 2.
+     * </li></ul></p>
+     *
+     * @param mu comparison constant
+     * @param observed array of values
+     * @return t statistic
+     * @throws IllegalArgumentException if input array length is less than 2
+     */
+    public double t(double mu, double[] observed)
+    throws IllegalArgumentException {
+        checkSampleData(observed);
+        return t(StatUtils.mean(observed), mu, StatUtils.variance(observed),
+                observed.length);
+    }
+
+    /**
+     * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula">
+     * t statistic </a> to use in comparing the mean of the dataset described by
+     * <code>sampleStats</code> to <code>mu</code>.
+     * <p>
+     * This statistic can be used to perform a one sample t-test for the mean.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li><code>observed.getN() > = 2</code>.
+     * </li></ul></p>
+     *
+     * @param mu comparison constant
+     * @param sampleStats DescriptiveStatistics holding sample summary statitstics
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    public double t(double mu, StatisticalSummary sampleStats)
+    throws IllegalArgumentException {
+        checkSampleData(sampleStats);
+        return t(sampleStats.getMean(), mu, sampleStats.getVariance(),
+                sampleStats.getN());
+    }
+
+    /**
+     * Computes a 2-sample t statistic,  under the hypothesis of equal
+     * subpopulation variances.  To compute a t-statistic without the
+     * equal variances hypothesis, use {@link #t(double[], double[])}.
+     * <p>
+     * This statistic can be used to perform a (homoscedastic) two-sample
+     * t-test to compare sample means.</p>
+     * <p>
+     * The t-statisitc is</p>
+     * <p>
+     * &nbsp;&nbsp;<code>  t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
+     * </p><p>
+     * where <strong><code>n1</code></strong> is the size of first sample;
+     * <strong><code> n2</code></strong> is the size of second sample;
+     * <strong><code> m1</code></strong> is the mean of first sample;
+     * <strong><code> m2</code></strong> is the mean of second sample</li>
+     * </ul>
+     * and <strong><code>var</code></strong> is the pooled variance estimate:
+     * </p><p>
+     * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
+     * </p><p>
+     * with <strong><code>var1<code></strong> the variance of the first sample and
+     * <strong><code>var2</code></strong> the variance of the second sample.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    public double homoscedasticT(double[] sample1, double[] sample2)
+    throws IllegalArgumentException {
+        checkSampleData(sample1);
+        checkSampleData(sample2);
+        return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2),
+                StatUtils.variance(sample1), StatUtils.variance(sample2),
+                sample1.length, sample2.length);
+    }
+
+    /**
+     * Computes a 2-sample t statistic, without the hypothesis of equal
+     * subpopulation variances.  To compute a t-statistic assuming equal
+     * variances, use {@link #homoscedasticT(double[], double[])}.
+     * <p>
+     * This statistic can be used to perform a two-sample t-test to compare
+     * sample means.</p>
+     * <p>
+     * The t-statisitc is</p>
+     * <p>
+     * &nbsp;&nbsp; <code>  t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
+     * </p><p>
+     *  where <strong><code>n1</code></strong> is the size of the first sample
+     * <strong><code> n2</code></strong> is the size of the second sample;
+     * <strong><code> m1</code></strong> is the mean of the first sample;
+     * <strong><code> m2</code></strong> is the mean of the second sample;
+     * <strong><code> var1</code></strong> is the variance of the first sample;
+     * <strong><code> var2</code></strong> is the variance of the second sample;
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    public double t(double[] sample1, double[] sample2)
+    throws IllegalArgumentException {
+        checkSampleData(sample1);
+        checkSampleData(sample2);
+        return t(StatUtils.mean(sample1), StatUtils.mean(sample2),
+                StatUtils.variance(sample1), StatUtils.variance(sample2),
+                sample1.length, sample2.length);
+    }
+
+    /**
+     * Computes a 2-sample t statistic </a>, comparing the means of the datasets
+     * described by two {@link StatisticalSummary} instances, without the
+     * assumption of equal subpopulation variances.  Use
+     * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to
+     * compute a t-statistic under the equal variances assumption.
+     * <p>
+     * This statistic can be used to perform a two-sample t-test to compare
+     * sample means.</p>
+     * <p>
+      * The returned  t-statisitc is</p>
+     * <p>
+     * &nbsp;&nbsp; <code>  t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code>
+     * </p><p>
+     * where <strong><code>n1</code></strong> is the size of the first sample;
+     * <strong><code> n2</code></strong> is the size of the second sample;
+     * <strong><code> m1</code></strong> is the mean of the first sample;
+     * <strong><code> m2</code></strong> is the mean of the second sample
+     * <strong><code> var1</code></strong> is the variance of the first sample;
+     * <strong><code> var2</code></strong> is the variance of the second sample
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1 StatisticalSummary describing data from the first sample
+     * @param sampleStats2 StatisticalSummary describing data from the second sample
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    public double t(StatisticalSummary sampleStats1,
+                    StatisticalSummary sampleStats2)
+    throws IllegalArgumentException {
+        checkSampleData(sampleStats1);
+        checkSampleData(sampleStats2);
+        return t(sampleStats1.getMean(), sampleStats2.getMean(),
+                sampleStats1.getVariance(), sampleStats2.getVariance(),
+                sampleStats1.getN(), sampleStats2.getN());
+    }
+
+    /**
+     * Computes a 2-sample t statistic, comparing the means of the datasets
+     * described by two {@link StatisticalSummary} instances, under the
+     * assumption of equal subpopulation variances.  To compute a t-statistic
+     * without the equal variances assumption, use
+     * {@link #t(StatisticalSummary, StatisticalSummary)}.
+     * <p>
+     * This statistic can be used to perform a (homoscedastic) two-sample
+     * t-test to compare sample means.</p>
+     * <p>
+     * The t-statisitc returned is</p>
+     * <p>
+     * &nbsp;&nbsp;<code>  t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code>
+     * </p><p>
+     * where <strong><code>n1</code></strong> is the size of first sample;
+     * <strong><code> n2</code></strong> is the size of second sample;
+     * <strong><code> m1</code></strong> is the mean of first sample;
+     * <strong><code> m2</code></strong> is the mean of second sample
+     * and <strong><code>var</code></strong> is the pooled variance estimate:
+     * </p><p>
+     * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code>
+     * <p>
+     * with <strong><code>var1<code></strong> the variance of the first sample and
+     * <strong><code>var2</code></strong> the variance of the second sample.
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1 StatisticalSummary describing data from the first sample
+     * @param sampleStats2 StatisticalSummary describing data from the second sample
+     * @return t statistic
+     * @throws IllegalArgumentException if the precondition is not met
+     */
+    public double homoscedasticT(StatisticalSummary sampleStats1,
+            StatisticalSummary sampleStats2)
+    throws IllegalArgumentException {
+        checkSampleData(sampleStats1);
+        checkSampleData(sampleStats2);
+        return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(),
+                sampleStats1.getVariance(), sampleStats2.getVariance(),
+                sampleStats1.getN(), sampleStats2.getN());
+    }
+
+     /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a one-sample, two-tailed t-test
+     * comparing the mean of the input array with the constant <code>mu</code>.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the mean equals
+     * <code>mu</code> in favor of the two-sided alternative that the mean
+     * is different from <code>mu</code>. For a one-sided test, divide the
+     * returned value by 2.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array length must be at least 2.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sample array of sample data values
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double tTest(double mu, double[] sample)
+    throws IllegalArgumentException, MathException {
+        checkSampleData(sample);
+        return tTest( StatUtils.mean(sample), mu, StatUtils.variance(sample),
+                sample.length);
+    }
+
+    /**
+     * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that the mean of the population from
+     * which <code>sample</code> is drawn equals <code>mu</code>.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis can be
+     * rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2</code>
+     * </p><p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
+     * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
+     * at the 99% level, first verify that the measured sample mean is less
+     * than <code>mu</code> and then use
+     * <br><code>tTest(mu, sample, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the one-sample
+     * parametric t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array length must be at least 2.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sample array of sample data values
+     * @param alpha significance level of the test
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error computing the p-value
+     */
+    public boolean tTest(double mu, double[] sample, double alpha)
+    throws IllegalArgumentException, MathException {
+        checkSignificanceLevel(alpha);
+        return tTest(mu, sample) < alpha;
+    }
+
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a one-sample, two-tailed t-test
+     * comparing the mean of the dataset described by <code>sampleStats</code>
+     * with the constant <code>mu</code>.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the mean equals
+     * <code>mu</code> in favor of the two-sided alternative that the mean
+     * is different from <code>mu</code>. For a one-sided test, divide the
+     * returned value by 2.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The sample must contain at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sampleStats StatisticalSummary describing sample data
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double tTest(double mu, StatisticalSummary sampleStats)
+    throws IllegalArgumentException, MathException {
+        checkSampleData(sampleStats);
+        return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(),
+                sampleStats.getN());
+    }
+
+     /**
+     * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that the mean of the
+     * population from which the dataset described by <code>stats</code> is
+     * drawn equals <code>mu</code>.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis can be rejected with
+     * confidence <code>1 - alpha</code>.  To  perform a 1-sided test, use
+     * <code>alpha * 2.</code></p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at
+     * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code>
+     * at the 99% level, first verify that the measured sample mean is less
+     * than <code>mu</code> and then use
+     * <br><code>tTest(mu, sampleStats, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the one-sample
+     * parametric t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The sample must include at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param mu constant value to compare sample mean against
+     * @param sampleStats StatisticalSummary describing sample data values
+     * @param alpha significance level of the test
+     * @return p-value
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public boolean tTest( double mu, StatisticalSummary sampleStats,
+            double alpha)
+    throws IllegalArgumentException, MathException {
+        checkSignificanceLevel(alpha);
+        return tTest(mu, sampleStats) < alpha;
+    }
+
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the input arrays.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * The test does not assume that the underlying popuation variances are
+     * equal  and it uses approximated degrees of freedom computed from the
+     * sample data to compute the p-value.  The t-statistic used is as defined in
+     * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation
+     * to the degrees of freedom is used,
+     * as described
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
+     * here.</a>  To perform the test under the assumption of equal subpopulation
+     * variances, use {@link #homoscedasticTTest(double[], double[])}.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double tTest(double[] sample1, double[] sample2)
+    throws IllegalArgumentException, MathException {
+        checkSampleData(sample1);
+        checkSampleData(sample2);
+        return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2),
+                StatUtils.variance(sample1), StatUtils.variance(sample2),
+                sample1.length, sample2.length);
+    }
+
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the input arrays, under the assumption that
+     * the two samples are drawn from subpopulations with equal variances.
+     * To perform the test without the equal variances assumption, use
+     * {@link #tTest(double[], double[])}.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * A pooled variance estimate is used to compute the t-statistic.  See
+     * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes
+     * minus 2 is used as the degrees of freedom.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double homoscedasticTTest(double[] sample1, double[] sample2)
+    throws IllegalArgumentException, MathException {
+        checkSampleData(sample1);
+        checkSampleData(sample2);
+        return homoscedasticTTest(StatUtils.mean(sample1),
+                StatUtils.mean(sample2), StatUtils.variance(sample1),
+                StatUtils.variance(sample2), sample1.length,
+                sample2.length);
+    }
+
+
+     /**
+     * Performs a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
+     * and <code>sample2</code> are drawn from populations with the same mean,
+     * with significance level <code>alpha</code>.  This test does not assume
+     * that the subpopulation variances are equal.  To perform the test assuming
+     * equal variances, use
+     * {@link #homoscedasticTTest(double[], double[], double)}.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis that the means are
+     * equal can be rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha / 2</code></p>
+     * <p>
+     * See {@link #t(double[], double[])} for the formula used to compute the
+     * t-statistic.  Degrees of freedom are approximated using the
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
+     * Welch-Satterthwaite approximation.</a></p>
+
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+     * the 95% level,  use
+     * <br><code>tTest(sample1, sample2, 0.05). </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code> at
+     * the 99% level, first verify that the measured  mean of <code>sample 1</code>
+     * is less than the mean of <code>sample 2</code> and then use
+     * <br><code>tTest(sample1, sample2, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    public boolean tTest(double[] sample1, double[] sample2,
+            double alpha)
+    throws IllegalArgumentException, MathException {
+        checkSignificanceLevel(alpha);
+        return tTest(sample1, sample2) < alpha;
+    }
+
+    /**
+     * Performs a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code>
+     * and <code>sample2</code> are drawn from populations with the same mean,
+     * with significance level <code>alpha</code>,  assuming that the
+     * subpopulation variances are equal.  Use
+     * {@link #tTest(double[], double[], double)} to perform the test without
+     * the assumption of equal variances.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis that the means are
+     * equal can be rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2.</code>  To perform the test
+     * without the assumption of equal subpopulation variances, use
+     * {@link #tTest(double[], double[], double)}.</p>
+     * <p>
+     * A pooled variance estimate is used to compute the t-statistic. See
+     * {@link #t(double[], double[])} for the formula. The sum of the sample
+     * sizes minus 2 is used as the degrees of freedom.</p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+     * the 95% level, use <br><code>tTest(sample1, sample2, 0.05). </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2, </code>
+     * at the 99% level, first verify that the measured mean of
+     * <code>sample 1</code> is less than the mean of <code>sample 2</code>
+     * and then use
+     * <br><code>tTest(sample1, sample2, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The observed array lengths must both be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sample1 array of sample data values
+     * @param sample2 array of sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    public boolean homoscedasticTTest(double[] sample1, double[] sample2,
+            double alpha)
+    throws IllegalArgumentException, MathException {
+        checkSignificanceLevel(alpha);
+        return homoscedasticTTest(sample1, sample2) < alpha;
+    }
+
+     /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the datasets described by two StatisticalSummary
+     * instances.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * The test does not assume that the underlying popuation variances are
+     * equal  and it uses approximated degrees of freedom computed from the
+     * sample data to compute the p-value.   To perform the test assuming
+     * equal variances, use
+     * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1  StatisticalSummary describing data from the first sample
+     * @param sampleStats2  StatisticalSummary describing data from the second sample
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2)
+    throws IllegalArgumentException, MathException {
+        checkSampleData(sampleStats1);
+        checkSampleData(sampleStats2);
+        return tTest(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(),
+                sampleStats2.getVariance(), sampleStats1.getN(),
+                sampleStats2.getN());
+    }
+
+    /**
+     * Returns the <i>observed significance level</i>, or
+     * <i>p-value</i>, associated with a two-sample, two-tailed t-test
+     * comparing the means of the datasets described by two StatisticalSummary
+     * instances, under the hypothesis of equal subpopulation variances. To
+     * perform a test without the equal variances assumption, use
+     * {@link #tTest(StatisticalSummary, StatisticalSummary)}.
+     * <p>
+     * The number returned is the smallest significance level
+     * at which one can reject the null hypothesis that the two means are
+     * equal in favor of the two-sided alternative that they are different.
+     * For a one-sided test, divide the returned value by 2.</p>
+     * <p>
+     * See {@link #homoscedasticT(double[], double[])} for the formula used to
+     * compute the t-statistic. The sum of the  sample sizes minus 2 is used as
+     * the degrees of freedom.</p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the p-value depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a>
+     * </p><p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li></ul></p>
+     *
+     * @param sampleStats1  StatisticalSummary describing data from the first sample
+     * @param sampleStats2  StatisticalSummary describing data from the second sample
+     * @return p-value for t-test
+     * @throws IllegalArgumentException if the precondition is not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    public double homoscedasticTTest(StatisticalSummary sampleStats1,
+                                     StatisticalSummary sampleStats2)
+    throws IllegalArgumentException, MathException {
+        checkSampleData(sampleStats1);
+        checkSampleData(sampleStats2);
+        return homoscedasticTTest(sampleStats1.getMean(),
+                sampleStats2.getMean(), sampleStats1.getVariance(),
+                sampleStats2.getVariance(), sampleStats1.getN(),
+                sampleStats2.getN());
+    }
+
+    /**
+     * Performs a
+     * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm">
+     * two-sided t-test</a> evaluating the null hypothesis that
+     * <code>sampleStats1</code> and <code>sampleStats2</code> describe
+     * datasets drawn from populations with the same mean, with significance
+     * level <code>alpha</code>.   This test does not assume that the
+     * subpopulation variances are equal.  To perform the test under the equal
+     * variances assumption, use
+     * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.
+     * <p>
+     * Returns <code>true</code> iff the null hypothesis that the means are
+     * equal can be rejected with confidence <code>1 - alpha</code>.  To
+     * perform a 1-sided test, use <code>alpha * 2</code></p>
+     * <p>
+     * See {@link #t(double[], double[])} for the formula used to compute the
+     * t-statistic.  Degrees of freedom are approximated using the
+     * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm">
+     * Welch-Satterthwaite approximation.</a></p>
+     * <p>
+     * <strong>Examples:</strong><br><ol>
+     * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at
+     * the 95%, use
+     * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code>
+     * </li>
+     * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>
+     * at the 99% level,  first verify that the measured mean of
+     * <code>sample 1</code> is less than  the mean of <code>sample 2</code>
+     * and then use
+     * <br><code>tTest(sampleStats1, sampleStats2, 0.02) </code>
+     * </li></ol></p>
+     * <p>
+     * <strong>Usage Note:</strong><br>
+     * The validity of the test depends on the assumptions of the parametric
+     * t-test procedure, as discussed
+     * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">
+     * here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>The datasets described by the two Univariates must each contain
+     * at least 2 observations.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul></p>
+     *
+     * @param sampleStats1 StatisticalSummary describing sample data values
+     * @param sampleStats2 StatisticalSummary describing sample data values
+     * @param alpha significance level of the test
+     * @return true if the null hypothesis can be rejected with
+     * confidence 1 - alpha
+     * @throws IllegalArgumentException if the preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    public boolean tTest(StatisticalSummary sampleStats1,
+            StatisticalSummary sampleStats2, double alpha)
+    throws IllegalArgumentException, MathException {
+        checkSignificanceLevel(alpha);
+        return tTest(sampleStats1, sampleStats2) < alpha;
+    }
+
+    //----------------------------------------------- Protected methods
+
+    /**
+     * Computes approximate degrees of freedom for 2-sample t-test.
+     *
+     * @param v1 first sample variance
+     * @param v2 second sample variance
+     * @param n1 first sample n
+     * @param n2 second sample n
+     * @return approximate degrees of freedom
+     */
+    protected double df(double v1, double v2, double n1, double n2) {
+        return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) /
+        ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) /
+                (n2 * n2 * (n2 - 1d)));
+    }
+
+    /**
+     * Computes t test statistic for 1-sample t-test.
+     *
+     * @param m sample mean
+     * @param mu constant to test against
+     * @param v sample variance
+     * @param n sample n
+     * @return t test statistic
+     */
+    protected double t(double m, double mu, double v, double n) {
+        return (m - mu) / FastMath.sqrt(v / n);
+    }
+
+    /**
+     * Computes t test statistic for 2-sample t-test.
+     * <p>
+     * Does not assume that subpopulation variances are equal.</p>
+     *
+     * @param m1 first sample mean
+     * @param m2 second sample mean
+     * @param v1 first sample variance
+     * @param v2 second sample variance
+     * @param n1 first sample n
+     * @param n2 second sample n
+     * @return t test statistic
+     */
+    protected double t(double m1, double m2,  double v1, double v2, double n1,
+            double n2)  {
+            return (m1 - m2) / FastMath.sqrt((v1 / n1) + (v2 / n2));
+    }
+
+    /**
+     * Computes t test statistic for 2-sample t-test under the hypothesis
+     * of equal subpopulation variances.
+     *
+     * @param m1 first sample mean
+     * @param m2 second sample mean
+     * @param v1 first sample variance
+     * @param v2 second sample variance
+     * @param n1 first sample n
+     * @param n2 second sample n
+     * @return t test statistic
+     */
+    protected double homoscedasticT(double m1, double m2,  double v1,
+            double v2, double n1, double n2)  {
+            double pooledVariance = ((n1  - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2);
+            return (m1 - m2) / FastMath.sqrt(pooledVariance * (1d / n1 + 1d / n2));
+    }
+
+    /**
+     * Computes p-value for 2-sided, 1-sample t-test.
+     *
+     * @param m sample mean
+     * @param mu constant to test against
+     * @param v sample variance
+     * @param n sample n
+     * @return p-value
+     * @throws MathException if an error occurs computing the p-value
+     */
+    protected double tTest(double m, double mu, double v, double n)
+    throws MathException {
+        double t = FastMath.abs(t(m, mu, v, n));
+        distribution.setDegreesOfFreedom(n - 1);
+        return 2.0 * distribution.cumulativeProbability(-t);
+    }
+
+    /**
+     * Computes p-value for 2-sided, 2-sample t-test.
+     * <p>
+     * Does not assume subpopulation variances are equal. Degrees of freedom
+     * are estimated from the data.</p>
+     *
+     * @param m1 first sample mean
+     * @param m2 second sample mean
+     * @param v1 first sample variance
+     * @param v2 second sample variance
+     * @param n1 first sample n
+     * @param n2 second sample n
+     * @return p-value
+     * @throws MathException if an error occurs computing the p-value
+     */
+    protected double tTest(double m1, double m2, double v1, double v2,
+            double n1, double n2)
+    throws MathException {
+        double t = FastMath.abs(t(m1, m2, v1, v2, n1, n2));
+        double degreesOfFreedom = 0;
+        degreesOfFreedom = df(v1, v2, n1, n2);
+        distribution.setDegreesOfFreedom(degreesOfFreedom);
+        return 2.0 * distribution.cumulativeProbability(-t);
+    }
+
+    /**
+     * Computes p-value for 2-sided, 2-sample t-test, under the assumption
+     * of equal subpopulation variances.
+     * <p>
+     * The sum of the sample sizes minus 2 is used as degrees of freedom.</p>
+     *
+     * @param m1 first sample mean
+     * @param m2 second sample mean
+     * @param v1 first sample variance
+     * @param v2 second sample variance
+     * @param n1 first sample n
+     * @param n2 second sample n
+     * @return p-value
+     * @throws MathException if an error occurs computing the p-value
+     */
+    protected double homoscedasticTTest(double m1, double m2, double v1,
+            double v2, double n1, double n2)
+    throws MathException {
+        double t = FastMath.abs(homoscedasticT(m1, m2, v1, v2, n1, n2));
+        double degreesOfFreedom = n1 + n2 - 2;
+        distribution.setDegreesOfFreedom(degreesOfFreedom);
+        return 2.0 * distribution.cumulativeProbability(-t);
+    }
+
+    /**
+     * Modify the distribution used to compute inference statistics.
+     * @param value the new distribution
+     * @since 1.2
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public void setDistribution(TDistribution value) {
+        distribution = value;
+    }
+
+    /** Check significance level.
+     * @param alpha significance level
+     * @exception IllegalArgumentException if significance level is out of bounds
+     */
+    private void checkSignificanceLevel(final double alpha)
+        throws IllegalArgumentException {
+        if ((alpha <= 0) || (alpha > 0.5)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL,
+                  alpha, 0.0, 0.5);
+        }
+    }
+
+    /** Check sample data.
+     * @param data sample data
+     * @exception IllegalArgumentException if there is not enough sample data
+     */
+    private void checkSampleData(final double[] data)
+        throws IllegalArgumentException {
+        if ((data == null) || (data.length < 2)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC,
+                  (data == null) ? 0 : data.length);
+        }
+    }
+
+    /** Check sample data.
+     * @param stat statistical summary
+     * @exception IllegalArgumentException if there is not enough sample data
+     */
+    private void checkSampleData(final StatisticalSummary stat)
+        throws IllegalArgumentException {
+        if ((stat == null) || (stat.getN() < 2)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INSUFFICIENT_DATA_FOR_T_STATISTIC,
+                  (stat == null) ? 0 : stat.getN());
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java b/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java
new file mode 100644
index 0000000..5023d55
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/TestUtils.java
@@ -0,0 +1,436 @@
+/*
+ * 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.stat.inference;
+
+import java.util.Collection;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.stat.descriptive.StatisticalSummary;
+
+/**
+ * A collection of static methods to create inference test instances or to
+ * perform inference tests.
+ *
+ * <p>
+ * The set methods are not compatible with using the class in multiple threads,
+ * and have therefore been deprecated (along with the getters).
+ * The setters and getters will be removed in version 3.0.
+ *
+ * @since 1.1
+ * @version $Revision: 1067582 $ $Date: 2011-02-06 04:55:32 +0100 (dim. 06 févr. 2011) $
+ */
+public class TestUtils  {
+
+    /** Singleton TTest instance using default implementation. */
+    private static TTest tTest = new TTestImpl();
+
+    /** Singleton ChiSquareTest instance using default implementation. */
+    private static ChiSquareTest chiSquareTest =
+        new ChiSquareTestImpl();
+
+    /** Singleton ChiSquareTest instance using default implementation. */
+    private static UnknownDistributionChiSquareTest unknownDistributionChiSquareTest =
+        new ChiSquareTestImpl();
+
+    /** Singleton OneWayAnova instance using default implementation. */
+    private static OneWayAnova oneWayAnova =
+        new OneWayAnovaImpl();
+
+    /**
+     * Prevent instantiation.
+     */
+    protected TestUtils() {
+        super();
+    }
+
+    /**
+     * Set the (singleton) TTest instance.
+     *
+     * @param chiSquareTest the new instance to use
+     * @since 1.2
+     * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads
+     */
+    @Deprecated
+    public static void setChiSquareTest(TTest chiSquareTest) {
+        TestUtils.tTest = chiSquareTest;
+    }
+
+    /**
+     * Return a (singleton) TTest instance.  Does not create a new instance.
+     *
+     * @return a TTest instance
+     * @deprecated 2.2 will be removed in 3.0
+     */
+    @Deprecated
+    public static TTest getTTest() {
+        return tTest;
+    }
+
+    /**
+     * Set the (singleton) ChiSquareTest instance.
+     *
+     * @param chiSquareTest the new instance to use
+     * @since 1.2
+     * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads
+     */
+    @Deprecated
+    public static void setChiSquareTest(ChiSquareTest chiSquareTest) {
+        TestUtils.chiSquareTest = chiSquareTest;
+    }
+
+    /**
+     * Return a (singleton) ChiSquareTest instance.  Does not create a new instance.
+     *
+     * @return a ChiSquareTest instance
+     * @deprecated 2.2 will be removed in 3.0
+     */
+    @Deprecated
+    public static ChiSquareTest getChiSquareTest() {
+        return chiSquareTest;
+    }
+
+    /**
+     * Set the (singleton) UnknownDistributionChiSquareTest instance.
+     *
+     * @param unknownDistributionChiSquareTest the new instance to use
+     * @since 1.2
+     * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads
+     */
+    @Deprecated
+    public static void setUnknownDistributionChiSquareTest(UnknownDistributionChiSquareTest unknownDistributionChiSquareTest) {
+        TestUtils.unknownDistributionChiSquareTest = unknownDistributionChiSquareTest;
+    }
+
+    /**
+     * Return a (singleton) UnknownDistributionChiSquareTest instance.  Does not create a new instance.
+     *
+     * @return a UnknownDistributionChiSquareTest instance
+     * @deprecated 2.2 will be removed in 3.0
+     */
+    @Deprecated
+    public static UnknownDistributionChiSquareTest getUnknownDistributionChiSquareTest() {
+        return unknownDistributionChiSquareTest;
+    }
+
+    /**
+     * Set the (singleton) OneWayAnova instance
+     *
+     * @param oneWayAnova the new instance to use
+     * @since 1.2
+     * @deprecated 2.2 will be removed in 3.0 - not compatible with use from multiple threads
+     */
+    @Deprecated
+    public static void setOneWayAnova(OneWayAnova oneWayAnova) {
+        TestUtils.oneWayAnova = oneWayAnova;
+    }
+
+    /**
+     * Return a (singleton) OneWayAnova instance.  Does not create a new instance.
+     *
+     * @return a OneWayAnova instance
+     * @since 1.2
+     * @deprecated 2.2 will be removed in 3.0
+     */
+    @Deprecated
+    public static OneWayAnova getOneWayAnova() {
+        return oneWayAnova;
+    }
+
+
+    // CHECKSTYLE: stop JavadocMethodCheck
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(double[], double[])
+     */
+    public static double homoscedasticT(double[] sample1, double[] sample2)
+        throws IllegalArgumentException {
+        return tTest.homoscedasticT(sample1, sample2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary)
+     */
+    public static double homoscedasticT(StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException {
+        return tTest.homoscedasticT(sampleStats1, sampleStats2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[], double)
+     */
+    public static boolean homoscedasticTTest(double[] sample1, double[] sample2,
+            double alpha)
+        throws IllegalArgumentException, MathException {
+        return tTest. homoscedasticTTest(sample1, sample2, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[])
+     */
+    public static double homoscedasticTTest(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException {
+        return tTest.homoscedasticTTest(sample1, sample2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary)
+     */
+    public static double homoscedasticTTest(StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException, MathException {
+        return tTest.homoscedasticTTest(sampleStats1, sampleStats2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#pairedT(double[], double[])
+     */
+    public static double pairedT(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException {
+        return tTest.pairedT(sample1, sample2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[], double)
+     */
+    public static boolean pairedTTest(double[] sample1, double[] sample2,
+        double alpha)
+        throws IllegalArgumentException, MathException {
+        return tTest.pairedTTest(sample1, sample2, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[])
+     */
+    public static double pairedTTest(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException {
+        return tTest.pairedTTest(sample1, sample2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#t(double, double[])
+     */
+    public static double t(double mu, double[] observed)
+        throws IllegalArgumentException {
+        return tTest.t(mu, observed);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#t(double, org.apache.commons.math.stat.descriptive.StatisticalSummary)
+     */
+    public static double t(double mu, StatisticalSummary sampleStats)
+        throws IllegalArgumentException {
+        return tTest.t(mu, sampleStats);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#t(double[], double[])
+     */
+    public static double t(double[] sample1, double[] sample2)
+        throws IllegalArgumentException {
+        return tTest.t(sample1, sample2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#t(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary)
+     */
+    public static double t(StatisticalSummary sampleStats1,
+            StatisticalSummary sampleStats2)
+        throws IllegalArgumentException {
+        return tTest.t(sampleStats1, sampleStats2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[], double)
+     */
+    public static boolean tTest(double mu, double[] sample, double alpha)
+        throws IllegalArgumentException, MathException {
+        return tTest.tTest(mu, sample, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[])
+     */
+    public static double tTest(double mu, double[] sample)
+        throws IllegalArgumentException, MathException {
+        return tTest.tTest(mu, sample);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary, double)
+     */
+    public static boolean tTest(double mu, StatisticalSummary sampleStats,
+        double alpha)
+        throws IllegalArgumentException, MathException {
+        return tTest. tTest(mu, sampleStats, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary)
+     */
+    public static double tTest(double mu, StatisticalSummary sampleStats)
+        throws IllegalArgumentException, MathException {
+        return tTest.tTest(mu, sampleStats);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[], double)
+     */
+    public static boolean tTest(double[] sample1, double[] sample2, double alpha)
+        throws IllegalArgumentException, MathException {
+        return tTest.tTest(sample1, sample2, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[])
+     */
+    public static double tTest(double[] sample1, double[] sample2)
+        throws IllegalArgumentException, MathException {
+        return tTest.tTest(sample1, sample2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary, double)
+     */
+    public static boolean tTest(StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2, double alpha)
+        throws IllegalArgumentException, MathException {
+        return tTest. tTest(sampleStats1, sampleStats2, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary)
+     */
+    public static double tTest(StatisticalSummary sampleStats1,
+        StatisticalSummary sampleStats2)
+        throws IllegalArgumentException, MathException {
+        return tTest.tTest(sampleStats1, sampleStats2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquare(double[], long[])
+     */
+    public static double chiSquare(double[] expected, long[] observed)
+        throws IllegalArgumentException {
+        return chiSquareTest.chiSquare(expected, observed);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquare(long[][])
+     */
+    public static double chiSquare(long[][] counts)
+        throws IllegalArgumentException {
+        return chiSquareTest.chiSquare(counts);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(double[], long[], double)
+     */
+    public static boolean chiSquareTest(double[] expected, long[] observed,
+        double alpha)
+        throws IllegalArgumentException, MathException {
+        return chiSquareTest.chiSquareTest(expected, observed, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(double[], long[])
+     */
+    public static double chiSquareTest(double[] expected, long[] observed)
+        throws IllegalArgumentException, MathException {
+        return chiSquareTest.chiSquareTest(expected, observed);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(long[][], double)
+     */
+    public static boolean chiSquareTest(long[][] counts, double alpha)
+        throws IllegalArgumentException, MathException {
+        return chiSquareTest. chiSquareTest(counts, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(long[][])
+     */
+    public static double chiSquareTest(long[][] counts)
+        throws IllegalArgumentException, MathException {
+        return chiSquareTest. chiSquareTest(counts);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareDataSetsComparison(long[], long[])
+     *
+     * @since 1.2
+     */
+    public static double chiSquareDataSetsComparison(long[] observed1, long[] observed2)
+        throws IllegalArgumentException {
+        return unknownDistributionChiSquareTest.chiSquareDataSetsComparison(observed1, observed2);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareTestDataSetsComparison(long[], long[])
+     *
+     * @since 1.2
+     */
+    public static double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2)
+        throws IllegalArgumentException, MathException {
+        return unknownDistributionChiSquareTest.chiSquareTestDataSetsComparison(observed1, observed2);
+    }
+
+
+    /**
+     * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareTestDataSetsComparison(long[], long[], double)
+     *
+     * @since 1.2
+     */
+    public static boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2,
+        double alpha)
+        throws IllegalArgumentException, MathException {
+        return unknownDistributionChiSquareTest.chiSquareTestDataSetsComparison(observed1, observed2, alpha);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaFValue(Collection)
+     *
+     * @since 1.2
+     */
+    public static double oneWayAnovaFValue(Collection<double[]> categoryData)
+    throws IllegalArgumentException, MathException {
+        return oneWayAnova.anovaFValue(categoryData);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaPValue(Collection)
+     *
+     * @since 1.2
+     */
+    public static double oneWayAnovaPValue(Collection<double[]> categoryData)
+    throws IllegalArgumentException, MathException {
+        return oneWayAnova.anovaPValue(categoryData);
+    }
+
+    /**
+     * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaTest(Collection,double)
+     *
+     * @since 1.2
+     */
+    public static boolean oneWayAnovaTest(Collection<double[]> categoryData, double alpha)
+    throws IllegalArgumentException, MathException {
+        return oneWayAnova.anovaTest(categoryData, alpha);
+    }
+
+    // CHECKSTYLE: resume JavadocMethodCheck
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/UnknownDistributionChiSquareTest.java b/src/main/java/org/apache/commons/math/stat/inference/UnknownDistributionChiSquareTest.java
new file mode 100644
index 0000000..662e4d6
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/UnknownDistributionChiSquareTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.stat.inference;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * An interface for Chi-Square tests for unknown distributions.
+ * <p>Two samples tests are used when the distribution is unknown <i>a priori</i>
+ * but provided by one sample. We compare the second sample against the first.</p>
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 1.2
+ */
+public interface UnknownDistributionChiSquareTest extends ChiSquareTest {
+
+    /**
+     * <p>Computes a
+     * <a href="http://www.itl.nist.gov/div898/software/dataplot/refman1/auxillar/chi2samp.htm">
+     * Chi-Square two sample test statistic</a> comparing bin frequency counts
+     * in <code>observed1</code> and <code>observed2</code>.  The
+     * sums of frequency counts in the two samples are not required to be the
+     * same.  The formula used to compute the test statistic is</p>
+     * <code>
+     * &sum;[(K * observed1[i] - observed2[i]/K)<sup>2</sup> / (observed1[i] + observed2[i])]
+     * </code> where
+     * <br/><code>K = &sqrt;[&sum(observed2 / &sum;(observed1)]</code>
+     * </p>
+     * <p>This statistic can be used to perform a Chi-Square test evaluating the null hypothesis that
+     * both observed counts follow the same distribution.</p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Observed counts must be non-negative.
+     * </li>
+     * <li>Observed counts for a specific bin must not both be zero.
+     * </li>
+     * <li>Observed counts for a specific sample must not all be 0.
+     * </li>
+     * <li>The arrays <code>observed1</code> and <code>observed2</code> must have the same length and
+     * their common length must be at least 2.
+     * </li></ul></p><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param observed1 array of observed frequency counts of the first data set
+     * @param observed2 array of observed frequency counts of the second data set
+     * @return chiSquare statistic
+     * @throws IllegalArgumentException if preconditions are not met
+     */
+    double chiSquareDataSetsComparison(long[] observed1, long[] observed2)
+        throws IllegalArgumentException;
+
+    /**
+     * <p>Returns the <i>observed significance level</i>, or <a href=
+     * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue">
+     * p-value</a>, associated with a Chi-Square two sample test comparing
+     * bin frequency counts in <code>observed1</code> and
+     * <code>observed2</code>.
+     * </p>
+     * <p>The number returned is the smallest significance level at which one
+     * can reject the null hypothesis that the observed counts conform to the
+     * same distribution.
+     * </p>
+     * <p>See {@link #chiSquareDataSetsComparison(long[], long[])} for details
+     * on the formula used to compute the test statistic. The degrees of
+     * of freedom used to perform the test is one less than the common length
+     * of the input observed count arrays.
+     * </p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Observed counts must be non-negative.
+     * </li>
+     * <li>Observed counts for a specific bin must not both be zero.
+     * </li>
+     * <li>Observed counts for a specific sample must not all be 0.
+     * </li>
+     * <li>The arrays <code>observed1</code> and <code>observed2</code> must
+     * have the same length and
+     * their common length must be at least 2.
+     * </li></ul><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param observed1 array of observed frequency counts of the first data set
+     * @param observed2 array of observed frequency counts of the second data set
+     * @return p-value
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs computing the p-value
+     */
+    double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2)
+      throws IllegalArgumentException, MathException;
+
+    /**
+     * <p>Performs a Chi-Square two sample test comparing two binned data
+     * sets. The test evaluates the null hypothesis that the two lists of
+     * observed counts conform to the same frequency distribution, with
+     * significance level <code>alpha</code>.  Returns true iff the null
+     * hypothesis can be rejected with 100 * (1 - alpha) percent confidence.
+     * </p>
+     * <p>See {@link #chiSquareDataSetsComparison(long[], long[])} for
+     * details on the formula used to compute the Chisquare statistic used
+     * in the test. The degrees of of freedom used to perform the test is
+     * one less than the common length of the input observed count arrays.
+     * </p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>Observed counts must be non-negative.
+     * </li>
+     * <li>Observed counts for a specific bin must not both be zero.
+     * </li>
+     * <li>Observed counts for a specific sample must not all be 0.
+     * </li>
+     * <li>The arrays <code>observed1</code> and <code>observed2</code> must
+     * have the same length and their common length must be at least 2.
+     * </li>
+     * <li> <code> 0 < alpha < 0.5 </code>
+     * </li></ul><p>
+     * If any of the preconditions are not met, an
+     * <code>IllegalArgumentException</code> is thrown.</p>
+     *
+     * @param observed1 array of observed frequency counts of the first data set
+     * @param observed2 array of observed frequency counts of the second data set
+     * @param alpha significance level of the test
+     * @return true iff null hypothesis can be rejected with confidence
+     * 1 - alpha
+     * @throws IllegalArgumentException if preconditions are not met
+     * @throws MathException if an error occurs performing the test
+     */
+    boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, double alpha)
+      throws IllegalArgumentException, MathException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/inference/package.html b/src/main/java/org/apache/commons/math/stat/inference/package.html
new file mode 100644
index 0000000..288eebf
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/inference/package.html
@@ -0,0 +1,23 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>
+      Classes providing hypothesis testing and confidence interval
+      construction.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/package.html b/src/main/java/org/apache/commons/math/stat/package.html
new file mode 100644
index 0000000..d62d67a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Data storage, manipulation and summary routines.</body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/ranking/NaNStrategy.java b/src/main/java/org/apache/commons/math/stat/ranking/NaNStrategy.java
new file mode 100644
index 0000000..cffa7d1
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/ranking/NaNStrategy.java
@@ -0,0 +1,49 @@
+/*
+ * 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.stat.ranking;
+
+/**
+ * Strategies for handling NaN values in rank transformations.
+ * <ul>
+ * <li>MINIMAL - NaNs are treated as minimal in the ordering, equivalent to
+ * (that is, tied with) <code>Double.NEGATIVE_INFINITY</code>.</li>
+ * <li>MAXIMAL - NaNs are treated as maximal in the ordering, equivalent to
+ * <code>Double.POSITIVE_INFINITY</code></li>
+ * <li>REMOVED - NaNs are removed before the rank transform is applied</li>
+ * <li>FIXED - NaNs are left "in place," that is the rank transformation is
+ * applied to the other elements in the input array, but the NaN elements
+ * are returned unchanged.</li>
+ * </ul>
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public enum NaNStrategy {
+
+    /** NaNs are considered minimal in the ordering */
+    MINIMAL,
+
+    /** NaNs are considered maximal in the ordering */
+    MAXIMAL,
+
+    /** NaNs are removed before computing ranks */
+    REMOVED,
+
+    /** NaNs are left in place */
+    FIXED
+}
diff --git a/src/main/java/org/apache/commons/math/stat/ranking/NaturalRanking.java b/src/main/java/org/apache/commons/math/stat/ranking/NaturalRanking.java
new file mode 100644
index 0000000..f51189c
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/ranking/NaturalRanking.java
@@ -0,0 +1,464 @@
+/*
+ * 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.stat.ranking;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.math.exception.MathInternalError;
+import org.apache.commons.math.random.RandomData;
+import org.apache.commons.math.random.RandomDataImpl;
+import org.apache.commons.math.random.RandomGenerator;
+import org.apache.commons.math.util.FastMath;
+
+
+/**
+ * <p> Ranking based on the natural ordering on doubles.</p>
+ * <p>NaNs are treated according to the configured {@link NaNStrategy} and ties
+ * are handled using the selected {@link TiesStrategy}.
+ * Configuration settings are supplied in optional constructor arguments.
+ * Defaults are {@link NaNStrategy#MAXIMAL} and {@link TiesStrategy#AVERAGE},
+ * respectively. When using {@link TiesStrategy#RANDOM}, a
+ * {@link RandomGenerator} may be supplied as a constructor argument.</p>
+ * <p>Examples:
+ * <table border="1" cellpadding="3">
+ * <tr><th colspan="3">
+ * Input data: (20, 17, 30, 42.3, 17, 50, Double.NaN, Double.NEGATIVE_INFINITY, 17)
+ * </th></tr>
+ * <tr><th>NaNStrategy</th><th>TiesStrategy</th>
+ * <th><code>rank(data)</code></th>
+ * <tr>
+ * <td>default (NaNs maximal)</td>
+ * <td>default (ties averaged)</td>
+ * <td>(5, 3, 6, 7, 3, 8, 9, 1, 3)</td></tr>
+ * <tr>
+ * <td>default (NaNs maximal)</td>
+ * <td>MINIMUM</td>
+ * <td>(5, 2, 6, 7, 2, 8, 9, 1, 2)</td></tr>
+ * <tr>
+ * <td>MINIMAL</td>
+ * <td>default (ties averaged)</td>
+ * <td>(6, 4, 7, 8, 4, 9, 1.5, 1.5, 4)</td></tr>
+ * <tr>
+ * <td>REMOVED</td>
+ * <td>SEQUENTIAL</td>
+ * <td>(5, 2, 6, 7, 3, 8, 1, 4)</td></tr>
+ * <tr>
+ * <td>MINIMAL</td>
+ * <td>MAXIMUM</td>
+ * <td>(6, 5, 7, 8, 5, 9, 2, 2, 5)</td></tr></table></p>
+ *
+ * @since 2.0
+ * @version $Revision: 1061496 $ $Date: 2011-01-20 21:32:16 +0100 (jeu. 20 janv. 2011) $
+ */
+public class NaturalRanking implements RankingAlgorithm {
+
+    /** default NaN strategy */
+    public static final NaNStrategy DEFAULT_NAN_STRATEGY = NaNStrategy.MAXIMAL;
+
+    /** default ties strategy */
+    public static final TiesStrategy DEFAULT_TIES_STRATEGY = TiesStrategy.AVERAGE;
+
+    /** NaN strategy - defaults to NaNs maximal */
+    private final NaNStrategy nanStrategy;
+
+    /** Ties strategy - defaults to ties averaged */
+    private final TiesStrategy tiesStrategy;
+
+    /** Source of random data - used only when ties strategy is RANDOM */
+    private final RandomData randomData;
+
+    /**
+     * Create a NaturalRanking with default strategies for handling ties and NaNs.
+     */
+    public NaturalRanking() {
+        super();
+        tiesStrategy = DEFAULT_TIES_STRATEGY;
+        nanStrategy = DEFAULT_NAN_STRATEGY;
+        randomData = null;
+    }
+
+    /**
+     * Create a NaturalRanking with the given TiesStrategy.
+     *
+     * @param tiesStrategy the TiesStrategy to use
+     */
+    public NaturalRanking(TiesStrategy tiesStrategy) {
+        super();
+        this.tiesStrategy = tiesStrategy;
+        nanStrategy = DEFAULT_NAN_STRATEGY;
+        randomData = new RandomDataImpl();
+    }
+
+    /**
+     * Create a NaturalRanking with the given NaNStrategy.
+     *
+     * @param nanStrategy the NaNStrategy to use
+     */
+    public NaturalRanking(NaNStrategy nanStrategy) {
+        super();
+        this.nanStrategy = nanStrategy;
+        tiesStrategy = DEFAULT_TIES_STRATEGY;
+        randomData = null;
+    }
+
+    /**
+     * Create a NaturalRanking with the given NaNStrategy and TiesStrategy.
+     *
+     * @param nanStrategy NaNStrategy to use
+     * @param tiesStrategy TiesStrategy to use
+     */
+    public NaturalRanking(NaNStrategy nanStrategy, TiesStrategy tiesStrategy) {
+        super();
+        this.nanStrategy = nanStrategy;
+        this.tiesStrategy = tiesStrategy;
+        randomData = new RandomDataImpl();
+    }
+
+    /**
+     * Create a NaturalRanking with TiesStrategy.RANDOM and the given
+     * RandomGenerator as the source of random data.
+     *
+     * @param randomGenerator source of random data
+     */
+    public NaturalRanking(RandomGenerator randomGenerator) {
+        super();
+        this.tiesStrategy = TiesStrategy.RANDOM;
+        nanStrategy = DEFAULT_NAN_STRATEGY;
+        randomData = new RandomDataImpl(randomGenerator);
+    }
+
+
+    /**
+     * Create a NaturalRanking with the given NaNStrategy, TiesStrategy.RANDOM
+     * and the given source of random data.
+     *
+     * @param nanStrategy NaNStrategy to use
+     * @param randomGenerator source of random data
+     */
+    public NaturalRanking(NaNStrategy nanStrategy,
+            RandomGenerator randomGenerator) {
+        super();
+        this.nanStrategy = nanStrategy;
+        this.tiesStrategy = TiesStrategy.RANDOM;
+        randomData = new RandomDataImpl(randomGenerator);
+    }
+
+    /**
+     * Return the NaNStrategy
+     *
+     * @return returns the NaNStrategy
+     */
+    public NaNStrategy getNanStrategy() {
+        return nanStrategy;
+    }
+
+    /**
+     * Return the TiesStrategy
+     *
+     * @return the TiesStrategy
+     */
+    public TiesStrategy getTiesStrategy() {
+        return tiesStrategy;
+    }
+
+    /**
+     * Rank <code>data</code> using the natural ordering on Doubles, with
+     * NaN values handled according to <code>nanStrategy</code> and ties
+     * resolved using <code>tiesStrategy.</code>
+     *
+     * @param data array to be ranked
+     * @return array of ranks
+     */
+    public double[] rank(double[] data) {
+
+        // Array recording initial positions of data to be ranked
+        IntDoublePair[] ranks = new IntDoublePair[data.length];
+        for (int i = 0; i < data.length; i++) {
+            ranks[i] = new IntDoublePair(data[i], i);
+        }
+
+        // Recode, remove or record positions of NaNs
+        List<Integer> nanPositions = null;
+        switch (nanStrategy) {
+            case MAXIMAL: // Replace NaNs with +INFs
+                recodeNaNs(ranks, Double.POSITIVE_INFINITY);
+                break;
+            case MINIMAL: // Replace NaNs with -INFs
+                recodeNaNs(ranks, Double.NEGATIVE_INFINITY);
+                break;
+            case REMOVED: // Drop NaNs from data
+                ranks = removeNaNs(ranks);
+                break;
+            case FIXED:   // Record positions of NaNs
+                nanPositions = getNanPositions(ranks);
+                break;
+            default: // this should not happen unless NaNStrategy enum is changed
+                throw new MathInternalError();
+        }
+
+        // Sort the IntDoublePairs
+        Arrays.sort(ranks);
+
+        // Walk the sorted array, filling output array using sorted positions,
+        // resolving ties as we go
+        double[] out = new double[ranks.length];
+        int pos = 1;  // position in sorted array
+        out[ranks[0].getPosition()] = pos;
+        List<Integer> tiesTrace = new ArrayList<Integer>();
+        tiesTrace.add(ranks[0].getPosition());
+        for (int i = 1; i < ranks.length; i++) {
+            if (Double.compare(ranks[i].getValue(), ranks[i - 1].getValue()) > 0) {
+                // tie sequence has ended (or had length 1)
+                pos = i + 1;
+                if (tiesTrace.size() > 1) {  // if seq is nontrivial, resolve
+                    resolveTie(out, tiesTrace);
+                }
+                tiesTrace = new ArrayList<Integer>();
+                tiesTrace.add(ranks[i].getPosition());
+            } else {
+                // tie sequence continues
+                tiesTrace.add(ranks[i].getPosition());
+            }
+            out[ranks[i].getPosition()] = pos;
+        }
+        if (tiesTrace.size() > 1) {  // handle tie sequence at end
+            resolveTie(out, tiesTrace);
+        }
+        if (nanStrategy == NaNStrategy.FIXED) {
+            restoreNaNs(out, nanPositions);
+        }
+        return out;
+    }
+
+    /**
+     * Returns an array that is a copy of the input array with IntDoublePairs
+     * having NaN values removed.
+     *
+     * @param ranks input array
+     * @return array with NaN-valued entries removed
+     */
+    private IntDoublePair[] removeNaNs(IntDoublePair[] ranks) {
+        if (!containsNaNs(ranks)) {
+            return ranks;
+        }
+        IntDoublePair[] outRanks = new IntDoublePair[ranks.length];
+        int j = 0;
+        for (int i = 0; i < ranks.length; i++) {
+            if (Double.isNaN(ranks[i].getValue())) {
+                // drop, but adjust original ranks of later elements
+                for (int k = i + 1; k < ranks.length; k++) {
+                    ranks[k] = new IntDoublePair(
+                            ranks[k].getValue(), ranks[k].getPosition() - 1);
+                }
+            } else {
+                outRanks[j] = new IntDoublePair(
+                        ranks[i].getValue(), ranks[i].getPosition());
+                j++;
+            }
+        }
+        IntDoublePair[] returnRanks = new IntDoublePair[j];
+        System.arraycopy(outRanks, 0, returnRanks, 0, j);
+        return returnRanks;
+    }
+
+    /**
+     * Recodes NaN values to the given value.
+     *
+     * @param ranks array to recode
+     * @param value the value to replace NaNs with
+     */
+    private void recodeNaNs(IntDoublePair[] ranks, double value) {
+        for (int i = 0; i < ranks.length; i++) {
+            if (Double.isNaN(ranks[i].getValue())) {
+                ranks[i] = new IntDoublePair(
+                        value, ranks[i].getPosition());
+            }
+        }
+    }
+
+    /**
+     * Checks for presence of NaNs in <code>ranks.</code>
+     *
+     * @param ranks array to be searched for NaNs
+     * @return true iff ranks contains one or more NaNs
+     */
+    private boolean containsNaNs(IntDoublePair[] ranks) {
+        for (int i = 0; i < ranks.length; i++) {
+            if (Double.isNaN(ranks[i].getValue())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Resolve a sequence of ties, using the configured {@link TiesStrategy}.
+     * The input <code>ranks</code> array is expected to take the same value
+     * for all indices in <code>tiesTrace</code>.  The common value is recoded
+     * according to the tiesStrategy. For example, if ranks = <5,8,2,6,2,7,1,2>,
+     * tiesTrace = <2,4,7> and tiesStrategy is MINIMUM, ranks will be unchanged.
+     * The same array and trace with tiesStrategy AVERAGE will come out
+     * <5,8,3,6,3,7,1,3>.
+     *
+     * @param ranks array of ranks
+     * @param tiesTrace list of indices where <code>ranks</code> is constant
+     * -- that is, for any i and j in TiesTrace, <code> ranks[i] == ranks[j]
+     * </code>
+     */
+    private void resolveTie(double[] ranks, List<Integer> tiesTrace) {
+
+        // constant value of ranks over tiesTrace
+        final double c = ranks[tiesTrace.get(0)];
+
+        // length of sequence of tied ranks
+        final int length = tiesTrace.size();
+
+        switch (tiesStrategy) {
+            case  AVERAGE:  // Replace ranks with average
+                fill(ranks, tiesTrace, (2 * c + length - 1) / 2d);
+                break;
+            case MAXIMUM:   // Replace ranks with maximum values
+                fill(ranks, tiesTrace, c + length - 1);
+                break;
+            case MINIMUM:   // Replace ties with minimum
+                fill(ranks, tiesTrace, c);
+                break;
+            case RANDOM:    // Fill with random integral values in [c, c + length - 1]
+                Iterator<Integer> iterator = tiesTrace.iterator();
+                long f = FastMath.round(c);
+                while (iterator.hasNext()) {
+                    ranks[iterator.next()] =
+                        randomData.nextLong(f, f + length - 1);
+                }
+                break;
+            case SEQUENTIAL:  // Fill sequentially from c to c + length - 1
+                // walk and fill
+                iterator = tiesTrace.iterator();
+                f = FastMath.round(c);
+                int i = 0;
+                while (iterator.hasNext()) {
+                    ranks[iterator.next()] = f + i++;
+                }
+                break;
+            default: // this should not happen unless TiesStrategy enum is changed
+                throw new MathInternalError();
+        }
+    }
+
+    /**
+     * Sets<code>data[i] = value</code> for each i in <code>tiesTrace.</code>
+     *
+     * @param data array to modify
+     * @param tiesTrace list of index values to set
+     * @param value value to set
+     */
+    private void fill(double[] data, List<Integer> tiesTrace, double value) {
+        Iterator<Integer> iterator = tiesTrace.iterator();
+        while (iterator.hasNext()) {
+            data[iterator.next()] = value;
+        }
+    }
+
+    /**
+     * Set <code>ranks[i] = Double.NaN</code> for each i in <code>nanPositions.</code>
+     *
+     * @param ranks array to modify
+     * @param nanPositions list of index values to set to <code>Double.NaN</code>
+     */
+    private void restoreNaNs(double[] ranks, List<Integer> nanPositions) {
+        if (nanPositions.size() == 0) {
+            return;
+        }
+        Iterator<Integer> iterator = nanPositions.iterator();
+        while (iterator.hasNext()) {
+            ranks[iterator.next().intValue()] = Double.NaN;
+        }
+
+    }
+
+    /**
+     * Returns a list of indexes where <code>ranks</code> is <code>NaN.</code>
+     *
+     * @param ranks array to search for <code>NaNs</code>
+     * @return list of indexes i such that <code>ranks[i] = NaN</code>
+     */
+    private List<Integer> getNanPositions(IntDoublePair[] ranks) {
+        ArrayList<Integer> out = new ArrayList<Integer>();
+        for (int i = 0; i < ranks.length; i++) {
+            if (Double.isNaN(ranks[i].getValue())) {
+                out.add(Integer.valueOf(i));
+            }
+        }
+        return out;
+    }
+
+    /**
+     * Represents the position of a double value in an ordering.
+     * Comparable interface is implemented so Arrays.sort can be used
+     * to sort an array of IntDoublePairs by value.  Note that the
+     * implicitly defined natural ordering is NOT consistent with equals.
+     */
+    private static class IntDoublePair implements Comparable<IntDoublePair>  {
+
+        /** Value of the pair */
+        private final double value;
+
+        /** Original position of the pair */
+        private final int position;
+
+        /**
+         * Construct an IntDoublePair with the given value and position.
+         * @param value the value of the pair
+         * @param position the original position
+         */
+        public IntDoublePair(double value, int position) {
+            this.value = value;
+            this.position = position;
+        }
+
+        /**
+         * Compare this IntDoublePair to another pair.
+         * Only the <strong>values</strong> are compared.
+         *
+         * @param other the other pair to compare this to
+         * @return result of <code>Double.compare(value, other.value)</code>
+         */
+        public int compareTo(IntDoublePair other) {
+            return Double.compare(value, other.value);
+        }
+
+        /**
+         * Returns the value of the pair.
+         * @return value
+         */
+        public double getValue() {
+            return value;
+        }
+
+        /**
+         * Returns the original position of the pair.
+         * @return position
+         */
+        public int getPosition() {
+            return position;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/ranking/RankingAlgorithm.java b/src/main/java/org/apache/commons/math/stat/ranking/RankingAlgorithm.java
new file mode 100644
index 0000000..b01f324
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/ranking/RankingAlgorithm.java
@@ -0,0 +1,41 @@
+/*
+ * 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.stat.ranking;
+
+/**
+ * Interface representing a rank transformation.
+ *
+ * @since 2.0
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface RankingAlgorithm {
+    /**
+     * <p>Performs a rank transformation on the input data, returning an array
+     * of ranks.</p>
+     *
+     * <p>Ranks should be 1-based - that is, the smallest value
+     * returned in an array of ranks should be greater than or equal to one,
+     * rather than 0. Ranks should in general take integer values, though
+     * implementations may return averages or other floating point values
+     * to resolve ties in the input data.</p>
+     *
+     * @param data array of data to be ranked
+     * @return an array of ranks corresponding to the elements of the input array
+     */
+    double[] rank (double[] data);
+}
diff --git a/src/main/java/org/apache/commons/math/stat/ranking/TiesStrategy.java b/src/main/java/org/apache/commons/math/stat/ranking/TiesStrategy.java
new file mode 100644
index 0000000..794c229
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/ranking/TiesStrategy.java
@@ -0,0 +1,55 @@
+/*
+ * 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.stat.ranking;
+
+/**
+ * Strategies for handling tied values in rank transformations.
+ * <ul>
+ * <li>SEQUENTIAL - Ties are assigned ranks in order of occurrence in the original array,
+ * for example (1,3,4,3) is ranked as (1,2,4,3)</li>
+ * <li>MINIMUM - Tied values are assigned the minimum applicable rank, or the rank
+ * of the first occurrence. For example, (1,3,4,3) is ranked as (1,2,4,2)</li>
+ * <li>MAXIMUM - Tied values are assigned the maximum applicable rank, or the rank
+ * of the last occurrence. For example, (1,3,4,3) is ranked as (1,3,4,3)</li>
+ * <li>AVERAGE - Tied values are assigned the average of the applicable ranks.
+ * For example, (1,3,4,3) is ranked as (1,2.5,4,2.5)</li>
+ * <li>RANDOM - Tied values are assigned a random integer rank from among the
+ * applicable values. The assigned rank will always be an integer, (inclusively)
+ * between the values returned by the MINIMUM and MAXIMUM strategies.</li>
+ * </ul>
+ *
+ * @since 2.0
+ * @version $Revision: 981332 $ $Date: 2010-08-02 00:24:31 +0200 (lun. 02 août 2010) $
+ */
+public enum TiesStrategy {
+
+    /** Ties assigned sequential ranks in order of occurrence */
+    SEQUENTIAL,
+
+    /** Ties get the minimum applicable rank */
+    MINIMUM,
+
+    /** Ties get the maximum applicable rank */
+    MAXIMUM,
+
+    /** Ties get the average of applicable ranks */
+    AVERAGE,
+
+    /** Ties get a random integral value from among applicable ranks */
+    RANDOM
+}
diff --git a/src/main/java/org/apache/commons/math/stat/ranking/package.html b/src/main/java/org/apache/commons/math/stat/ranking/package.html
new file mode 100644
index 0000000..63e0c4a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/ranking/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision:$ $Date:$ -->
+    <body>
+      Classes providing rank transformations.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java b/src/main/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
new file mode 100644
index 0000000..9757682
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
@@ -0,0 +1,366 @@
+/*
+ * 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.stat.regression;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.linear.ArrayRealVector;
+import org.apache.commons.math.stat.descriptive.moment.Variance;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Abstract base class for implementations of MultipleLinearRegression.
+ * @version $Revision: 1073459 $ $Date: 2011-02-22 20:18:12 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+public abstract class AbstractMultipleLinearRegression implements
+        MultipleLinearRegression {
+
+    /** X sample data. */
+    protected RealMatrix X;
+
+    /** Y sample data. */
+    protected RealVector Y;
+
+    /** Whether or not the regression model includes an intercept.  True means no intercept. */
+    private boolean noIntercept = false;
+
+    /**
+     * @return true if the model has no intercept term; false otherwise
+     * @since 2.2
+     */
+    public boolean isNoIntercept() {
+        return noIntercept;
+    }
+
+    /**
+     * @param noIntercept true means the model is to be estimated without an intercept term
+     * @since 2.2
+     */
+    public void setNoIntercept(boolean noIntercept) {
+        this.noIntercept = noIntercept;
+    }
+
+    /**
+     * <p>Loads model x and y sample data from a flat input array, overriding any previous sample.
+     * </p>
+     * <p>Assumes that rows are concatenated with y values first in each row.  For example, an input
+     * <code>data</code> array containing the sequence of values (1, 2, 3, 4, 5, 6, 7, 8, 9) with
+     * <code>nobs = 3</code> and <code>nvars = 2</code> creates a regression dataset with two
+     * independent variables, as below:
+     * <pre>
+     *   y   x[0]  x[1]
+     *   --------------
+     *   1     2     3
+     *   4     5     6
+     *   7     8     9
+     * </pre>
+     * </p>
+     * <p>Note that there is no need to add an initial unitary column (column of 1's) when
+     * specifying a model including an intercept term.  If {@link #isNoIntercept()} is <code>true</code>,
+     * the X matrix will be created without an initial column of "1"s; otherwise this column will
+     * be added.
+     * </p>
+     * <p>Throws IllegalArgumentException if any of the following preconditions fail:
+     * <ul><li><code>data</code> cannot be null</li>
+     * <li><code>data.length = nobs * (nvars + 1)</li>
+     * <li><code>nobs > nvars</code></li></ul>
+     * </p>
+     *
+     * @param data input data array
+     * @param nobs number of observations (rows)
+     * @param nvars number of independent variables (columns, not counting y)
+     * @throws IllegalArgumentException if the preconditions are not met
+     */
+    public void newSampleData(double[] data, int nobs, int nvars) {
+        if (data == null) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NULL_NOT_ALLOWED);
+        }
+        if (data.length != nobs * (nvars + 1)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INVALID_REGRESSION_ARRAY, data.length, nobs, nvars);
+        }
+        if (nobs <= nvars) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS);
+        }
+        double[] y = new double[nobs];
+        final int cols = noIntercept ? nvars: nvars + 1;
+        double[][] x = new double[nobs][cols];
+        int pointer = 0;
+        for (int i = 0; i < nobs; i++) {
+            y[i] = data[pointer++];
+            if (!noIntercept) {
+                x[i][0] = 1.0d;
+            }
+            for (int j = noIntercept ? 0 : 1; j < cols; j++) {
+                x[i][j] = data[pointer++];
+            }
+        }
+        this.X = new Array2DRowRealMatrix(x);
+        this.Y = new ArrayRealVector(y);
+    }
+
+    /**
+     * Loads new y sample data, overriding any previous data.
+     *
+     * @param y the array representing the y sample
+     * @throws IllegalArgumentException if y is null or empty
+     */
+    protected void newYSampleData(double[] y) {
+        if (y == null) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NULL_NOT_ALLOWED);
+        }
+        if (y.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NO_DATA);
+        }
+        this.Y = new ArrayRealVector(y);
+    }
+
+    /**
+     * <p>Loads new x sample data, overriding any previous data.
+     * </p>
+     * The input <code>x</code> array should have one row for each sample
+     * observation, with columns corresponding to independent variables.
+     * For example, if <pre>
+     * <code> x = new double[][] {{1, 2}, {3, 4}, {5, 6}} </code></pre>
+     * then <code>setXSampleData(x) </code> results in a model with two independent
+     * variables and 3 observations:
+     * <pre>
+     *   x[0]  x[1]
+     *   ----------
+     *     1    2
+     *     3    4
+     *     5    6
+     * </pre>
+     * </p>
+     * <p>Note that there is no need to add an initial unitary column (column of 1's) when
+     * specifying a model including an intercept term.
+     * </p>
+     * @param x the rectangular array representing the x sample
+     * @throws IllegalArgumentException if x is null, empty or not rectangular
+     */
+    protected void newXSampleData(double[][] x) {
+        if (x == null) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NULL_NOT_ALLOWED);
+        }
+        if (x.length == 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NO_DATA);
+        }
+        if (noIntercept) {
+            this.X = new Array2DRowRealMatrix(x, true);
+        } else { // Augment design matrix with initial unitary column
+            final int nVars = x[0].length;
+            final double[][] xAug = new double[x.length][nVars + 1];
+            for (int i = 0; i < x.length; i++) {
+                if (x[i].length != nVars) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
+                            x[i].length, nVars);
+                }
+                xAug[i][0] = 1.0d;
+                System.arraycopy(x[i], 0, xAug[i], 1, nVars);
+            }
+            this.X = new Array2DRowRealMatrix(xAug, false);
+        }
+    }
+
+    /**
+     * Validates sample data.  Checks that
+     * <ul><li>Neither x nor y is null or empty;</li>
+     * <li>The length (i.e. number of rows) of x equals the length of y</li>
+     * <li>x has at least one more row than it has columns (i.e. there is
+     * sufficient data to estimate regression coefficients for each of the
+     * columns in x plus an intercept.</li>
+     * </ul>
+     *
+     * @param x the [n,k] array representing the x data
+     * @param y the [n,1] array representing the y data
+     * @throws IllegalArgumentException if any of the checks fail
+     *
+     */
+    protected void validateSampleData(double[][] x, double[] y) {
+        if ((x == null) || (y == null) || (x.length != y.length)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE,
+                  (x == null) ? 0 : x.length,
+                  (y == null) ? 0 : y.length);
+        }
+        if (x.length == 0) {  // Must be no y data either
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NO_DATA);
+        }
+        if (x[0].length + 1 > x.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NOT_ENOUGH_DATA_FOR_NUMBER_OF_PREDICTORS,
+                  x.length, x[0].length);
+        }
+    }
+
+    /**
+     * Validates that the x data and covariance matrix have the same
+     * number of rows and that the covariance matrix is square.
+     *
+     * @param x the [n,k] array representing the x sample
+     * @param covariance the [n,n] array representing the covariance matrix
+     * @throws IllegalArgumentException if the number of rows in x is not equal
+     * to the number of rows in covariance or covariance is not square.
+     */
+    protected void validateCovarianceData(double[][] x, double[][] covariance) {
+        if (x.length != covariance.length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                 LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, covariance.length);
+        }
+        if (covariance.length > 0 && covariance.length != covariance[0].length) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.NON_SQUARE_MATRIX,
+                  covariance.length, covariance[0].length);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double[] estimateRegressionParameters() {
+        RealVector b = calculateBeta();
+        return b.getData();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double[] estimateResiduals() {
+        RealVector b = calculateBeta();
+        RealVector e = Y.subtract(X.operate(b));
+        return e.getData();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double[][] estimateRegressionParametersVariance() {
+        return calculateBetaVariance().getData();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double[] estimateRegressionParametersStandardErrors() {
+        double[][] betaVariance = estimateRegressionParametersVariance();
+        double sigma = calculateErrorVariance();
+        int length = betaVariance[0].length;
+        double[] result = new double[length];
+        for (int i = 0; i < length; i++) {
+            result[i] = FastMath.sqrt(sigma * betaVariance[i][i]);
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public double estimateRegressandVariance() {
+        return calculateYVariance();
+    }
+
+    /**
+     * Estimates the variance of the error.
+     *
+     * @return estimate of the error variance
+     * @since 2.2
+     */
+    public double estimateErrorVariance() {
+        return calculateErrorVariance();
+
+    }
+
+    /**
+     * Estimates the standard error of the regression.
+     *
+     * @return regression standard error
+     * @since 2.2
+     */
+    public double estimateRegressionStandardError() {
+        return Math.sqrt(estimateErrorVariance());
+    }
+
+    /**
+     * Calculates the beta of multiple linear regression in matrix notation.
+     *
+     * @return beta
+     */
+    protected abstract RealVector calculateBeta();
+
+    /**
+     * Calculates the beta variance of multiple linear regression in matrix
+     * notation.
+     *
+     * @return beta variance
+     */
+    protected abstract RealMatrix calculateBetaVariance();
+
+
+    /**
+     * Calculates the variance of the y values.
+     *
+     * @return Y variance
+     */
+    protected double calculateYVariance() {
+        return new Variance().evaluate(Y.getData());
+    }
+
+    /**
+     * <p>Calculates the variance of the error term.</p>
+     * Uses the formula <pre>
+     * var(u) = u &middot; u / (n - k)
+     * </pre>
+     * where n and k are the row and column dimensions of the design
+     * matrix X.
+     *
+     * @return error variance estimate
+     * @since 2.2
+     */
+    protected double calculateErrorVariance() {
+        RealVector residuals = calculateResiduals();
+        return residuals.dotProduct(residuals) /
+               (X.getRowDimension() - X.getColumnDimension());
+    }
+
+    /**
+     * Calculates the residuals of multiple linear regression in matrix
+     * notation.
+     *
+     * <pre>
+     * u = y - X * b
+     * </pre>
+     *
+     * @return The residuals [n,1] matrix
+     */
+    protected RealVector calculateResiduals() {
+        RealVector b = calculateBeta();
+        return Y.subtract(X.operate(b));
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java b/src/main/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
new file mode 100644
index 0000000..dc6ef0d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
@@ -0,0 +1,136 @@
+/*
+ * 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.stat.regression;
+
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.RealVector;
+
+/**
+ * The GLS implementation of the multiple linear regression.
+ *
+ * GLS assumes a general covariance matrix Omega of the error
+ * <pre>
+ * u ~ N(0, Omega)
+ * </pre>
+ *
+ * Estimated by GLS,
+ * <pre>
+ * b=(X' Omega^-1 X)^-1X'Omega^-1 y
+ * </pre>
+ * whose variance is
+ * <pre>
+ * Var(b)=(X' Omega^-1 X)^-1
+ * </pre>
+ * @version $Revision: 1073460 $ $Date: 2011-02-22 20:22:39 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+public class GLSMultipleLinearRegression extends AbstractMultipleLinearRegression {
+
+    /** Covariance matrix. */
+    private RealMatrix Omega;
+
+    /** Inverse of covariance matrix. */
+    private RealMatrix OmegaInverse;
+
+    /** Replace sample data, overriding any previous sample.
+     * @param y y values of the sample
+     * @param x x values of the sample
+     * @param covariance array representing the covariance matrix
+     */
+    public void newSampleData(double[] y, double[][] x, double[][] covariance) {
+        validateSampleData(x, y);
+        newYSampleData(y);
+        newXSampleData(x);
+        validateCovarianceData(x, covariance);
+        newCovarianceData(covariance);
+    }
+
+    /**
+     * Add the covariance data.
+     *
+     * @param omega the [n,n] array representing the covariance
+     */
+    protected void newCovarianceData(double[][] omega){
+        this.Omega = new Array2DRowRealMatrix(omega);
+        this.OmegaInverse = null;
+    }
+
+    /**
+     * Get the inverse of the covariance.
+     * <p>The inverse of the covariance matrix is lazily evaluated and cached.</p>
+     * @return inverse of the covariance
+     */
+    protected RealMatrix getOmegaInverse() {
+        if (OmegaInverse == null) {
+            OmegaInverse = new LUDecompositionImpl(Omega).getSolver().getInverse();
+        }
+        return OmegaInverse;
+    }
+
+    /**
+     * Calculates beta by GLS.
+     * <pre>
+     *  b=(X' Omega^-1 X)^-1X'Omega^-1 y
+     * </pre>
+     * @return beta
+     */
+    @Override
+    protected RealVector calculateBeta() {
+        RealMatrix OI = getOmegaInverse();
+        RealMatrix XT = X.transpose();
+        RealMatrix XTOIX = XT.multiply(OI).multiply(X);
+        RealMatrix inverse = new LUDecompositionImpl(XTOIX).getSolver().getInverse();
+        return inverse.multiply(XT).multiply(OI).operate(Y);
+    }
+
+    /**
+     * Calculates the variance on the beta.
+     * <pre>
+     *  Var(b)=(X' Omega^-1 X)^-1
+     * </pre>
+     * @return The beta variance matrix
+     */
+    @Override
+    protected RealMatrix calculateBetaVariance() {
+        RealMatrix OI = getOmegaInverse();
+        RealMatrix XTOIX = X.transpose().multiply(OI).multiply(X);
+        return new LUDecompositionImpl(XTOIX).getSolver().getInverse();
+    }
+
+
+    /**
+     * Calculates the estimated variance of the error term using the formula
+     * <pre>
+     *  Var(u) = Tr(u' Omega^-1 u)/(n-k)
+     * </pre>
+     * where n and k are the row and column dimensions of the design
+     * matrix X.
+     *
+     * @return error variance
+     * @since 2.2
+     */
+    @Override
+    protected double calculateErrorVariance() {
+        RealVector residuals = calculateResiduals();
+        double t = residuals.dotProduct(getOmegaInverse().operate(residuals));
+        return t / (X.getRowDimension() - X.getColumnDimension());
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java b/src/main/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
new file mode 100644
index 0000000..b7aabd4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
@@ -0,0 +1,70 @@
+/*
+ * 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.stat.regression;
+
+/**
+ * The multiple linear regression can be represented in matrix-notation.
+ * <pre>
+ *  y=X*b+u
+ * </pre>
+ * where y is an <code>n-vector</code> <b>regressand</b>, X is a <code>[n,k]</code> matrix whose <code>k</code> columns are called
+ * <b>regressors</b>, b is <code>k-vector</code> of <b>regression parameters</b> and <code>u</code> is an <code>n-vector</code>
+ * of <b>error terms</b> or <b>residuals</b>.
+ *
+ * The notation is quite standard in literature,
+ * cf eg <a href="http://www.econ.queensu.ca/ETM">Davidson and MacKinnon, Econometrics Theory and Methods, 2004</a>.
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ * @since 2.0
+ */
+public interface MultipleLinearRegression {
+
+    /**
+     * Estimates the regression parameters b.
+     *
+     * @return The [k,1] array representing b
+     */
+    double[] estimateRegressionParameters();
+
+    /**
+     * Estimates the variance of the regression parameters, ie Var(b).
+     *
+     * @return The [k,k] array representing the variance of b
+     */
+    double[][] estimateRegressionParametersVariance();
+
+    /**
+     * Estimates the residuals, ie u = y - X*b.
+     *
+     * @return The [n,1] array representing the residuals
+     */
+    double[] estimateResiduals();
+
+    /**
+     * Returns the variance of the regressand, ie Var(y).
+     *
+     * @return The double representing the variance of y
+     */
+    double estimateRegressandVariance();
+
+    /**
+     * Returns the standard errors of the regression parameters.
+     *
+     * @return standard errors of estimated regression parameters
+     */
+     double[] estimateRegressionParametersStandardErrors();
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java b/src/main/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
new file mode 100644
index 0000000..22a59e8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
@@ -0,0 +1,233 @@
+/*
+ * 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.stat.regression;
+
+import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.linear.LUDecompositionImpl;
+import org.apache.commons.math.linear.QRDecomposition;
+import org.apache.commons.math.linear.QRDecompositionImpl;
+import org.apache.commons.math.linear.RealMatrix;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.stat.StatUtils;
+import org.apache.commons.math.stat.descriptive.moment.SecondMoment;
+
+/**
+ * <p>Implements ordinary least squares (OLS) to estimate the parameters of a
+ * multiple linear regression model.</p>
+ *
+ * <p>The regression coefficients, <code>b</code>, satisfy the normal equations:
+ * <pre><code> X<sup>T</sup> X b = X<sup>T</sup> y </code></pre></p>
+ *
+ * <p>To solve the normal equations, this implementation uses QR decomposition
+ * of the <code>X</code> matrix. (See {@link QRDecompositionImpl} for details on the
+ * decomposition algorithm.) The <code>X</code> matrix, also known as the <i>design matrix,</i>
+ * has rows corresponding to sample observations and columns corresponding to independent
+ * variables.  When the model is estimated using an intercept term (i.e. when
+ * {@link #isNoIntercept() isNoIntercept} is false as it is by default), the <code>X</code>
+ * matrix includes an initial column identically equal to 1.  We solve the normal equations
+ * as follows:
+ * <pre><code> X<sup>T</sup>X b = X<sup>T</sup> y
+ * (QR)<sup>T</sup> (QR) b = (QR)<sup>T</sup>y
+ * R<sup>T</sup> (Q<sup>T</sup>Q) R b = R<sup>T</sup> Q<sup>T</sup> y
+ * R<sup>T</sup> R b = R<sup>T</sup> Q<sup>T</sup> y
+ * (R<sup>T</sup>)<sup>-1</sup> R<sup>T</sup> R b = (R<sup>T</sup>)<sup>-1</sup> R<sup>T</sup> Q<sup>T</sup> y
+ * R b = Q<sup>T</sup> y </code></pre></p>
+ *
+ * <p>Given <code>Q</code> and <code>R</code>, the last equation is solved by back-substitution.</p>
+ *
+ * @version $Revision: 1073464 $ $Date: 2011-02-22 20:35:02 +0100 (mar. 22 févr. 2011) $
+ * @since 2.0
+ */
+public class OLSMultipleLinearRegression extends AbstractMultipleLinearRegression {
+
+    /** Cached QR decomposition of X matrix */
+    private QRDecomposition qr = null;
+
+    /**
+     * Loads model x and y sample data, overriding any previous sample.
+     *
+     * Computes and caches QR decomposition of the X matrix.
+     * @param y the [n,1] array representing the y sample
+     * @param x the [n,k] array representing the x sample
+     * @throws IllegalArgumentException if the x and y array data are not
+     *             compatible for the regression
+     */
+    public void newSampleData(double[] y, double[][] x) {
+        validateSampleData(x, y);
+        newYSampleData(y);
+        newXSampleData(x);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>This implementation computes and caches the QR decomposition of the X matrix.</p>
+     */
+    @Override
+    public void newSampleData(double[] data, int nobs, int nvars) {
+        super.newSampleData(data, nobs, nvars);
+        qr = new QRDecompositionImpl(X);
+    }
+
+    /**
+     * <p>Compute the "hat" matrix.
+     * </p>
+     * <p>The hat matrix is defined in terms of the design matrix X
+     *  by X(X<sup>T</sup>X)<sup>-1</sup>X<sup>T</sup>
+     * </p>
+     * <p>The implementation here uses the QR decomposition to compute the
+     * hat matrix as Q I<sub>p</sub>Q<sup>T</sup> where I<sub>p</sub> is the
+     * p-dimensional identity matrix augmented by 0's.  This computational
+     * formula is from "The Hat Matrix in Regression and ANOVA",
+     * David C. Hoaglin and Roy E. Welsch,
+     * <i>The American Statistician</i>, Vol. 32, No. 1 (Feb., 1978), pp. 17-22.
+     *
+     * @return the hat matrix
+     */
+    public RealMatrix calculateHat() {
+        // Create augmented identity matrix
+        RealMatrix Q = qr.getQ();
+        final int p = qr.getR().getColumnDimension();
+        final int n = Q.getColumnDimension();
+        Array2DRowRealMatrix augI = new Array2DRowRealMatrix(n, n);
+        double[][] augIData = augI.getDataRef();
+        for (int i = 0; i < n; i++) {
+            for (int j =0; j < n; j++) {
+                if (i == j && i < p) {
+                    augIData[i][j] = 1d;
+                } else {
+                    augIData[i][j] = 0d;
+                }
+            }
+        }
+
+        // Compute and return Hat matrix
+        return Q.multiply(augI).multiply(Q.transpose());
+    }
+
+    /**
+     * <p>Returns the sum of squared deviations of Y from its mean.</p>
+     *
+     * <p>If the model has no intercept term, <code>0</code> is used for the
+     * mean of Y - i.e., what is returned is the sum of the squared Y values.</p>
+     *
+     * <p>The value returned by this method is the SSTO value used in
+     * the {@link #calculateRSquared() R-squared} computation.</p>
+     *
+     * @return SSTO - the total sum of squares
+     * @see #isNoIntercept()
+     * @since 2.2
+     */
+    public double calculateTotalSumOfSquares() {
+        if (isNoIntercept()) {
+            return StatUtils.sumSq(Y.getData());
+        } else {
+            return new SecondMoment().evaluate(Y.getData());
+        }
+    }
+
+    /**
+     * Returns the sum of squared residuals.
+     *
+     * @return residual sum of squares
+     * @since 2.2
+     */
+    public double calculateResidualSumOfSquares() {
+        final RealVector residuals = calculateResiduals();
+        return residuals.dotProduct(residuals);
+    }
+
+    /**
+     * Returns the R-Squared statistic, defined by the formula <pre>
+     * R<sup>2</sup> = 1 - SSR / SSTO
+     * </pre>
+     * where SSR is the {@link #calculateResidualSumOfSquares() sum of squared residuals}
+     * and SSTO is the {@link #calculateTotalSumOfSquares() total sum of squares}
+     *
+     * @return R-square statistic
+     * @since 2.2
+     */
+    public double calculateRSquared() {
+        return 1 - calculateResidualSumOfSquares() / calculateTotalSumOfSquares();
+    }
+
+    /**
+     * <p>Returns the adjusted R-squared statistic, defined by the formula <pre>
+     * R<sup>2</sup><sub>adj</sub> = 1 - [SSR (n - 1)] / [SSTO (n - p)]
+     * </pre>
+     * where SSR is the {@link #calculateResidualSumOfSquares() sum of squared residuals},
+     * SSTO is the {@link #calculateTotalSumOfSquares() total sum of squares}, n is the number
+     * of observations and p is the number of parameters estimated (including the intercept).</p>
+     *
+     * <p>If the regression is estimated without an intercept term, what is returned is <pre>
+     * <code> 1 - (1 - {@link #calculateRSquared()}) * (n / (n - p)) </code>
+     * </pre></p>
+     *
+     * @return adjusted R-Squared statistic
+     * @see #isNoIntercept()
+     * @since 2.2
+     */
+    public double calculateAdjustedRSquared() {
+        final double n = X.getRowDimension();
+        if (isNoIntercept()) {
+            return 1 - (1 - calculateRSquared()) * (n / (n - X.getColumnDimension()));
+        } else {
+            return 1 - (calculateResidualSumOfSquares() * (n - 1)) /
+                (calculateTotalSumOfSquares() * (n - X.getColumnDimension()));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>This implementation computes and caches the QR decomposition of the X matrix
+     * once it is successfully loaded.</p>
+     */
+    @Override
+    protected void newXSampleData(double[][] x) {
+        super.newXSampleData(x);
+        qr = new QRDecompositionImpl(X);
+    }
+
+    /**
+     * Calculates the regression coefficients using OLS.
+     *
+     * @return beta
+     */
+    @Override
+    protected RealVector calculateBeta() {
+        return qr.getSolver().solve(Y);
+    }
+
+    /**
+     * <p>Calculates the variance-covariance matrix of the regression parameters.
+     * </p>
+     * <p>Var(b) = (X<sup>T</sup>X)<sup>-1</sup>
+     * </p>
+     * <p>Uses QR decomposition to reduce (X<sup>T</sup>X)<sup>-1</sup>
+     * to (R<sup>T</sup>R)<sup>-1</sup>, with only the top p rows of
+     * R included, where p = the length of the beta vector.</p>
+     *
+     * @return The beta variance-covariance matrix
+     */
+    @Override
+    protected RealMatrix calculateBetaVariance() {
+        int p = X.getColumnDimension();
+        RealMatrix Raug = qr.getR().getSubMatrix(0, p - 1 , 0, p - 1);
+        RealMatrix Rinv = new LUDecompositionImpl(Raug).getSolver().getInverse();
+        return Rinv.multiply(Rinv.transpose());
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/stat/regression/SimpleRegression.java b/src/main/java/org/apache/commons/math/stat/regression/SimpleRegression.java
new file mode 100644
index 0000000..d950541
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/regression/SimpleRegression.java
@@ -0,0 +1,639 @@
+/*
+ * 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.stat.regression;
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.distribution.TDistribution;
+import org.apache.commons.math.distribution.TDistributionImpl;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Estimates an ordinary least squares regression model
+ * with one independent variable.
+ * <p>
+ * <code> y = intercept + slope * x  </code></p>
+ * <p>
+ * Standard errors for <code>intercept</code> and <code>slope</code> are
+ * available as well as ANOVA, r-square and Pearson's r statistics.</p>
+ * <p>
+ * Observations (x,y pairs) can be added to the model one at a time or they
+ * can be provided in a 2-dimensional array.  The observations are not stored
+ * in memory, so there is no limit to the number of observations that can be
+ * added to the model.</p>
+ * <p>
+ * <strong>Usage Notes</strong>: <ul>
+ * <li> When there are fewer than two observations in the model, or when
+ * there is no variation in the x values (i.e. all x values are the same)
+ * all statistics return <code>NaN</code>. At least two observations with
+ * different x coordinates are requred to estimate a bivariate regression
+ * model.
+ * </li>
+ * <li> getters for the statistics always compute values based on the current
+ * set of observations -- i.e., you can get statistics, then add more data
+ * and get updated statistics without using a new instance.  There is no
+ * "compute" method that updates all statistics.  Each of the getters performs
+ * the necessary computations to return the requested statistic.</li>
+ * </ul></p>
+ *
+ * @version $Revision: 1042336 $ $Date: 2010-12-05 13:40:48 +0100 (dim. 05 déc. 2010) $
+ */
+public class SimpleRegression implements Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3004689053607543335L;
+
+    /** the distribution used to compute inference statistics. */
+    private TDistribution distribution;
+
+    /** sum of x values */
+    private double sumX = 0d;
+
+    /** total variation in x (sum of squared deviations from xbar) */
+    private double sumXX = 0d;
+
+    /** sum of y values */
+    private double sumY = 0d;
+
+    /** total variation in y (sum of squared deviations from ybar) */
+    private double sumYY = 0d;
+
+    /** sum of products */
+    private double sumXY = 0d;
+
+    /** number of observations */
+    private long n = 0;
+
+    /** mean of accumulated x values, used in updating formulas */
+    private double xbar = 0;
+
+    /** mean of accumulated y values, used in updating formulas */
+    private double ybar = 0;
+
+    // ---------------------Public methods--------------------------------------
+
+    /**
+     * Create an empty SimpleRegression instance
+     */
+    public SimpleRegression() {
+        this(new TDistributionImpl(1.0));
+    }
+
+    /**
+     * Create an empty SimpleRegression using the given distribution object to
+     * compute inference statistics.
+     * @param t the distribution used to compute inference statistics.
+     * @since 1.2
+     * @deprecated in 2.2 (to be removed in 3.0). Please use the {@link
+     * #SimpleRegression(int) other constructor} instead.
+     */
+    @Deprecated
+    public SimpleRegression(TDistribution t) {
+        super();
+        setDistribution(t);
+    }
+
+    /**
+     * Create an empty SimpleRegression.
+     *
+     * @param degrees Number of degrees of freedom of the distribution
+     * used to compute inference statistics.
+     * @since 2.2
+     */
+    public SimpleRegression(int degrees) {
+        setDistribution(new TDistributionImpl(degrees));
+    }
+
+    /**
+     * Adds the observation (x,y) to the regression data set.
+     * <p>
+     * Uses updating formulas for means and sums of squares defined in
+     * "Algorithms for Computing the Sample Variance: Analysis and
+     * Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J.
+     * 1983, American Statistician, vol. 37, pp. 242-247, referenced in
+     * Weisberg, S. "Applied Linear Regression". 2nd Ed. 1985.</p>
+     *
+     *
+     * @param x independent variable value
+     * @param y dependent variable value
+     */
+    public void addData(double x, double y) {
+        if (n == 0) {
+            xbar = x;
+            ybar = y;
+        } else {
+            double dx = x - xbar;
+            double dy = y - ybar;
+            sumXX += dx * dx * (double) n / (n + 1d);
+            sumYY += dy * dy * (double) n / (n + 1d);
+            sumXY += dx * dy * (double) n / (n + 1d);
+            xbar += dx / (n + 1.0);
+            ybar += dy / (n + 1.0);
+        }
+        sumX += x;
+        sumY += y;
+        n++;
+
+        if (n > 2) {
+            distribution.setDegreesOfFreedom(n - 2);
+        }
+    }
+
+
+    /**
+     * Removes the observation (x,y) from the regression data set.
+     * <p>
+     * Mirrors the addData method.  This method permits the use of
+     * SimpleRegression instances in streaming mode where the regression
+     * is applied to a sliding "window" of observations, however the caller is
+     * responsible for maintaining the set of observations in the window.</p>
+     *
+     * The method has no effect if there are no points of data (i.e. n=0)
+     *
+     * @param x independent variable value
+     * @param y dependent variable value
+     */
+    public void removeData(double x, double y) {
+        if (n > 0) {
+            double dx = x - xbar;
+            double dy = y - ybar;
+            sumXX -= dx * dx * (double) n / (n - 1d);
+            sumYY -= dy * dy * (double) n / (n - 1d);
+            sumXY -= dx * dy * (double) n / (n - 1d);
+            xbar -= dx / (n - 1.0);
+            ybar -= dy / (n - 1.0);
+            sumX -= x;
+            sumY -= y;
+            n--;
+
+            if (n > 2) {
+                distribution.setDegreesOfFreedom(n - 2);
+            }
+        }
+    }
+
+    /**
+     * Adds the observations represented by the elements in
+     * <code>data</code>.
+     * <p>
+     * <code>(data[0][0],data[0][1])</code> will be the first observation, then
+     * <code>(data[1][0],data[1][1])</code>, etc.</p>
+     * <p>
+     * This method does not replace data that has already been added.  The
+     * observations represented by <code>data</code> are added to the existing
+     * dataset.</p>
+     * <p>
+     * To replace all data, use <code>clear()</code> before adding the new
+     * data.</p>
+     *
+     * @param data array of observations to be added
+     */
+    public void addData(double[][] data) {
+        for (int i = 0; i < data.length; i++) {
+            addData(data[i][0], data[i][1]);
+        }
+    }
+
+
+    /**
+     * Removes observations represented by the elements in <code>data</code>.
+      * <p>
+     * If the array is larger than the current n, only the first n elements are
+     * processed.  This method permits the use of SimpleRegression instances in
+     * streaming mode where the regression is applied to a sliding "window" of
+     * observations, however the caller is responsible for maintaining the set
+     * of observations in the window.</p>
+     * <p>
+     * To remove all data, use <code>clear()</code>.</p>
+     *
+     * @param data array of observations to be removed
+     */
+    public void removeData(double[][] data) {
+        for (int i = 0; i < data.length && n > 0; i++) {
+            removeData(data[i][0], data[i][1]);
+        }
+    }
+
+    /**
+     * Clears all data from the model.
+     */
+    public void clear() {
+        sumX = 0d;
+        sumXX = 0d;
+        sumY = 0d;
+        sumYY = 0d;
+        sumXY = 0d;
+        n = 0;
+    }
+
+    /**
+     * Returns the number of observations that have been added to the model.
+     *
+     * @return n number of observations that have been added.
+     */
+    public long getN() {
+        return n;
+    }
+
+    /**
+     * Returns the "predicted" <code>y</code> value associated with the
+     * supplied <code>x</code> value,  based on the data that has been
+     * added to the model when this method is activated.
+     * <p>
+     * <code> predict(x) = intercept + slope * x </code></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>At least two observations (with at least two different x values)
+     * must have been added before invoking this method. If this method is
+     * invoked before a model can be estimated, <code>Double,NaN</code> is
+     * returned.
+     * </li></ul></p>
+     *
+     * @param x input <code>x</code> value
+     * @return predicted <code>y</code> value
+     */
+    public double predict(double x) {
+        double b1 = getSlope();
+        return getIntercept(b1) + b1 * x;
+    }
+
+    /**
+     * Returns the intercept of the estimated regression line.
+     * <p>
+     * The least squares estimate of the intercept is computed using the
+     * <a href="http://www.xycoon.com/estimation4.htm">normal equations</a>.
+     * The intercept is sometimes denoted b0.</p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>At least two observations (with at least two different x values)
+     * must have been added before invoking this method. If this method is
+     * invoked before a model can be estimated, <code>Double,NaN</code> is
+     * returned.
+     * </li></ul></p>
+     *
+     * @return the intercept of the regression line
+     */
+    public double getIntercept() {
+        return getIntercept(getSlope());
+    }
+
+    /**
+    * Returns the slope of the estimated regression line.
+    * <p>
+    * The least squares estimate of the slope is computed using the
+    * <a href="http://www.xycoon.com/estimation4.htm">normal equations</a>.
+    * The slope is sometimes denoted b1.</p>
+    * <p>
+    * <strong>Preconditions</strong>: <ul>
+    * <li>At least two observations (with at least two different x values)
+    * must have been added before invoking this method. If this method is
+    * invoked before a model can be estimated, <code>Double.NaN</code> is
+    * returned.
+    * </li></ul></p>
+    *
+    * @return the slope of the regression line
+    */
+    public double getSlope() {
+        if (n < 2) {
+            return Double.NaN; //not enough data
+        }
+        if (FastMath.abs(sumXX) < 10 * Double.MIN_VALUE) {
+            return Double.NaN; //not enough variation in x
+        }
+        return sumXY / sumXX;
+    }
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/SumOfSquares.htm">
+     * sum of squared errors</a> (SSE) associated with the regression
+     * model.
+     * <p>
+     * The sum is computed using the computational formula</p>
+     * <p>
+     * <code>SSE = SYY - (SXY * SXY / SXX)</code></p>
+     * <p>
+     * where <code>SYY</code> is the sum of the squared deviations of the y
+     * values about their mean, <code>SXX</code> is similarly defined and
+     * <code>SXY</code> is the sum of the products of x and y mean deviations.
+     * </p><p>
+     * The sums are accumulated using the updating algorithm referenced in
+     * {@link #addData}.</p>
+     * <p>
+     * The return value is constrained to be non-negative - i.e., if due to
+     * rounding errors the computational formula returns a negative result,
+     * 0 is returned.</p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>At least two observations (with at least two different x values)
+     * must have been added before invoking this method. If this method is
+     * invoked before a model can be estimated, <code>Double,NaN</code> is
+     * returned.
+     * </li></ul></p>
+     *
+     * @return sum of squared errors associated with the regression model
+     */
+    public double getSumSquaredErrors() {
+        return FastMath.max(0d, sumYY - sumXY * sumXY / sumXX);
+    }
+
+    /**
+     * Returns the sum of squared deviations of the y values about their mean.
+     * <p>
+     * This is defined as SSTO
+     * <a href="http://www.xycoon.com/SumOfSquares.htm">here</a>.</p>
+     * <p>
+     * If <code>n < 2</code>, this returns <code>Double.NaN</code>.</p>
+     *
+     * @return sum of squared deviations of y values
+     */
+    public double getTotalSumSquares() {
+        if (n < 2) {
+            return Double.NaN;
+        }
+        return sumYY;
+    }
+
+    /**
+     * Returns the sum of squared deviations of the x values about their mean.
+     *
+     * If <code>n < 2</code>, this returns <code>Double.NaN</code>.</p>
+     *
+     * @return sum of squared deviations of x values
+     */
+    public double getXSumSquares() {
+        if (n < 2) {
+            return Double.NaN;
+        }
+        return sumXX;
+    }
+
+    /**
+     * Returns the sum of crossproducts, x<sub>i</sub>*y<sub>i</sub>.
+     *
+     * @return sum of cross products
+     */
+    public double getSumOfCrossProducts() {
+        return sumXY;
+    }
+
+    /**
+     * Returns the sum of squared deviations of the predicted y values about
+     * their mean (which equals the mean of y).
+     * <p>
+     * This is usually abbreviated SSR or SSM.  It is defined as SSM
+     * <a href="http://www.xycoon.com/SumOfSquares.htm">here</a></p>
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>At least two observations (with at least two different x values)
+     * must have been added before invoking this method. If this method is
+     * invoked before a model can be estimated, <code>Double.NaN</code> is
+     * returned.
+     * </li></ul></p>
+     *
+     * @return sum of squared deviations of predicted y values
+     */
+    public double getRegressionSumSquares() {
+        return getRegressionSumSquares(getSlope());
+    }
+
+    /**
+     * Returns the sum of squared errors divided by the degrees of freedom,
+     * usually abbreviated MSE.
+     * <p>
+     * If there are fewer than <strong>three</strong> data pairs in the model,
+     * or if there is no variation in <code>x</code>, this returns
+     * <code>Double.NaN</code>.</p>
+     *
+     * @return sum of squared deviations of y values
+     */
+    public double getMeanSquareError() {
+        if (n < 3) {
+            return Double.NaN;
+        }
+        return getSumSquaredErrors() / (n - 2);
+    }
+
+    /**
+     * Returns <a href="http://mathworld.wolfram.com/CorrelationCoefficient.html">
+     * Pearson's product moment correlation coefficient</a>,
+     * usually denoted r.
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>At least two observations (with at least two different x values)
+     * must have been added before invoking this method. If this method is
+     * invoked before a model can be estimated, <code>Double,NaN</code> is
+     * returned.
+     * </li></ul></p>
+     *
+     * @return Pearson's r
+     */
+    public double getR() {
+        double b1 = getSlope();
+        double result = FastMath.sqrt(getRSquare());
+        if (b1 < 0) {
+            result = -result;
+        }
+        return result;
+    }
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/coefficient1.htm">
+     * coefficient of determination</a>,
+     * usually denoted r-square.
+     * <p>
+     * <strong>Preconditions</strong>: <ul>
+     * <li>At least two observations (with at least two different x values)
+     * must have been added before invoking this method. If this method is
+     * invoked before a model can be estimated, <code>Double,NaN</code> is
+     * returned.
+     * </li></ul></p>
+     *
+     * @return r-square
+     */
+    public double getRSquare() {
+        double ssto = getTotalSumSquares();
+        return (ssto - getSumSquaredErrors()) / ssto;
+    }
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/standarderrorb0.htm">
+     * standard error of the intercept estimate</a>,
+     * usually denoted s(b0).
+     * <p>
+     * If there are fewer that <strong>three</strong> observations in the
+     * model, or if there is no variation in x, this returns
+     * <code>Double.NaN</code>.</p>
+     *
+     * @return standard error associated with intercept estimate
+     */
+    public double getInterceptStdErr() {
+        return FastMath.sqrt(
+            getMeanSquareError() * ((1d / (double) n) + (xbar * xbar) / sumXX));
+    }
+
+    /**
+     * Returns the <a href="http://www.xycoon.com/standerrorb(1).htm">standard
+     * error of the slope estimate</a>,
+     * usually denoted s(b1).
+     * <p>
+     * If there are fewer that <strong>three</strong> data pairs in the model,
+     * or if there is no variation in x, this returns <code>Double.NaN</code>.
+     * </p>
+     *
+     * @return standard error associated with slope estimate
+     */
+    public double getSlopeStdErr() {
+        return FastMath.sqrt(getMeanSquareError() / sumXX);
+    }
+
+    /**
+     * Returns the half-width of a 95% confidence interval for the slope
+     * estimate.
+     * <p>
+     * The 95% confidence interval is</p>
+     * <p>
+     * <code>(getSlope() - getSlopeConfidenceInterval(),
+     * getSlope() + getSlopeConfidenceInterval())</code></p>
+     * <p>
+     * If there are fewer that <strong>three</strong> observations in the
+     * model, or if there is no variation in x, this returns
+     * <code>Double.NaN</code>.</p>
+     * <p>
+     * <strong>Usage Note</strong>:<br>
+     * The validity of this statistic depends on the assumption that the
+     * observations included in the model are drawn from a
+     * <a href="http://mathworld.wolfram.com/BivariateNormalDistribution.html">
+     * Bivariate Normal Distribution</a>.</p>
+     *
+     * @return half-width of 95% confidence interval for the slope estimate
+     * @throws MathException if the confidence interval can not be computed.
+     */
+    public double getSlopeConfidenceInterval() throws MathException {
+        return getSlopeConfidenceInterval(0.05d);
+    }
+
+    /**
+     * Returns the half-width of a (100-100*alpha)% confidence interval for
+     * the slope estimate.
+     * <p>
+     * The (100-100*alpha)% confidence interval is </p>
+     * <p>
+     * <code>(getSlope() - getSlopeConfidenceInterval(),
+     * getSlope() + getSlopeConfidenceInterval())</code></p>
+     * <p>
+     * To request, for example, a 99% confidence interval, use
+     * <code>alpha = .01</code></p>
+     * <p>
+     * <strong>Usage Note</strong>:<br>
+     * The validity of this statistic depends on the assumption that the
+     * observations included in the model are drawn from a
+     * <a href="http://mathworld.wolfram.com/BivariateNormalDistribution.html">
+     * Bivariate Normal Distribution</a>.</p>
+     * <p>
+     * <strong> Preconditions:</strong><ul>
+     * <li>If there are fewer that <strong>three</strong> observations in the
+     * model, or if there is no variation in x, this returns
+     * <code>Double.NaN</code>.
+     * </li>
+     * <li><code>(0 < alpha < 1)</code>; otherwise an
+     * <code>IllegalArgumentException</code> is thrown.
+     * </li></ul></p>
+     *
+     * @param alpha the desired significance level
+     * @return half-width of 95% confidence interval for the slope estimate
+     * @throws MathException if the confidence interval can not be computed.
+     */
+    public double getSlopeConfidenceInterval(double alpha)
+        throws MathException {
+        if (alpha >= 1 || alpha <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_BOUND_SIGNIFICANCE_LEVEL,
+                  alpha, 0.0, 1.0);
+        }
+        return getSlopeStdErr() *
+            distribution.inverseCumulativeProbability(1d - alpha / 2d);
+    }
+
+    /**
+     * Returns the significance level of the slope (equiv) correlation.
+     * <p>
+     * Specifically, the returned value is the smallest <code>alpha</code>
+     * such that the slope confidence interval with significance level
+     * equal to <code>alpha</code> does not include <code>0</code>.
+     * On regression output, this is often denoted <code>Prob(|t| > 0)</code>
+     * </p><p>
+     * <strong>Usage Note</strong>:<br>
+     * The validity of this statistic depends on the assumption that the
+     * observations included in the model are drawn from a
+     * <a href="http://mathworld.wolfram.com/BivariateNormalDistribution.html">
+     * Bivariate Normal Distribution</a>.</p>
+     * <p>
+     * If there are fewer that <strong>three</strong> observations in the
+     * model, or if there is no variation in x, this returns
+     * <code>Double.NaN</code>.</p>
+     *
+     * @return significance level for slope/correlation
+     * @throws MathException if the significance level can not be computed.
+     */
+    public double getSignificance() throws MathException {
+        return 2d * (1.0 - distribution.cumulativeProbability(
+                    FastMath.abs(getSlope()) / getSlopeStdErr()));
+    }
+
+    // ---------------------Private methods-----------------------------------
+
+    /**
+    * Returns the intercept of the estimated regression line, given the slope.
+    * <p>
+    * Will return <code>NaN</code> if slope is <code>NaN</code>.</p>
+    *
+    * @param slope current slope
+    * @return the intercept of the regression line
+    */
+    private double getIntercept(double slope) {
+        return (sumY - slope * sumX) / n;
+    }
+
+    /**
+     * Computes SSR from b1.
+     *
+     * @param slope regression slope estimate
+     * @return sum of squared deviations of predicted y values
+     */
+    private double getRegressionSumSquares(double slope) {
+        return slope * slope * sumXX;
+    }
+
+    /**
+     * Modify the distribution used to compute inference statistics.
+     * @param value the new distribution
+     * @since 1.2
+     * @deprecated in 2.2 (to be removed in 3.0).
+     */
+    @Deprecated
+    public void setDistribution(TDistribution value) {
+        distribution = value;
+
+        // modify degrees of freedom
+        if (n > 2) {
+            distribution.setDegreesOfFreedom(n - 2);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/stat/regression/package.html b/src/main/java/org/apache/commons/math/stat/regression/package.html
new file mode 100644
index 0000000..2538c6e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/stat/regression/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>
+      Statistical routines involving multivariate data.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java b/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java
new file mode 100644
index 0000000..bda0fe2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/transform/FastCosineTransformer.java
@@ -0,0 +1,262 @@
+/*
+ * 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.transform;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/
+ * StandardPackages/LinearAlgebra/FourierTrig.html">Fast Cosine Transform</a>
+ * for transformation of one-dimensional data sets. For reference, see
+ * <b>Fast Fourier Transforms</b>, ISBN 0849371635, chapter 3.
+ * <p>
+ * FCT is its own inverse, up to a multiplier depending on conventions.
+ * The equations are listed in the comments of the corresponding methods.</p>
+ * <p>
+ * Different from FFT and FST, FCT requires the length of data set to be
+ * power of 2 plus one. Users should especially pay attention to the
+ * function transformation on how this affects the sampling.</p>
+ * <p>As of version 2.0 this no longer implements Serializable</p>
+ *
+ * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $
+ * @since 1.2
+ */
+public class FastCosineTransformer implements RealTransformer {
+
+    /**
+     * Construct a default transformer.
+     */
+    public FastCosineTransformer() {
+        super();
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>
+     * The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
+     *                        &sum;<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be transformed
+     * @return the real transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform(double f[]) throws IllegalArgumentException {
+        return fct(f);
+    }
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
+     *                        &sum;<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform(UnivariateRealFunction f,
+                              double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+        double data[] = FastFourierTransformer.sample(f, min, max, n);
+        return fct(data);
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>
+     * The formula is F<sub>n</sub> = &radic;(1/2N) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
+     *                        &radic;(2/N) &sum;<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be transformed
+     * @return the real transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform2(double f[]) throws IllegalArgumentException {
+
+        double scaling_coefficient = FastMath.sqrt(2.0 / (f.length-1));
+        return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient);
+    }
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is F<sub>n</sub> = &radic;(1/2N) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] +
+     *                        &radic;(2/N) &sum;<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(&pi; nk/N)
+     *
+     * </p>
+     *
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform2(UnivariateRealFunction f,
+                               double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = FastFourierTransformer.sample(f, min, max, n);
+        double scaling_coefficient = FastMath.sqrt(2.0 / (n-1));
+        return FastFourierTransformer.scaleArray(fct(data), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real data set.
+     * <p>
+     * The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
+     *                        (2/N) &sum;<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be inversely transformed
+     * @return the real inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform(double f[]) throws IllegalArgumentException {
+
+        double scaling_coefficient = 2.0 / (f.length - 1);
+        return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
+     *                        (2/N) &sum;<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform(UnivariateRealFunction f,
+                                     double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = FastFourierTransformer.sample(f, min, max, n);
+        double scaling_coefficient = 2.0 / (n - 1);
+        return FastFourierTransformer.scaleArray(fct(data), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real data set.
+     * <p>
+     * The formula is f<sub>k</sub> = &radic;(1/2N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
+     *                        &radic;(2/N) &sum;<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be inversely transformed
+     * @return the real inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform2(double f[]) throws IllegalArgumentException {
+        return transform2(f);
+    }
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is f<sub>k</sub> = &radic;(1/2N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] +
+     *                        &radic;(2/N) &sum;<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform2(UnivariateRealFunction f,
+                                      double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        return transform2(f, min, max, n);
+    }
+
+    /**
+     * Perform the FCT algorithm (including inverse).
+     *
+     * @param f the real data array to be transformed
+     * @return the real transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    protected double[] fct(double f[])
+        throws IllegalArgumentException {
+
+        final double transformed[] = new double[f.length];
+
+        final int n = f.length - 1;
+        if (!FastFourierTransformer.isPowerOf2(n)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POWER_OF_TWO_PLUS_ONE,
+                    f.length);
+        }
+        if (n == 1) {       // trivial case
+            transformed[0] = 0.5 * (f[0] + f[1]);
+            transformed[1] = 0.5 * (f[0] - f[1]);
+            return transformed;
+        }
+
+        // construct a new array and perform FFT on it
+        final double[] x = new double[n];
+        x[0] = 0.5 * (f[0] + f[n]);
+        x[n >> 1] = f[n >> 1];
+        double t1 = 0.5 * (f[0] - f[n]);   // temporary variable for transformed[1]
+        for (int i = 1; i < (n >> 1); i++) {
+            final double a = 0.5 * (f[i] + f[n-i]);
+            final double b = FastMath.sin(i * FastMath.PI / n) * (f[i] - f[n-i]);
+            final double c = FastMath.cos(i * FastMath.PI / n) * (f[i] - f[n-i]);
+            x[i] = a - b;
+            x[n-i] = a + b;
+            t1 += c;
+        }
+        FastFourierTransformer transformer = new FastFourierTransformer();
+        Complex y[] = transformer.transform(x);
+
+        // reconstruct the FCT result for the original array
+        transformed[0] = y[0].getReal();
+        transformed[1] = t1;
+        for (int i = 1; i < (n >> 1); i++) {
+            transformed[2 * i]     = y[i].getReal();
+            transformed[2 * i + 1] = transformed[2 * i - 1] - y[i].getImaginary();
+        }
+        transformed[n] = y[n >> 1].getReal();
+
+        return transformed;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java b/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java
new file mode 100644
index 0000000..e6ced5e
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/transform/FastFourierTransformer.java
@@ -0,0 +1,912 @@
+/*
+ * 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.transform;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://mathworld.wolfram.com/FastFourierTransform.html">
+ * Fast Fourier Transform</a> for transformation of one-dimensional data sets.
+ * For reference, see <b>Applied Numerical Linear Algebra</b>, ISBN 0898713897,
+ * chapter 6.
+ * <p>
+ * There are several conventions for the definition of FFT and inverse FFT,
+ * mainly on different coefficient and exponent. Here the equations are listed
+ * in the comments of the corresponding methods.</p>
+ * <p>
+ * We require the length of data set to be power of 2, this greatly simplifies
+ * and speeds up the code. Users can pad the data with zeros to meet this
+ * requirement. There are other flavors of FFT, for reference, see S. Winograd,
+ * <i>On computing the discrete Fourier transform</i>, Mathematics of Computation,
+ * 32 (1978), 175 - 199.</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class FastFourierTransformer implements Serializable {
+
+    /** Serializable version identifier. */
+    static final long serialVersionUID = 5138259215438106000L;
+
+    /** roots of unity */
+    private RootsOfUnity roots = new RootsOfUnity();
+
+    /**
+     * Construct a default transformer.
+     */
+    public FastFourierTransformer() {
+        super();
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>
+     * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $
+     * </p>
+     *
+     * @param f the real data array to be transformed
+     * @return the complex transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] transform(double f[])
+        throws IllegalArgumentException {
+        return fft(f, false);
+    }
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $
+     * </p>
+     *
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the complex transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] transform(UnivariateRealFunction f,
+                               double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+        double data[] = sample(f, min, max, n);
+        return fft(data, false);
+    }
+
+    /**
+     * Transform the given complex data set.
+     * <p>
+     * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $
+     * </p>
+     *
+     * @param f the complex data array to be transformed
+     * @return the complex transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] transform(Complex f[])
+        throws IllegalArgumentException {
+        roots.computeOmega(f.length);
+        return fft(f);
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>
+     * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$
+     * </p>
+     *
+     * @param f the real data array to be transformed
+     * @return the complex transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] transform2(double f[])
+        throws IllegalArgumentException {
+
+        double scaling_coefficient = 1.0 / FastMath.sqrt(f.length);
+        return scaleArray(fft(f, false), scaling_coefficient);
+    }
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$
+     * </p>
+     *
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the complex transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] transform2(UnivariateRealFunction f,
+                                double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = sample(f, min, max, n);
+        double scaling_coefficient = 1.0 / FastMath.sqrt(n);
+        return scaleArray(fft(data, false), scaling_coefficient);
+    }
+
+    /**
+     * Transform the given complex data set.
+     * <p>
+     * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$
+     * </p>
+     *
+     * @param f the complex data array to be transformed
+     * @return the complex transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] transform2(Complex f[])
+        throws IllegalArgumentException {
+
+        roots.computeOmega(f.length);
+        double scaling_coefficient = 1.0 / FastMath.sqrt(f.length);
+        return scaleArray(fft(f), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real data set.
+     * <p>
+     * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $
+     * </p>
+     *
+     * @param f the real data array to be inversely transformed
+     * @return the complex inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] inversetransform(double f[])
+        throws IllegalArgumentException {
+
+        double scaling_coefficient = 1.0 / f.length;
+        return scaleArray(fft(f, true), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $
+     * </p>
+     *
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the complex inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] inversetransform(UnivariateRealFunction f,
+                                      double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = sample(f, min, max, n);
+        double scaling_coefficient = 1.0 / n;
+        return scaleArray(fft(data, true), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given complex data set.
+     * <p>
+     * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $
+     * </p>
+     *
+     * @param f the complex data array to be inversely transformed
+     * @return the complex inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] inversetransform(Complex f[])
+        throws IllegalArgumentException {
+
+        roots.computeOmega(-f.length);    // pass negative argument
+        double scaling_coefficient = 1.0 / f.length;
+        return scaleArray(fft(f), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real data set.
+     * <p>
+     * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$
+     * </p>
+     *
+     * @param f the real data array to be inversely transformed
+     * @return the complex inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] inversetransform2(double f[])
+        throws IllegalArgumentException {
+
+        double scaling_coefficient = 1.0 / FastMath.sqrt(f.length);
+        return scaleArray(fft(f, true), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$
+     * </p>
+     *
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the complex inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] inversetransform2(UnivariateRealFunction f,
+                                       double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = sample(f, min, max, n);
+        double scaling_coefficient = 1.0 / FastMath.sqrt(n);
+        return scaleArray(fft(data, true), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given complex data set.
+     * <p>
+     * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$
+     * </p>
+     *
+     * @param f the complex data array to be inversely transformed
+     * @return the complex inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public Complex[] inversetransform2(Complex f[])
+        throws IllegalArgumentException {
+
+        roots.computeOmega(-f.length);    // pass negative argument
+        double scaling_coefficient = 1.0 / FastMath.sqrt(f.length);
+        return scaleArray(fft(f), scaling_coefficient);
+    }
+
+    /**
+     * Perform the base-4 Cooley-Tukey FFT algorithm (including inverse).
+     *
+     * @param f the real data array to be transformed
+     * @param isInverse the indicator of forward or inverse transform
+     * @return the complex transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    protected Complex[] fft(double f[], boolean isInverse)
+        throws IllegalArgumentException {
+
+        verifyDataSet(f);
+        Complex F[] = new Complex[f.length];
+        if (f.length == 1) {
+            F[0] = new Complex(f[0], 0.0);
+            return F;
+        }
+
+        // Rather than the naive real to complex conversion, pack 2N
+        // real numbers into N complex numbers for better performance.
+        int N = f.length >> 1;
+        Complex c[] = new Complex[N];
+        for (int i = 0; i < N; i++) {
+            c[i] = new Complex(f[2*i], f[2*i+1]);
+        }
+        roots.computeOmega(isInverse ? -N : N);
+        Complex z[] = fft(c);
+
+        // reconstruct the FFT result for the original array
+        roots.computeOmega(isInverse ? -2*N : 2*N);
+        F[0] = new Complex(2 * (z[0].getReal() + z[0].getImaginary()), 0.0);
+        F[N] = new Complex(2 * (z[0].getReal() - z[0].getImaginary()), 0.0);
+        for (int i = 1; i < N; i++) {
+            Complex A = z[N-i].conjugate();
+            Complex B = z[i].add(A);
+            Complex C = z[i].subtract(A);
+            //Complex D = roots.getOmega(i).multiply(Complex.I);
+            Complex D = new Complex(-roots.getOmegaImaginary(i),
+                                    roots.getOmegaReal(i));
+            F[i] = B.subtract(C.multiply(D));
+            F[2*N-i] = F[i].conjugate();
+        }
+
+        return scaleArray(F, 0.5);
+    }
+
+    /**
+     * Perform the base-4 Cooley-Tukey FFT algorithm (including inverse).
+     *
+     * @param data the complex data array to be transformed
+     * @return the complex transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    protected Complex[] fft(Complex data[])
+        throws IllegalArgumentException {
+
+        final int n = data.length;
+        final Complex f[] = new Complex[n];
+
+        // initial simple cases
+        verifyDataSet(data);
+        if (n == 1) {
+            f[0] = data[0];
+            return f;
+        }
+        if (n == 2) {
+            f[0] = data[0].add(data[1]);
+            f[1] = data[0].subtract(data[1]);
+            return f;
+        }
+
+        // permute original data array in bit-reversal order
+        int ii = 0;
+        for (int i = 0; i < n; i++) {
+            f[i] = data[ii];
+            int k = n >> 1;
+            while (ii >= k && k > 0) {
+                ii -= k; k >>= 1;
+            }
+            ii += k;
+        }
+
+        // the bottom base-4 round
+        for (int i = 0; i < n; i += 4) {
+            final Complex a = f[i].add(f[i+1]);
+            final Complex b = f[i+2].add(f[i+3]);
+            final Complex c = f[i].subtract(f[i+1]);
+            final Complex d = f[i+2].subtract(f[i+3]);
+            final Complex e1 = c.add(d.multiply(Complex.I));
+            final Complex e2 = c.subtract(d.multiply(Complex.I));
+            f[i] = a.add(b);
+            f[i+2] = a.subtract(b);
+            // omegaCount indicates forward or inverse transform
+            f[i+1] = roots.isForward() ? e2 : e1;
+            f[i+3] = roots.isForward() ? e1 : e2;
+        }
+
+        // iterations from bottom to top take O(N*logN) time
+        for (int i = 4; i < n; i <<= 1) {
+            final int m = n / (i<<1);
+            for (int j = 0; j < n; j += i<<1) {
+                for (int k = 0; k < i; k++) {
+                    //z = f[i+j+k].multiply(roots.getOmega(k*m));
+                    final int k_times_m = k*m;
+                    final double omega_k_times_m_real = roots.getOmegaReal(k_times_m);
+                    final double omega_k_times_m_imaginary = roots.getOmegaImaginary(k_times_m);
+                    //z = f[i+j+k].multiply(omega[k*m]);
+                    final Complex z = new Complex(
+                        f[i+j+k].getReal() * omega_k_times_m_real -
+                        f[i+j+k].getImaginary() * omega_k_times_m_imaginary,
+                        f[i+j+k].getReal() * omega_k_times_m_imaginary +
+                        f[i+j+k].getImaginary() * omega_k_times_m_real);
+
+                    f[i+j+k] = f[j+k].subtract(z);
+                    f[j+k] = f[j+k].add(z);
+                }
+            }
+        }
+        return f;
+    }
+
+    /**
+     * Sample the given univariate real function on the given interval.
+     * <p>
+     * The interval is divided equally into N sections and sample points
+     * are taken from min to max-(max-min)/N. Usually f(x) is periodic
+     * such that f(min) = f(max) (note max is not sampled), but we don't
+     * require that.</p>
+     *
+     * @param f the function to be sampled
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the samples array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public static double[] sample(UnivariateRealFunction f, double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        if (n <= 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POSITIVE_NUMBER_OF_SAMPLES,
+                    n);
+        }
+        verifyInterval(min, max);
+
+        double s[] = new double[n];
+        double h = (max - min) / n;
+        for (int i = 0; i < n; i++) {
+            s[i] = f.value(min + i * h);
+        }
+        return s;
+    }
+
+    /**
+     * Multiply every component in the given real array by the
+     * given real number. The change is made in place.
+     *
+     * @param f the real array to be scaled
+     * @param d the real scaling coefficient
+     * @return a reference to the scaled array
+     */
+    public static double[] scaleArray(double f[], double d) {
+        for (int i = 0; i < f.length; i++) {
+            f[i] *= d;
+        }
+        return f;
+    }
+
+    /**
+     * Multiply every component in the given complex array by the
+     * given real number. The change is made in place.
+     *
+     * @param f the complex array to be scaled
+     * @param d the real scaling coefficient
+     * @return a reference to the scaled array
+     */
+    public static Complex[] scaleArray(Complex f[], double d) {
+        for (int i = 0; i < f.length; i++) {
+            f[i] = new Complex(d * f[i].getReal(), d * f[i].getImaginary());
+        }
+        return f;
+    }
+
+    /**
+     * Returns true if the argument is power of 2.
+     *
+     * @param n the number to test
+     * @return true if the argument is power of 2
+     */
+    public static boolean isPowerOf2(long n) {
+        return (n > 0) && ((n & (n - 1)) == 0);
+    }
+
+    /**
+     * Verifies that the data set has length of power of 2.
+     *
+     * @param d the data array
+     * @throws IllegalArgumentException if array length is not power of 2
+     */
+    public static void verifyDataSet(double d[]) throws IllegalArgumentException {
+        if (!isPowerOf2(d.length)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POWER_OF_TWO_CONSIDER_PADDING, d.length);
+        }
+    }
+
+    /**
+     * Verifies that the data set has length of power of 2.
+     *
+     * @param o the data array
+     * @throws IllegalArgumentException if array length is not power of 2
+     */
+    public static void verifyDataSet(Object o[]) throws IllegalArgumentException {
+        if (!isPowerOf2(o.length)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POWER_OF_TWO_CONSIDER_PADDING, o.length);
+        }
+    }
+
+    /**
+     * Verifies that the endpoints specify an interval.
+     *
+     * @param lower lower endpoint
+     * @param upper upper endpoint
+     * @throws IllegalArgumentException if not interval
+     */
+    public static void verifyInterval(double lower, double upper)
+        throws IllegalArgumentException {
+
+        if (lower >= upper) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
+                    lower, upper);
+        }
+    }
+
+    /**
+     * Performs a multi-dimensional Fourier transform on a given array.
+     * Use {@link #inversetransform2(Complex[])} and
+     * {@link #transform2(Complex[])} in a row-column implementation
+     * in any number of dimensions with O(N&times;log(N)) complexity with
+     * N=n<sub>1</sub>&times;n<sub>2</sub>&times;n<sub>3</sub>&times;...&times;n<sub>d</sub>,
+     * n<sub>x</sub>=number of elements in dimension x,
+     * and d=total number of dimensions.
+     *
+     * @param mdca Multi-Dimensional Complex Array id est Complex[][][][]
+     * @param forward inverseTransform2 is preformed if this is false
+     * @return transform of mdca as a Multi-Dimensional Complex Array id est Complex[][][][]
+     * @throws IllegalArgumentException if any dimension is not a power of two
+     */
+    public Object mdfft(Object mdca, boolean forward)
+        throws IllegalArgumentException {
+        MultiDimensionalComplexMatrix mdcm = (MultiDimensionalComplexMatrix)
+                new MultiDimensionalComplexMatrix(mdca).clone();
+        int[] dimensionSize = mdcm.getDimensionSizes();
+        //cycle through each dimension
+        for (int i = 0; i < dimensionSize.length; i++) {
+            mdfft(mdcm, forward, i, new int[0]);
+        }
+        return mdcm.getArray();
+    }
+
+    /**
+     * Performs one dimension of a multi-dimensional Fourier transform.
+     *
+     * @param mdcm input matrix
+     * @param forward inverseTransform2 is preformed if this is false
+     * @param d index of the dimension to process
+     * @param subVector recursion subvector
+     * @throws IllegalArgumentException if any dimension is not a power of two
+     */
+    private void mdfft(MultiDimensionalComplexMatrix mdcm, boolean forward,
+                       int d, int[] subVector)
+        throws IllegalArgumentException {
+        int[] dimensionSize = mdcm.getDimensionSizes();
+        //if done
+        if (subVector.length == dimensionSize.length) {
+            Complex[] temp = new Complex[dimensionSize[d]];
+            for (int i = 0; i < dimensionSize[d]; i++) {
+                //fft along dimension d
+                subVector[d] = i;
+                temp[i] = mdcm.get(subVector);
+            }
+
+            if (forward)
+                temp = transform2(temp);
+            else
+                temp = inversetransform2(temp);
+
+            for (int i = 0; i < dimensionSize[d]; i++) {
+                subVector[d] = i;
+                mdcm.set(temp[i], subVector);
+            }
+        } else {
+            int[] vector = new int[subVector.length + 1];
+            System.arraycopy(subVector, 0, vector, 0, subVector.length);
+            if (subVector.length == d) {
+                //value is not important once the recursion is done.
+                //then an fft will be applied along the dimension d.
+                vector[d] = 0;
+                mdfft(mdcm, forward, d, vector);
+            } else {
+                for (int i = 0; i < dimensionSize[subVector.length]; i++) {
+                    vector[subVector.length] = i;
+                    //further split along the next dimension
+                    mdfft(mdcm, forward, d, vector);
+                }
+            }
+        }
+        return;
+    }
+
+    /**
+     * Complex matrix implementation.
+     * Not designed for synchronized access
+     * may eventually be replaced by jsr-83 of the java community process
+     * http://jcp.org/en/jsr/detail?id=83
+     * may require additional exception throws for other basic requirements.
+     */
+    private static class MultiDimensionalComplexMatrix
+        implements Cloneable {
+
+        /** Size in all dimensions. */
+        protected int[] dimensionSize;
+
+        /** Storage array. */
+        protected Object multiDimensionalComplexArray;
+
+        /** Simple constructor.
+         * @param multiDimensionalComplexArray array containing the matrix elements
+         */
+        public MultiDimensionalComplexMatrix(Object multiDimensionalComplexArray) {
+
+            this.multiDimensionalComplexArray = multiDimensionalComplexArray;
+
+            // count dimensions
+            int numOfDimensions = 0;
+            for (Object lastDimension = multiDimensionalComplexArray;
+                 lastDimension instanceof Object[];) {
+                final Object[] array = (Object[]) lastDimension;
+                numOfDimensions++;
+                lastDimension = array[0];
+            }
+
+            // allocate array with exact count
+            dimensionSize = new int[numOfDimensions];
+
+            // fill array
+            numOfDimensions = 0;
+            for (Object lastDimension = multiDimensionalComplexArray;
+                 lastDimension instanceof Object[];) {
+                final Object[] array = (Object[]) lastDimension;
+                dimensionSize[numOfDimensions++] = array.length;
+                lastDimension = array[0];
+            }
+
+        }
+
+        /**
+         * Get a matrix element.
+         * @param vector indices of the element
+         * @return matrix element
+         * @exception IllegalArgumentException if dimensions do not match
+         */
+        public Complex get(int... vector)
+            throws IllegalArgumentException {
+            if (vector == null) {
+                if (dimensionSize.length > 0) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, 0, dimensionSize.length);
+                }
+                return null;
+            }
+            if (vector.length != dimensionSize.length) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, vector.length, dimensionSize.length);
+            }
+
+            Object lastDimension = multiDimensionalComplexArray;
+
+            for (int i = 0; i < dimensionSize.length; i++) {
+                lastDimension = ((Object[]) lastDimension)[vector[i]];
+            }
+            return (Complex) lastDimension;
+        }
+
+        /**
+         * Set a matrix element.
+         * @param magnitude magnitude of the element
+         * @param vector indices of the element
+         * @return the previous value
+         * @exception IllegalArgumentException if dimensions do not match
+         */
+        public Complex set(Complex magnitude, int... vector)
+            throws IllegalArgumentException {
+            if (vector == null) {
+                if (dimensionSize.length > 0) {
+                    throw MathRuntimeException.createIllegalArgumentException(
+                            LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, 0, dimensionSize.length);
+                }
+                return null;
+            }
+            if (vector.length != dimensionSize.length) {
+                throw MathRuntimeException.createIllegalArgumentException(
+                        LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, vector.length,dimensionSize.length);
+            }
+
+            Object[] lastDimension = (Object[]) multiDimensionalComplexArray;
+            for (int i = 0; i < dimensionSize.length - 1; i++) {
+                lastDimension = (Object[]) lastDimension[vector[i]];
+            }
+
+            Complex lastValue = (Complex) lastDimension[vector[dimensionSize.length - 1]];
+            lastDimension[vector[dimensionSize.length - 1]] = magnitude;
+
+            return lastValue;
+        }
+
+        /**
+         * Get the size in all dimensions.
+         * @return size in all dimensions
+         */
+        public int[] getDimensionSizes() {
+            return dimensionSize.clone();
+        }
+
+        /**
+         * Get the underlying storage array
+         * @return underlying storage array
+         */
+        public Object getArray() {
+            return multiDimensionalComplexArray;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public Object clone() {
+            MultiDimensionalComplexMatrix mdcm =
+                    new MultiDimensionalComplexMatrix(Array.newInstance(
+                    Complex.class, dimensionSize));
+            clone(mdcm);
+            return mdcm;
+        }
+
+        /**
+         * Copy contents of current array into mdcm.
+         * @param mdcm array where to copy data
+         */
+        private void clone(MultiDimensionalComplexMatrix mdcm) {
+            int[] vector = new int[dimensionSize.length];
+            int size = 1;
+            for (int i = 0; i < dimensionSize.length; i++) {
+                size *= dimensionSize[i];
+            }
+            int[][] vectorList = new int[size][dimensionSize.length];
+            for (int[] nextVector: vectorList) {
+                System.arraycopy(vector, 0, nextVector, 0,
+                                 dimensionSize.length);
+                for (int i = 0; i < dimensionSize.length; i++) {
+                    vector[i]++;
+                    if (vector[i] < dimensionSize[i]) {
+                        break;
+                    } else {
+                        vector[i] = 0;
+                    }
+                }
+            }
+
+            for (int[] nextVector: vectorList) {
+                mdcm.set(get(nextVector), nextVector);
+            }
+        }
+    }
+
+
+    /** Computes the n<sup>th</sup> roots of unity.
+     * A cache of already computed values is maintained.
+     */
+    private static class RootsOfUnity implements Serializable {
+
+      /** Serializable version id. */
+      private static final long serialVersionUID = 6404784357747329667L;
+
+      /** Number of roots of unity. */
+      private int      omegaCount;
+
+      /** Real part of the roots. */
+      private double[] omegaReal;
+
+      /** Imaginary part of the roots for forward transform. */
+      private double[] omegaImaginaryForward;
+
+      /** Imaginary part of the roots for reverse transform. */
+      private double[] omegaImaginaryInverse;
+
+      /** Forward/reverse indicator. */
+      private boolean  isForward;
+
+      /**
+       * Build an engine for computing then <sup>th</sup> roots of unity
+       */
+      public RootsOfUnity() {
+
+        omegaCount = 0;
+        omegaReal = null;
+        omegaImaginaryForward = null;
+        omegaImaginaryInverse = null;
+        isForward = true;
+
+      }
+
+      /**
+       * Check if computation has been done for forward or reverse transform.
+       * @return true if computation has been done for forward transform
+       * @throws IllegalStateException if no roots of unity have been computed yet
+       */
+      public synchronized boolean isForward() throws IllegalStateException {
+
+        if (omegaCount == 0) {
+          throw MathRuntimeException.createIllegalStateException(LocalizedFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET);
+        }
+        return isForward;
+
+      }
+
+      /** Computes the n<sup>th</sup> roots of unity.
+       * <p>The computed omega[] = { 1, w, w<sup>2</sup>, ... w<sup>(n-1)</sup> } where
+       * w = exp(-2 &pi; i / n), i = &sqrt;(-1).</p>
+       * <p>Note that n is positive for
+       * forward transform and negative for inverse transform.</p>
+       * @param n number of roots of unity to compute,
+       * positive for forward transform, negative for inverse transform
+       * @throws IllegalArgumentException if n = 0
+       */
+      public synchronized void computeOmega(int n) throws IllegalArgumentException {
+
+        if (n == 0) {
+          throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.CANNOT_COMPUTE_0TH_ROOT_OF_UNITY);
+        }
+
+        isForward = n > 0;
+
+        // avoid repetitive calculations
+        final int absN = FastMath.abs(n);
+
+        if (absN == omegaCount) {
+            return;
+        }
+
+        // calculate everything from scratch, for both forward and inverse versions
+        final double t    = 2.0 * FastMath.PI / absN;
+        final double cosT = FastMath.cos(t);
+        final double sinT = FastMath.sin(t);
+        omegaReal             = new double[absN];
+        omegaImaginaryForward = new double[absN];
+        omegaImaginaryInverse = new double[absN];
+        omegaReal[0]             = 1.0;
+        omegaImaginaryForward[0] = 0.0;
+        omegaImaginaryInverse[0] = 0.0;
+        for (int i = 1; i < absN; i++) {
+          omegaReal[i] =
+            omegaReal[i-1] * cosT + omegaImaginaryForward[i-1] * sinT;
+          omegaImaginaryForward[i] =
+             omegaImaginaryForward[i-1] * cosT - omegaReal[i-1] * sinT;
+          omegaImaginaryInverse[i] = -omegaImaginaryForward[i];
+        }
+        omegaCount = absN;
+
+      }
+
+      /**
+       * Get the real part of the k<sup>th</sup> n<sup>th</sup> root of unity
+       * @param k index of the n<sup>th</sup> root of unity
+       * @return real part of the k<sup>th</sup> n<sup>th</sup> root of unity
+       * @throws IllegalStateException if no roots of unity have been computed yet
+       * @throws IllegalArgumentException if k is out of range
+       */
+      public synchronized double getOmegaReal(int k)
+        throws IllegalStateException, IllegalArgumentException {
+
+        if (omegaCount == 0) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET);
+        }
+        if ((k < 0) || (k >= omegaCount)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.OUT_OF_RANGE_ROOT_OF_UNITY_INDEX, k, 0, omegaCount - 1);
+        }
+
+        return omegaReal[k];
+
+      }
+
+      /**
+       * Get the imaginary part of the k<sup>th</sup> n<sup>th</sup> root of unity
+       * @param k index of the n<sup>th</sup> root of unity
+       * @return imaginary part of the k<sup>th</sup> n<sup>th</sup> root of unity
+       * @throws IllegalStateException if no roots of unity have been computed yet
+       * @throws IllegalArgumentException if k is out of range
+       */
+      public synchronized double getOmegaImaginary(int k)
+        throws IllegalStateException, IllegalArgumentException {
+
+        if (omegaCount == 0) {
+            throw MathRuntimeException.createIllegalStateException(LocalizedFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET);
+        }
+        if ((k < 0) || (k >= omegaCount)) {
+          throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.OUT_OF_RANGE_ROOT_OF_UNITY_INDEX, k, 0, omegaCount - 1);
+        }
+
+        return isForward ? omegaImaginaryForward[k] : omegaImaginaryInverse[k];
+
+      }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/transform/FastHadamardTransformer.java b/src/main/java/org/apache/commons/math/transform/FastHadamardTransformer.java
new file mode 100644
index 0000000..db79c99
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/transform/FastHadamardTransformer.java
@@ -0,0 +1,252 @@
+/*
+ * 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.transform;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Implements the <a href="http://www.archive.chipcenter.com/dsp/DSP000517F1.html">Fast Hadamard Transform</a> (FHT).
+ * Transformation of an input vector x to the output vector y.
+ * <p>In addition to transformation of real vectors, the Hadamard transform can
+ * transform integer vectors into integer vectors. However, this integer transform
+ * cannot be inverted directly. Due to a scaling factor it may lead to rational results.
+ * As an example, the inverse transform of integer vector (0, 1, 0, 1) is rational
+ * vector (1/2, -1/2, 0, 0).</p>
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public class FastHadamardTransformer implements RealTransformer {
+
+    /** {@inheritDoc} */
+    public double[] transform(double f[])
+        throws IllegalArgumentException {
+        return fht(f);
+    }
+
+    /** {@inheritDoc} */
+    public double[] transform(UnivariateRealFunction f,
+                              double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+        return fht(FastFourierTransformer.sample(f, min, max, n));
+    }
+
+    /** {@inheritDoc} */
+    public double[] inversetransform(double f[])
+    throws IllegalArgumentException {
+        return FastFourierTransformer.scaleArray(fht(f), 1.0 / f.length);
+   }
+
+    /** {@inheritDoc} */
+    public double[] inversetransform(UnivariateRealFunction f,
+                                     double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+        final double[] unscaled =
+            fht(FastFourierTransformer.sample(f, min, max, n));
+        return FastFourierTransformer.scaleArray(unscaled, 1.0 / n);
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>The integer transform cannot be inverted directly, due to a scaling
+     * factor it may lead to double results.</p>
+     * @param f the integer data array to be transformed (signal)
+     * @return the integer transformed array (spectrum)
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public int[] transform(int f[])
+        throws IllegalArgumentException {
+        return fht(f);
+    }
+
+    /**
+     * The FHT (Fast Hadamard Transformation) which uses only subtraction and addition.
+     * <br>
+     * Requires <b>Nlog2N = n2</b><sup>n</sup> additions.
+     * <br>
+     * <br>
+     * <b><u>Short Table of manual calculation for N=8:</u></b>
+     * <ol>
+     * <li><b>x</b> is the input vector we want to transform</li>
+     * <li><b>y</b> is the output vector which is our desired result</li>
+     * <li>a and b are just helper rows</li>
+     * </ol>
+     * <pre>
+     * <code>
+     * +----+----------+---------+----------+
+     * | <b>x</b>  |    <b>a</b>     |    <b>b</b>    |    <b>y</b>     |
+     * +----+----------+---------+----------+
+     * | x<sub>0</sub> | a<sub>0</sub>=x<sub>0</sub>+x<sub>1</sub> | b<sub>0</sub>=a<sub>0</sub>+a<sub>1</sub> | y<sub>0</sub>=b<sub>0</sub>+b<sub>1</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>1</sub> | a<sub>1</sub>=x<sub>2</sub>+x<sub>3</sub> | b<sub>0</sub>=a<sub>2</sub>+a<sub>3</sub> | y<sub>0</sub>=b<sub>2</sub>+b<sub>3</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>2</sub> | a<sub>2</sub>=x<sub>4</sub>+x<sub>5</sub> | b<sub>0</sub>=a<sub>4</sub>+a<sub>5</sub> | y<sub>0</sub>=b<sub>4</sub>+b<sub>5</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>3</sub> | a<sub>3</sub>=x<sub>6</sub>+x<sub>7</sub> | b<sub>0</sub>=a<sub>6</sub>+a<sub>7</sub> | y<sub>0</sub>=b<sub>6</sub>+b<sub>7</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>4</sub> | a<sub>0</sub>=x<sub>0</sub>-x<sub>1</sub> | b<sub>0</sub>=a<sub>0</sub>-a<sub>1</sub> | y<sub>0</sub>=b<sub>0</sub>-b<sub>1</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>5</sub> | a<sub>1</sub>=x<sub>2</sub>-x<sub>3</sub> | b<sub>0</sub>=a<sub>2</sub>-a<sub>3</sub> | y<sub>0</sub>=b<sub>2</sub>-b<sub>3</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>6</sub> | a<sub>2</sub>=x<sub>4</sub>-x<sub>5</sub> | b<sub>0</sub>=a<sub>4</sub>-a<sub>5</sub> | y<sub>0</sub>=b<sub>4</sub>-b<sub>5</sub> |
+     * +----+----------+---------+----------+
+     * | x<sub>7</sub> | a<sub>3</sub>=x<sub>6</sub>-x<sub>7</sub> | b<sub>0</sub>=a<sub>6</sub>-a<sub>7</sub> | y<sub>0</sub>=b<sub>6</sub>-b<sub>7</sub> |
+     * +----+----------+---------+----------+
+     * </code>
+     * </pre>
+     *
+     * <b><u>How it works</u></b>
+     * <ol>
+     * <li>Construct a matrix with N rows and n+1 columns<br>   <b>hadm[n+1][N]</b>
+     * <br><i>(If I use [x][y] it always means [row-offset][column-offset] of a Matrix with n rows and m columns. Its entries go from M[0][0] to M[n][m])</i></li>
+     * <li>Place the input vector <b>x[N]</b> in the first column of the matrix <b>hadm</b></li>
+     * <li>The entries of the submatrix D<sub>top</sub> are calculated as follows.
+     * <br>D<sub>top</sub> goes from entry [0][1] to [N/2-1][n+1].
+     * <br>The columns of D<sub>top</sub> are the pairwise mutually exclusive sums of the previous column
+     * </li>
+     * <li>The entries of the submatrix D<sub>bottom</sub> are calculated as follows.
+     * <br>D<sub>bottom</sub> goes from entry [N/2][1] to [N][n+1].
+     * <br>The columns of D<sub>bottom</sub> are the pairwise differences of the previous column
+     * </li>
+     * <li>How D<sub>top</sub> and D<sub>bottom</sub> you can understand best with the example for N=8 above.
+     * <li>The output vector y is now in the last column of <b>hadm</b></li>
+     * <li><i>Algorithm from: http://www.archive.chipcenter.com/dsp/DSP000517F1.html</i></li>
+     * </ol>
+     * <br>
+     * <b><u>Visually</u></b>
+     * <pre>
+     *        +--------+---+---+---+-----+---+
+     *        |   0    | 1 | 2 | 3 | ... |n+1|
+     * +------+--------+---+---+---+-----+---+
+     * |0     | x<sub>0</sub>     |       /\            |
+     * |1     | x<sub>1</sub>     |       ||            |
+     * |2     | x<sub>2</sub>     |   <= D<sub>top</sub>  =>       |
+     * |...   | ...    |       ||            |
+     * |N/2-1 | x<sub>N/2-1</sub>  |       \/            |
+     * +------+--------+---+---+---+-----+---+
+     * |N/2   | x<sub>N/2</sub>   |       /\            |
+     * |N/2+1 | x<sub>N/2+1</sub>  |       ||            |
+     * |N/2+2 | x<sub>N/2+2</sub>  |  <= D<sub>bottom</sub>  =>      | which is in the last column of the matrix
+     * |...   | ...    |       ||            |
+     * |N     | x<sub>N/2</sub>   |        \/           |
+     * +------+--------+---+---+---+-----+---+
+     * </pre>
+     *
+     * @param x input vector
+     * @return y output vector
+     * @exception IllegalArgumentException if input array is not a power of 2
+     */
+    protected double[] fht(double x[]) throws IllegalArgumentException {
+
+        // n is the row count of the input vector x
+        final int n     = x.length;
+        final int halfN = n / 2;
+
+        // n has to be of the form n = 2^p !!
+        if (!FastFourierTransformer.isPowerOf2(n)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POWER_OF_TWO,
+                    n);
+        }
+
+        // Instead of creating a matrix with p+1 columns and n rows
+        // we will use two single dimension arrays which we will use in an alternating way.
+        double[] yPrevious = new double[n];
+        double[] yCurrent  = x.clone();
+
+        // iterate from left to right (column)
+        for (int j = 1; j < n; j <<= 1) {
+
+            // switch columns
+            final double[] yTmp = yCurrent;
+            yCurrent  = yPrevious;
+            yPrevious = yTmp;
+
+            // iterate from top to bottom (row)
+            for (int i = 0; i < halfN; ++i) {
+                // D<sub>top</sub>
+                // The top part works with addition
+                final int twoI = 2 * i;
+                yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1];
+            }
+            for (int i = halfN; i < n; ++i) {
+                // D<sub>bottom</sub>
+                // The bottom part works with subtraction
+                final int twoI = 2 * i;
+                yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1];
+            }
+        }
+
+        // return the last computed output vector y
+        return yCurrent;
+
+    }
+    /**
+     * The FHT (Fast Hadamard Transformation) which uses only subtraction and addition.
+     * @param x input vector
+     * @return y output vector
+     * @exception IllegalArgumentException if input array is not a power of 2
+     */
+    protected int[] fht(int x[]) throws IllegalArgumentException {
+
+        // n is the row count of the input vector x
+        final int n     = x.length;
+        final int halfN = n / 2;
+
+        // n has to be of the form n = 2^p !!
+        if (!FastFourierTransformer.isPowerOf2(n)) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.NOT_POWER_OF_TWO,
+                    n);
+        }
+
+        // Instead of creating a matrix with p+1 columns and n rows
+        // we will use two single dimension arrays which we will use in an alternating way.
+        int[] yPrevious = new int[n];
+        int[] yCurrent  = x.clone();
+
+        // iterate from left to right (column)
+        for (int j = 1; j < n; j <<= 1) {
+
+            // switch columns
+            final int[] yTmp = yCurrent;
+            yCurrent  = yPrevious;
+            yPrevious = yTmp;
+
+            // iterate from top to bottom (row)
+            for (int i = 0; i < halfN; ++i) {
+                // D<sub>top</sub>
+                // The top part works with addition
+                final int twoI = 2 * i;
+                yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1];
+            }
+            for (int i = halfN; i < n; ++i) {
+                // D<sub>bottom</sub>
+                // The bottom part works with subtraction
+                final int twoI = 2 * i;
+                yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1];
+            }
+        }
+
+        // return the last computed output vector y
+        return yCurrent;
+
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java b/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java
new file mode 100644
index 0000000..28d7fce
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/transform/FastSineTransformer.java
@@ -0,0 +1,252 @@
+/*
+ * 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.transform;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.util.FastMath;
+
+/**
+ * Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/
+ * StandardPackages/LinearAlgebra/FourierTrig.html">Fast Sine Transform</a>
+ * for transformation of one-dimensional data sets. For reference, see
+ * <b>Fast Fourier Transforms</b>, ISBN 0849371635, chapter 3.
+ * <p>
+ * FST is its own inverse, up to a multiplier depending on conventions.
+ * The equations are listed in the comments of the corresponding methods.</p>
+ * <p>
+ * Similar to FFT, we also require the length of data set to be power of 2.
+ * In addition, the first element must be 0 and it's enforced in function
+ * transformation after sampling.</p>
+ * <p>As of version 2.0 this no longer implements Serializable</p>
+ *
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 1.2
+ */
+public class FastSineTransformer implements RealTransformer {
+
+    /**
+     * Construct a default transformer.
+     */
+    public FastSineTransformer() {
+        super();
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>
+     * The formula is F<sub>n</sub> = &sum;<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be transformed
+     * @return the real transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform(double f[])
+        throws IllegalArgumentException {
+        return fst(f);
+    }
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is F<sub>n</sub> = &sum;<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform(UnivariateRealFunction f,
+                              double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = FastFourierTransformer.sample(f, min, max, n);
+        data[0] = 0.0;
+        return fst(data);
+    }
+
+    /**
+     * Transform the given real data set.
+     * <p>
+     * The formula is F<sub>n</sub> = &radic;(2/N) &sum;<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be transformed
+     * @return the real transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform2(double f[]) throws IllegalArgumentException {
+
+        double scaling_coefficient = FastMath.sqrt(2.0 / f.length);
+        return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient);
+    }
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is F<sub>n</sub> = &radic;(2/N) &sum;<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated
+     * at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] transform2(
+        UnivariateRealFunction f, double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = FastFourierTransformer.sample(f, min, max, n);
+        data[0] = 0.0;
+        double scaling_coefficient = FastMath.sqrt(2.0 / n);
+        return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real data set.
+     * <p>
+     * The formula is f<sub>k</sub> = (2/N) &sum;<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be inversely transformed
+     * @return the real inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform(double f[]) throws IllegalArgumentException {
+
+        double scaling_coefficient = 2.0 / f.length;
+        return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is f<sub>k</sub> = (2/N) &sum;<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        double data[] = FastFourierTransformer.sample(f, min, max, n);
+        data[0] = 0.0;
+        double scaling_coefficient = 2.0 / n;
+        return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient);
+    }
+
+    /**
+     * Inversely transform the given real data set.
+     * <p>
+     * The formula is f<sub>k</sub> = &radic;(2/N) &sum;<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the real data array to be inversely transformed
+     * @return the real inversely transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform2(double f[]) throws IllegalArgumentException {
+
+        return transform2(f);
+    }
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * <p>
+     * The formula is f<sub>k</sub> = &radic;(2/N) &sum;<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(&pi; nk/N)
+     * </p>
+     *
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    public double[] inversetransform2(UnivariateRealFunction f, double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException {
+
+        return transform2(f, min, max, n);
+    }
+
+    /**
+     * Perform the FST algorithm (including inverse).
+     *
+     * @param f the real data array to be transformed
+     * @return the real transformed array
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    protected double[] fst(double f[]) throws IllegalArgumentException {
+
+        final double transformed[] = new double[f.length];
+
+        FastFourierTransformer.verifyDataSet(f);
+        if (f[0] != 0.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.FIRST_ELEMENT_NOT_ZERO,
+                    f[0]);
+        }
+        final int n = f.length;
+        if (n == 1) {       // trivial case
+            transformed[0] = 0.0;
+            return transformed;
+        }
+
+        // construct a new array and perform FFT on it
+        final double[] x = new double[n];
+        x[0] = 0.0;
+        x[n >> 1] = 2.0 * f[n >> 1];
+        for (int i = 1; i < (n >> 1); i++) {
+            final double a = FastMath.sin(i * FastMath.PI / n) * (f[i] + f[n-i]);
+            final double b = 0.5 * (f[i] - f[n-i]);
+            x[i]     = a + b;
+            x[n - i] = a - b;
+        }
+        FastFourierTransformer transformer = new FastFourierTransformer();
+        Complex y[] = transformer.transform(x);
+
+        // reconstruct the FST result for the original array
+        transformed[0] = 0.0;
+        transformed[1] = 0.5 * y[0].getReal();
+        for (int i = 1; i < (n >> 1); i++) {
+            transformed[2 * i]     = -y[i].getImaginary();
+            transformed[2 * i + 1] = y[i].getReal() + transformed[2 * i - 1];
+        }
+
+        return transformed;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/transform/RealTransformer.java b/src/main/java/org/apache/commons/math/transform/RealTransformer.java
new file mode 100644
index 0000000..c91061b
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/transform/RealTransformer.java
@@ -0,0 +1,80 @@
+/*
+ * 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.transform;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+/**
+ * Interface for one-dimensional data sets transformations producing real results.
+ * <p>Such transforms include {@link FastSineTransformer sine transform},
+ * {@link FastCosineTransformer cosine transform} or {@link
+ * FastHadamardTransformer Hadamard transform}. {@link FastFourierTransformer
+ * Fourier transform} is of a different kind and does not implement this
+ * interface since it produces {@link org.apache.commons.math.complex.Complex complex}
+ * results instead of real ones.
+ * </p>
+ * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
+ * @since 2.0
+ */
+public interface RealTransformer  {
+
+    /**
+     * Transform the given real data set.
+     * @param f the real data array to be transformed (signal)
+     * @return the real transformed array (spectrum)
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    double[] transform(double f[])
+        throws IllegalArgumentException;
+
+    /**
+     * Transform the given real function, sampled on the given interval.
+     * @param f the function to be sampled and transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    double[] transform(UnivariateRealFunction f, double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException;
+
+    /**
+     * Inversely transform the given real data set.
+     * @param f the real data array to be inversely transformed (spectrum)
+     * @return the real inversely transformed array (signal)
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    double[] inversetransform(double f[])
+        throws IllegalArgumentException;
+
+    /**
+     * Inversely transform the given real function, sampled on the given interval.
+     * @param f the function to be sampled and inversely transformed
+     * @param min the lower bound for the interval
+     * @param max the upper bound for the interval
+     * @param n the number of sample points
+     * @return the real inversely transformed array
+     * @throws FunctionEvaluationException if function cannot be evaluated at some point
+     * @throws IllegalArgumentException if any parameters are invalid
+     */
+    double[] inversetransform(UnivariateRealFunction f, double min, double max, int n)
+        throws FunctionEvaluationException, IllegalArgumentException;
+
+}
diff --git a/src/main/java/org/apache/commons/math/transform/package.html b/src/main/java/org/apache/commons/math/transform/package.html
new file mode 100644
index 0000000..7377906
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/transform/package.html
@@ -0,0 +1,22 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 618423 $ $Date: 2008-02-04 21:29:08 +0100 (lun. 04 févr. 2008) $ -->
+    <body>
+     Implementations of transform methods, including Fast Fourier transforms.
+    </body>
+</html>
diff --git a/src/main/java/org/apache/commons/math/util/BigReal.java b/src/main/java/org/apache/commons/math/util/BigReal.java
new file mode 100644
index 0000000..e7789a4
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/BigReal.java
@@ -0,0 +1,292 @@
+/*
+ * 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.util;
+
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+
+import org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+
+/**
+ * Arbitrary precision decimal number.
+ * <p>
+ * This class is a simple wrapper around the standard <code>BigDecimal</code>
+ * in order to implement the {@link FieldElement} interface.
+ * </p>
+ * @since 2.0
+ * @version $Revision: 925812 $ $Date: 2010-03-21 16:49:31 +0100 (dim. 21 mars 2010) $
+ */
+public class BigReal implements FieldElement<BigReal>, Comparable<BigReal>, Serializable {
+
+    /** A big real representing 0. */
+    public static final BigReal ZERO = new BigReal(BigDecimal.ZERO);
+
+    /** A big real representing 1. */
+    public static final BigReal ONE = new BigReal(BigDecimal.ONE);
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 4984534880991310382L;
+
+    /** Underlying BigDecimal. */
+    private final BigDecimal d;
+
+    /** Rounding mode for divisions. **/
+    private RoundingMode roundingMode = RoundingMode.HALF_UP;
+
+    /*** BigDecimal scale ***/
+    private int scale = 64;
+
+    /** Build an instance from a BigDecimal.
+     * @param val value of the instance
+     */
+    public BigReal(BigDecimal val) {
+        d =  val;
+    }
+
+    /** Build an instance from a BigInteger.
+     * @param val value of the instance
+     */
+    public BigReal(BigInteger val) {
+        d = new BigDecimal(val);
+    }
+
+    /** Build an instance from an unscaled BigInteger.
+     * @param unscaledVal unscaled value
+     * @param scale scale to use
+     */
+    public BigReal(BigInteger unscaledVal, int scale) {
+        d = new BigDecimal(unscaledVal, scale);
+    }
+
+    /** Build an instance from an unscaled BigInteger.
+     * @param unscaledVal unscaled value
+     * @param scale scale to use
+     * @param mc to used
+     */
+    public BigReal(BigInteger unscaledVal, int scale, MathContext mc) {
+        d = new BigDecimal(unscaledVal, scale, mc);
+    }
+
+    /** Build an instance from a BigInteger.
+     * @param val value of the instance
+     * @param mc context to use
+     */
+    public BigReal(BigInteger val, MathContext mc) {
+        d = new BigDecimal(val, mc);
+    }
+
+    /** Build an instance from a characters representation.
+     * @param in character representation of the value
+     */
+    public BigReal(char[] in) {
+        d = new BigDecimal(in);
+    }
+
+    /** Build an instance from a characters representation.
+     * @param in character representation of the value
+     * @param offset offset of the first character to analyze
+     * @param len length of the array slice to analyze
+     */
+    public BigReal(char[] in, int offset, int len) {
+        d = new BigDecimal(in, offset, len);
+    }
+
+    /** Build an instance from a characters representation.
+     * @param in character representation of the value
+     * @param offset offset of the first character to analyze
+     * @param len length of the array slice to analyze
+     * @param mc context to use
+     */
+    public BigReal(char[] in, int offset, int len, MathContext mc) {
+        d = new BigDecimal(in, offset, len, mc);
+    }
+
+    /** Build an instance from a characters representation.
+     * @param in character representation of the value
+     * @param mc context to use
+     */
+    public BigReal(char[] in, MathContext mc) {
+        d = new BigDecimal(in, mc);
+    }
+
+    /** Build an instance from a double.
+     * @param val value of the instance
+     */
+    public BigReal(double val) {
+        d = new BigDecimal(val);
+    }
+
+    /** Build an instance from a double.
+     * @param val value of the instance
+     * @param mc context to use
+     */
+    public BigReal(double val, MathContext mc) {
+        d = new BigDecimal(val, mc);
+    }
+
+    /** Build an instance from an int.
+     * @param val value of the instance
+     */
+    public BigReal(int val) {
+        d = new BigDecimal(val);
+    }
+
+    /** Build an instance from an int.
+     * @param val value of the instance
+     * @param mc context to use
+     */
+    public BigReal(int val, MathContext mc) {
+        d = new BigDecimal(val, mc);
+    }
+
+    /** Build an instance from a long.
+     * @param val value of the instance
+     */
+    public BigReal(long val) {
+        d = new BigDecimal(val);
+    }
+
+    /** Build an instance from a long.
+     * @param val value of the instance
+     * @param mc context to use
+     */
+    public BigReal(long val, MathContext mc) {
+        d = new BigDecimal(val, mc);
+    }
+
+    /** Build an instance from a String representation.
+     * @param val character representation of the value
+     */
+    public BigReal(String val) {
+        d = new BigDecimal(val);
+    }
+
+    /** Build an instance from a String representation.
+     * @param val character representation of the value
+     * @param mc context to use
+     */
+    public BigReal(String val, MathContext mc)  {
+        d = new BigDecimal(val, mc);
+    }
+
+    /***
+     * Gets the rounding mode for division operations
+     * The default is {@code RoundingMode.HALF_UP}
+     * @return the rounding mode.
+     * @since 2.1
+     */
+    public RoundingMode getRoundingMode() {
+        return roundingMode;
+    }
+
+    /***
+     * Sets the rounding mode for decimal divisions.
+     * @param roundingMode rounding mode for decimal divisions
+     * @since 2.1
+     */
+    public void setRoundingMode(RoundingMode roundingMode) {
+        this.roundingMode = roundingMode;
+    }
+
+    /***
+     * Sets the scale for division operations.
+     * The default is 64
+     * @return the scale
+     * @since 2.1
+     */
+    public int getScale() {
+        return scale;
+    }
+
+    /***
+     * Sets the scale for division operations.
+     * @param scale scale for division operations
+     * @since 2.1
+     */
+    public void setScale(int scale) {
+        this.scale = scale;
+    }
+
+    /** {@inheritDoc} */
+    public BigReal add(BigReal a) {
+        return new BigReal(d.add(a.d));
+    }
+
+    /** {@inheritDoc} */
+    public BigReal subtract(BigReal a) {
+        return new BigReal(d.subtract(a.d));
+    }
+
+    /** {@inheritDoc} */
+    public BigReal divide(BigReal a) throws ArithmeticException {
+        return new BigReal(d.divide(a.d, scale, roundingMode));
+    }
+
+    /** {@inheritDoc} */
+    public BigReal multiply(BigReal a) {
+        return new BigReal(d.multiply(a.d));
+    }
+
+    /** {@inheritDoc} */
+    public int compareTo(BigReal a) {
+        return d.compareTo(a.d);
+    }
+
+    /** Get the double value corresponding to the instance.
+     * @return double value corresponding to the instance
+     */
+    public double doubleValue() {
+        return d.doubleValue();
+    }
+
+    /** Get the BigDecimal value corresponding to the instance.
+     * @return BigDecimal value corresponding to the instance
+     */
+    public BigDecimal bigDecimalValue() {
+        return d;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other){
+            return true;
+        }
+
+        if (other instanceof BigReal){
+            return d.equals(((BigReal) other).d);
+        }
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return d.hashCode();
+    }
+
+    /** {@inheritDoc} */
+    public Field<BigReal> getField() {
+        return BigRealField.getInstance();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/BigRealField.java b/src/main/java/org/apache/commons/math/util/BigRealField.java
new file mode 100644
index 0000000..02361bc
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/BigRealField.java
@@ -0,0 +1,78 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.Field;
+
+/**
+ * Representation of real numbers with arbitrary precision field.
+ * <p>
+ * This class is a singleton.
+ * </p>
+ * @see BigReal
+ * @version $Revision: 811827 $ $Date: 2009-09-06 17:32:50 +0200 (dim. 06 sept. 2009) $
+ * @since 2.0
+ */
+public class BigRealField implements Field<BigReal>, Serializable  {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4756431066541037559L;
+
+    /** Private constructor for the singleton.
+     */
+    private BigRealField() {
+    }
+
+    /** Get the unique instance.
+     * @return the unique instance
+     */
+    public static BigRealField getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    /** {@inheritDoc} */
+    public BigReal getOne() {
+        return BigReal.ONE;
+    }
+
+    /** {@inheritDoc} */
+    public BigReal getZero() {
+        return BigReal.ZERO;
+    }
+
+    // CHECKSTYLE: stop HideUtilityClassConstructor
+    /** Holder for the instance.
+     * <p>We use here the Initialization On Demand Holder Idiom.</p>
+     */
+    private static class LazyHolder {
+        /** Cached field instance. */
+        private static final BigRealField INSTANCE = new BigRealField();
+    }
+    // CHECKSTYLE: resume HideUtilityClassConstructor
+
+    /** Handle deserialization of the singleton.
+     * @return the singleton instance
+     */
+    private Object readResolve() {
+        // return the singleton instance
+        return LazyHolder.INSTANCE;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/CompositeFormat.java b/src/main/java/org/apache/commons/math/util/CompositeFormat.java
new file mode 100644
index 0000000..99d18ab
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/CompositeFormat.java
@@ -0,0 +1,220 @@
+/*
+ * 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.util;
+
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.NumberFormat;
+import java.text.ParsePosition;
+import java.util.Locale;
+
+/**
+ * Base class for formatters of composite objects (complex numbers, vectors ...).
+ *
+ * @version $Revision: 1042376 $ $Date: 2010-12-05 16:54:55 +0100 (dim. 05 déc. 2010) $
+ */
+public abstract class CompositeFormat extends Format {
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = 5358685519349262494L;
+
+    /**
+     * Create a default number format.  The default number format is based on
+     * {@link NumberFormat#getInstance()} with the only customizing that the
+     * maximum number of fraction digits is set to 2.
+     * @return the default number format.
+     */
+    protected static NumberFormat getDefaultNumberFormat() {
+        return getDefaultNumberFormat(Locale.getDefault());
+    }
+
+    /**
+     * Create a default number format.  The default number format is based on
+     * {@link NumberFormat#getInstance(java.util.Locale)} with the only
+     * customizing that the maximum number of fraction digits is set to 2.
+     * @param locale the specific locale used by the format.
+     * @return the default number format specific to the given locale.
+     */
+    protected static NumberFormat getDefaultNumberFormat(final Locale locale) {
+        final NumberFormat nf = NumberFormat.getInstance(locale);
+        nf.setMaximumFractionDigits(2);
+        return nf;
+    }
+
+    /**
+     * Parses <code>source</code> until a non-whitespace character is found.
+     *
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.  On output, <code>pos</code>
+     *        holds the index of the next non-whitespace character.
+     */
+    protected void parseAndIgnoreWhitespace(final String source,
+                                            final ParsePosition pos) {
+        parseNextCharacter(source, pos);
+        pos.setIndex(pos.getIndex() - 1);
+    }
+
+    /**
+     * Parses <code>source</code> until a non-whitespace character is found.
+     *
+     * @param source the string to parse
+     * @param pos input/ouput parsing parameter.
+     * @return the first non-whitespace character.
+     */
+    protected char parseNextCharacter(final String source,
+                                      final ParsePosition pos) {
+         int index = pos.getIndex();
+         final int n = source.length();
+         char ret = 0;
+
+         if (index < n) {
+             char c;
+             do {
+                 c = source.charAt(index++);
+             } while (Character.isWhitespace(c) && index < n);
+             pos.setIndex(index);
+
+             if (index < n) {
+                 ret = c;
+             }
+         }
+
+         return ret;
+    }
+
+    /**
+     * Parses <code>source</code> for special double values.  These values
+     * include Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.
+     *
+     * @param source the string to parse
+     * @param value the special value to parse.
+     * @param pos input/ouput parsing parameter.
+     * @return the special number.
+     */
+    private Number parseNumber(final String source, final double value,
+                               final ParsePosition pos) {
+        Number ret = null;
+
+        StringBuilder sb = new StringBuilder();
+        sb.append('(');
+        sb.append(value);
+        sb.append(')');
+
+        final int n = sb.length();
+        final int startIndex = pos.getIndex();
+        final int endIndex = startIndex + n;
+        if (endIndex < source.length()) {
+            if (source.substring(startIndex, endIndex).compareTo(sb.toString()) == 0) {
+                ret = Double.valueOf(value);
+                pos.setIndex(endIndex);
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * Parses <code>source</code> for a number.  This method can parse normal,
+     * numeric values as well as special values.  These special values include
+     * Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.
+     *
+     * @param source the string to parse
+     * @param format the number format used to parse normal, numeric values.
+     * @param pos input/ouput parsing parameter.
+     * @return the parsed number.
+     */
+    protected Number parseNumber(final String source, final NumberFormat format,
+                                 final ParsePosition pos) {
+        final int startIndex = pos.getIndex();
+        Number number = format.parse(source, pos);
+        final int endIndex = pos.getIndex();
+
+        // check for error parsing number
+        if (startIndex == endIndex) {
+            // try parsing special numbers
+            final double[] special = {
+                Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY
+            };
+            for (int i = 0; i < special.length; ++i) {
+                number = parseNumber(source, special[i], pos);
+                if (number != null) {
+                    break;
+                }
+            }
+        }
+
+        return number;
+    }
+
+    /**
+     * Parse <code>source</code> for an expected fixed string.
+     * @param source the string to parse
+     * @param expected expected string
+     * @param pos input/ouput parsing parameter.
+     * @return true if the expected string was there
+     */
+    protected boolean parseFixedstring(final String source, final String expected,
+                                       final ParsePosition pos) {
+
+        final int startIndex = pos.getIndex();
+        final int endIndex = startIndex + expected.length();
+        if ((startIndex >= source.length()) ||
+            (endIndex > source.length()) ||
+            (source.substring(startIndex, endIndex).compareTo(expected) != 0)) {
+            // set index back to start, error index should be the start index
+            pos.setIndex(startIndex);
+            pos.setErrorIndex(startIndex);
+            return false;
+        }
+
+        // the string was here
+        pos.setIndex(endIndex);
+        return true;
+
+    }
+
+    /**
+     * Formats a double value to produce a string.  In general, the value is
+     * formatted using the formatting rules of <code>format</code>.  There are
+     * three exceptions to this:
+     * <ol>
+     * <li>NaN is formatted as '(NaN)'</li>
+     * <li>Positive infinity is formatted as '(Infinity)'</li>
+     * <li>Negative infinity is formatted as '(-Infinity)'</li>
+     * </ol>
+     *
+     * @param value the double to format.
+     * @param format the format used.
+     * @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.
+     */
+    protected StringBuffer formatDouble(final double value, final NumberFormat format,
+                                        final StringBuffer toAppendTo,
+                                        final FieldPosition pos) {
+        if( Double.isNaN(value) || Double.isInfinite(value) ) {
+            toAppendTo.append('(');
+            toAppendTo.append(value);
+            toAppendTo.append(')');
+        } else {
+            format.format(value, toAppendTo, pos);
+        }
+        return toAppendTo;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/ContinuedFraction.java b/src/main/java/org/apache/commons/math/util/ContinuedFraction.java
new file mode 100644
index 0000000..80df5d8
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/ContinuedFraction.java
@@ -0,0 +1,208 @@
+/*
+ * 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.util;
+
+import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MaxIterationsExceededException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Provides a generic means to evaluate continued fractions.  Subclasses simply
+ * provided the a and b coefficients to evaluate the continued fraction.
+ *
+ * <p>
+ * References:
+ * <ul>
+ * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
+ * Continued Fraction</a></li>
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ */
+public abstract class ContinuedFraction {
+
+    /** Maximum allowed numerical error. */
+    private static final double DEFAULT_EPSILON = 10e-9;
+
+    /**
+     * Default constructor.
+     */
+    protected ContinuedFraction() {
+        super();
+    }
+
+    /**
+     * Access the n-th a coefficient of the continued fraction.  Since a can be
+     * a function of the evaluation point, x, that is passed in as well.
+     * @param n the coefficient index to retrieve.
+     * @param x the evaluation point.
+     * @return the n-th a coefficient.
+     */
+    protected abstract double getA(int n, double x);
+
+    /**
+     * Access the n-th b coefficient of the continued fraction.  Since b can be
+     * a function of the evaluation point, x, that is passed in as well.
+     * @param n the coefficient index to retrieve.
+     * @param x the evaluation point.
+     * @return the n-th b coefficient.
+     */
+    protected abstract double getB(int n, double x);
+
+    /**
+     * Evaluates the continued fraction at the value x.
+     * @param x the evaluation point.
+     * @return the value of the continued fraction evaluated at x.
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public double evaluate(double x) throws MathException {
+        return evaluate(x, DEFAULT_EPSILON, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Evaluates the continued fraction at the value x.
+     * @param x the evaluation point.
+     * @param epsilon maximum error allowed.
+     * @return the value of the continued fraction evaluated at x.
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public double evaluate(double x, double epsilon) throws MathException {
+        return evaluate(x, epsilon, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Evaluates the continued fraction at the value x.
+     * @param x the evaluation point.
+     * @param maxIterations maximum number of convergents
+     * @return the value of the continued fraction evaluated at x.
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public double evaluate(double x, int maxIterations) throws MathException {
+        return evaluate(x, DEFAULT_EPSILON, maxIterations);
+    }
+
+    /**
+     * <p>
+     * Evaluates the continued fraction at the value x.
+     * </p>
+     *
+     * <p>
+     * The implementation of this method is based on equations 14-17 of:
+     * <ul>
+     * <li>
+     *   Eric W. Weisstein. "Continued Fraction." From MathWorld--A Wolfram Web
+     *   Resource. <a target="_blank"
+     *   href="http://mathworld.wolfram.com/ContinuedFraction.html">
+     *   http://mathworld.wolfram.com/ContinuedFraction.html</a>
+     * </li>
+     * </ul>
+     * The recurrence relationship defined in those equations can result in
+     * very large intermediate results which can result in numerical overflow.
+     * As a means to combat these overflow conditions, the intermediate results
+     * are scaled whenever they threaten to become numerically unstable.</p>
+     *
+     * @param x the evaluation point.
+     * @param epsilon maximum error allowed.
+     * @param maxIterations maximum number of convergents
+     * @return the value of the continued fraction evaluated at x.
+     * @throws MathException if the algorithm fails to converge.
+     */
+    public double evaluate(double x, double epsilon, int maxIterations)
+        throws MathException
+    {
+        double p0 = 1.0;
+        double p1 = getA(0, x);
+        double q0 = 0.0;
+        double q1 = 1.0;
+        double c = p1 / q1;
+        int n = 0;
+        double relativeError = Double.MAX_VALUE;
+        while (n < maxIterations && relativeError > epsilon) {
+            ++n;
+            double a = getA(n, x);
+            double b = getB(n, x);
+            double p2 = a * p1 + b * p0;
+            double q2 = a * q1 + b * q0;
+            boolean infinite = false;
+            if (Double.isInfinite(p2) || Double.isInfinite(q2)) {
+                /*
+                 * Need to scale. Try successive powers of the larger of a or b
+                 * up to 5th power. Throw ConvergenceException if one or both
+                 * of p2, q2 still overflow.
+                 */
+                double scaleFactor = 1d;
+                double lastScaleFactor = 1d;
+                final int maxPower = 5;
+                final double scale = FastMath.max(a,b);
+                if (scale <= 0) {  // Can't scale
+                    throw new ConvergenceException(
+                            LocalizedFormats.CONTINUED_FRACTION_INFINITY_DIVERGENCE,
+                             x);
+                }
+                infinite = true;
+                for (int i = 0; i < maxPower; i++) {
+                    lastScaleFactor = scaleFactor;
+                    scaleFactor *= scale;
+                    if (a != 0.0 && a > b) {
+                        p2 = p1 / lastScaleFactor + (b / scaleFactor * p0);
+                        q2 = q1 / lastScaleFactor + (b / scaleFactor * q0);
+                    } else if (b != 0) {
+                        p2 = (a / scaleFactor * p1) + p0 / lastScaleFactor;
+                        q2 = (a / scaleFactor * q1) + q0 / lastScaleFactor;
+                    }
+                    infinite = Double.isInfinite(p2) || Double.isInfinite(q2);
+                    if (!infinite) {
+                        break;
+                    }
+                }
+            }
+
+            if (infinite) {
+               // Scaling failed
+               throw new ConvergenceException(
+                 LocalizedFormats.CONTINUED_FRACTION_INFINITY_DIVERGENCE,
+                  x);
+            }
+
+            double r = p2 / q2;
+
+            if (Double.isNaN(r)) {
+                throw new ConvergenceException(
+                  LocalizedFormats.CONTINUED_FRACTION_NAN_DIVERGENCE,
+                  x);
+            }
+            relativeError = FastMath.abs(r / c - 1.0);
+
+            // prepare for next iteration
+            c = p2 / q2;
+            p0 = p1;
+            p1 = p2;
+            q0 = q1;
+            q1 = q2;
+        }
+
+        if (n >= maxIterations) {
+            throw new MaxIterationsExceededException(maxIterations,
+                LocalizedFormats.NON_CONVERGENT_CONTINUED_FRACTION,
+                x);
+        }
+
+        return c;
+    }
+}
diff --git a/src/main/java/org/apache/commons/math/util/DefaultTransformer.java b/src/main/java/org/apache/commons/math/util/DefaultTransformer.java
new file mode 100644
index 0000000..e4579b2
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/DefaultTransformer.java
@@ -0,0 +1,80 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * A Default NumberTransformer for java.lang.Numbers and Numeric Strings. This
+ * provides some simple conversion capabilities to turn any java.lang.Number
+ * into a primitive double or to turn a String representation of a Number into
+ * a double.
+ *
+ * @version $Revision: 1073658 $ $Date: 2011-02-23 10:45:42 +0100 (mer. 23 févr. 2011) $
+ */
+public class DefaultTransformer implements NumberTransformer, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4019938025047800455L;
+
+    /**
+     * @param o  the object that gets transformed.
+     * @return a double primitive representation of the Object o.
+     * @throws MathException if it cannot successfully be transformed.
+     * @see <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/Transformer.html">Commons Collections Transformer</a>
+     */
+    public double transform(Object o) throws MathException {
+        if (o == null) {
+            throw new MathException(LocalizedFormats.OBJECT_TRANSFORMATION);
+        }
+
+        if (o instanceof Number) {
+            return ((Number)o).doubleValue();
+        }
+
+        try {
+            return Double.valueOf(o.toString()).doubleValue();
+        } catch (NumberFormatException e) {
+            throw new MathException(e,
+                                    LocalizedFormats.CANNOT_TRANSFORM_TO_DOUBLE, e.getMessage());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other == null) {
+            return false;
+        }
+        return other instanceof DefaultTransformer;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        // some arbitrary number ...
+        return 401993047;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/DoubleArray.java b/src/main/java/org/apache/commons/math/util/DoubleArray.java
new file mode 100644
index 0000000..c213b84
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/DoubleArray.java
@@ -0,0 +1,104 @@
+/*
+ * 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.util;
+
+
+/**
+ * Provides a standard interface for double arrays.  Allows different
+ * array implementations to support various storage mechanisms
+ * such as automatic expansion, contraction, and array "rolling".
+ *
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ */
+public interface DoubleArray {
+
+    /**
+     * Returns the number of elements currently in the array.  Please note
+     * that this may be different from the length of the internal storage array.
+     *
+     * @return number of elements
+     */
+    int getNumElements();
+
+    /**
+     * Returns the element at the specified index.  Note that if an
+     * out of bounds index is supplied a ArrayIndexOutOfBoundsException
+     * will be thrown.
+     *
+     * @param index index to fetch a value from
+     * @return value stored at the specified index
+     * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than
+     *         zero or is greater than <code>getNumElements() - 1</code>.
+     */
+    double getElement(int index);
+
+    /**
+     * Sets the element at the specified index.  If the specified index is greater than
+     * <code>getNumElements() - 1</code>, the <code>numElements</code> property
+     * is increased to <code>index +1</code> and additional storage is allocated
+     * (if necessary) for the new element and all  (uninitialized) elements
+     * between the new element and the previous end of the array).
+     *
+     * @param index index to store a value in
+     * @param value value to store at the specified index
+     * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than
+     *         zero.
+     */
+    void setElement(int index, double value);
+
+    /**
+     * Adds an element to the end of this expandable array
+     *
+     * @param value to be added to end of array
+     */
+    void addElement(double value);
+
+    /**
+     * <p>
+     * Adds an element to the end of the array and removes the first
+     * element in the array.  Returns the discarded first element.
+     * The effect is similar to a push operation in a FIFO queue.
+     * </p>
+     * <p>
+     * Example: If the array contains the elements 1, 2, 3, 4 (in that order)
+     * and addElementRolling(5) is invoked, the result is an array containing
+     * the entries 2, 3, 4, 5 and the value returned is 1.
+     * </p>
+     *
+     * @param value the value to be added to the array
+     * @return the value which has been discarded or "pushed" out of the array
+     *         by this rolling insert
+     */
+    double addElementRolling(double value);
+
+    /**
+     * Returns a double[] array containing the elements of this
+     * <code>DoubleArray</code>.  If the underlying implementation is
+     * array-based, this method should always return a copy, rather than a
+     * reference to the underlying array so that changes made to the returned
+     *  array have no effect on the <code>DoubleArray.</code>
+     *
+     * @return all elements added to the array
+     */
+    double[] getElements();
+
+    /**
+     * Clear the double array
+     */
+    void clear();
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/FastMath.java b/src/main/java/org/apache/commons/math/util/FastMath.java
new file mode 100644
index 0000000..1907b32
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/FastMath.java
@@ -0,0 +1,4047 @@
+/*
+ * 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.util;
+
+/**
+ * Faster, more accurate, portable alternative to {@link StrictMath}.
+ * <p>
+ * Additionally implements the following methods not found in StrictMath:
+ * <ul>
+ * <li>{@link #asinh(double)}</li>
+ * <li>{@link #acosh(double)}</li>
+ * <li>{@link #atanh(double)}</li>
+ * </ul>
+ * The following methods are found in StrictMath since 1.6 only
+ * <ul>
+ * <li>{@link #copySign(double, double)}</li>
+ * <li>{@link #getExponent(double)}</li>
+ * <li>{@link #nextAfter(double,double)}</li>
+ * <li>{@link #nextUp(double)}</li>
+ * <li>{@link #scalb(double, int)}</li>
+ * <li>{@link #copySign(float, float)}</li>
+ * <li>{@link #getExponent(float)}</li>
+ * <li>{@link #nextAfter(float,double)}</li>
+ * <li>{@link #nextUp(float)}</li>
+ * <li>{@link #scalb(float, int)}</li>
+ * </ul>
+ * @version $Revision: 1074294 $ $Date: 2011-02-24 22:18:59 +0100 (jeu. 24 févr. 2011) $
+ * @since 2.2
+ */
+public class FastMath {
+
+    /** Archimede's constant PI, ratio of circle circumference to diameter. */
+    public static final double PI = 105414357.0 / 33554432.0 + 1.984187159361080883e-9;
+
+    /** Napier's constant e, base of the natural logarithm. */
+    public static final double E = 2850325.0 / 1048576.0 + 8.254840070411028747e-8;
+
+    /** Exponential evaluated at integer values,
+     * exp(x) =  expIntTableA[x + 750] + expIntTableB[x+750].
+     */
+    private static final double EXP_INT_TABLE_A[] = new double[1500];
+
+    /** Exponential evaluated at integer values,
+     * exp(x) =  expIntTableA[x + 750] + expIntTableB[x+750]
+     */
+    private static final double EXP_INT_TABLE_B[] = new double[1500];
+
+    /** Exponential over the range of 0 - 1 in increments of 2^-10
+     * exp(x/1024) =  expFracTableA[x] + expFracTableB[x].
+     */
+    private static final double EXP_FRAC_TABLE_A[] = new double[1025];
+
+    /** Exponential over the range of 0 - 1 in increments of 2^-10
+     * exp(x/1024) =  expFracTableA[x] + expFracTableB[x].
+     */
+    private static final double EXP_FRAC_TABLE_B[] = new double[1025];
+
+    /** Factorial table, for Taylor series expansions. */
+    private static final double FACT[] = new double[20];
+
+    /** Extended precision logarithm table over the range 1 - 2 in increments of 2^-10. */
+    private static final double LN_MANT[][] = new double[1024][];
+
+    /** log(2) (high bits). */
+    private static final double LN_2_A = 0.693147063255310059;
+
+    /** log(2) (low bits). */
+    private static final double LN_2_B = 1.17304635250823482e-7;
+
+    /** Coefficients for slowLog. */
+    private static final double LN_SPLIT_COEF[][] = {
+        {2.0, 0.0},
+        {0.6666666269302368, 3.9736429850260626E-8},
+        {0.3999999761581421, 2.3841857910019882E-8},
+        {0.2857142686843872, 1.7029898543501842E-8},
+        {0.2222222089767456, 1.3245471311735498E-8},
+        {0.1818181574344635, 2.4384203044354907E-8},
+        {0.1538461446762085, 9.140260083262505E-9},
+        {0.13333332538604736, 9.220590270857665E-9},
+        {0.11764700710773468, 1.2393345855018391E-8},
+        {0.10526403784751892, 8.251545029714408E-9},
+        {0.0952233225107193, 1.2675934823758863E-8},
+        {0.08713622391223907, 1.1430250008909141E-8},
+        {0.07842259109020233, 2.404307984052299E-9},
+        {0.08371849358081818, 1.176342548272881E-8},
+        {0.030589580535888672, 1.2958646899018938E-9},
+        {0.14982303977012634, 1.225743062930824E-8},
+    };
+
+    /** Coefficients for log, when input 0.99 < x < 1.01. */
+    private static final double LN_QUICK_COEF[][] = {
+        {1.0, 5.669184079525E-24},
+        {-0.25, -0.25},
+        {0.3333333134651184, 1.986821492305628E-8},
+        {-0.25, -6.663542893624021E-14},
+        {0.19999998807907104, 1.1921056801463227E-8},
+        {-0.1666666567325592, -7.800414592973399E-9},
+        {0.1428571343421936, 5.650007086920087E-9},
+        {-0.12502530217170715, -7.44321345601866E-11},
+        {0.11113807559013367, 9.219544613762692E-9},
+    };
+
+    /** Coefficients for log in the range of 1.0 < x < 1.0 + 2^-10. */
+    private static final double LN_HI_PREC_COEF[][] = {
+        {1.0, -6.032174644509064E-23},
+        {-0.25, -0.25},
+        {0.3333333134651184, 1.9868161777724352E-8},
+        {-0.2499999701976776, -2.957007209750105E-8},
+        {0.19999954104423523, 1.5830993332061267E-10},
+        {-0.16624879837036133, -2.6033824355191673E-8}
+    };
+
+    /** Sine table (high bits). */
+    private static final double SINE_TABLE_A[] = new double[14];
+
+    /** Sine table (low bits). */
+    private static final double SINE_TABLE_B[] = new double[14];
+
+    /** Cosine table (high bits). */
+    private static final double COSINE_TABLE_A[] = new double[14];
+
+    /** Cosine table (low bits). */
+    private static final double COSINE_TABLE_B[] = new double[14];
+
+    /** Tangent table, used by atan() (high bits). */
+    private static final double TANGENT_TABLE_A[] = new double[14];
+
+    /** Tangent table, used by atan() (low bits). */
+    private static final double TANGENT_TABLE_B[] = new double[14];
+
+    /** Bits of 1/(2*pi), need for reducePayneHanek(). */
+    private static final long RECIP_2PI[] = new long[] {
+        (0x28be60dbL << 32) | 0x9391054aL,
+        (0x7f09d5f4L << 32) | 0x7d4d3770L,
+        (0x36d8a566L << 32) | 0x4f10e410L,
+        (0x7f9458eaL << 32) | 0xf7aef158L,
+        (0x6dc91b8eL << 32) | 0x909374b8L,
+        (0x01924bbaL << 32) | 0x82746487L,
+        (0x3f877ac7L << 32) | 0x2c4a69cfL,
+        (0xba208d7dL << 32) | 0x4baed121L,
+        (0x3a671c09L << 32) | 0xad17df90L,
+        (0x4e64758eL << 32) | 0x60d4ce7dL,
+        (0x272117e2L << 32) | 0xef7e4a0eL,
+        (0xc7fe25ffL << 32) | 0xf7816603L,
+        (0xfbcbc462L << 32) | 0xd6829b47L,
+        (0xdb4d9fb3L << 32) | 0xc9f2c26dL,
+        (0xd3d18fd9L << 32) | 0xa797fa8bL,
+        (0x5d49eeb1L << 32) | 0xfaf97c5eL,
+        (0xcf41ce7dL << 32) | 0xe294a4baL,
+         0x9afed7ecL << 32  };
+
+    /** Bits of pi/4, need for reducePayneHanek(). */
+    private static final long PI_O_4_BITS[] = new long[] {
+        (0xc90fdaa2L << 32) | 0x2168c234L,
+        (0xc4c6628bL << 32) | 0x80dc1cd1L };
+
+    /** Eighths.
+     * This is used by sinQ, because its faster to do a table lookup than
+     * a multiply in this time-critical routine
+     */
+    private static final double EIGHTHS[] = {0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.125, 1.25, 1.375, 1.5, 1.625};
+
+    /** Table of 2^((n+2)/3) */
+    private static final double CBRTTWO[] = { 0.6299605249474366,
+                                            0.7937005259840998,
+                                            1.0,
+                                            1.2599210498948732,
+                                            1.5874010519681994 };
+
+    /*
+     *  There are 52 bits in the mantissa of a double.
+     *  For additional precision, the code splits double numbers into two parts,
+     *  by clearing the low order 30 bits if possible, and then performs the arithmetic
+     *  on each half separately.
+     */
+
+    /**
+     * 0x40000000 - used to split a double into two parts, both with the low order bits cleared.
+     * Equivalent to 2^30.
+     */
+    private static final long HEX_40000000 = 0x40000000L; // 1073741824L
+
+    /** Mask used to clear low order 30 bits */
+    private static final long MASK_30BITS = -1L - (HEX_40000000 -1); // 0xFFFFFFFFC0000000L;
+
+    /** 2^52 - double numbers this large must be integral (no fraction) or NaN or Infinite */
+    private static final double TWO_POWER_52 = 4503599627370496.0;
+
+    // Initialize tables
+    static {
+        int i;
+
+        // Generate an array of factorials
+        FACT[0] = 1.0;
+        for (i = 1; i < FACT.length; i++) {
+            FACT[i] = FACT[i-1] * i;
+        }
+
+        double tmp[] = new double[2];
+        double recip[] = new double[2];
+
+        // Populate expIntTable
+        for (i = 0; i < 750; i++) {
+            expint(i, tmp);
+            EXP_INT_TABLE_A[i+750] = tmp[0];
+            EXP_INT_TABLE_B[i+750] = tmp[1];
+
+            if (i != 0) {
+                // Negative integer powers
+                splitReciprocal(tmp, recip);
+                EXP_INT_TABLE_A[750-i] = recip[0];
+                EXP_INT_TABLE_B[750-i] = recip[1];
+            }
+        }
+
+        // Populate expFracTable
+        for (i = 0; i < EXP_FRAC_TABLE_A.length; i++) {
+            slowexp(i/1024.0, tmp);
+            EXP_FRAC_TABLE_A[i] = tmp[0];
+            EXP_FRAC_TABLE_B[i] = tmp[1];
+        }
+
+        // Populate lnMant table
+        for (i = 0; i < LN_MANT.length; i++) {
+            double d = Double.longBitsToDouble( (((long) i) << 42) | 0x3ff0000000000000L );
+            LN_MANT[i] = slowLog(d);
+        }
+
+        // Build the sine and cosine tables
+        buildSinCosTables();
+    }
+
+    /**
+     * Private Constructor
+     */
+    private FastMath() {
+    }
+
+    // Generic helper methods
+
+    /**
+     * Get the high order bits from the mantissa.
+     * Equivalent to adding and subtracting HEX_40000 but also works for very large numbers
+     *
+     * @param d the value to split
+     * @return the high order part of the mantissa
+     */
+    private static double doubleHighPart(double d) {
+        if (d > -MathUtils.SAFE_MIN && d < MathUtils.SAFE_MIN){
+            return d; // These are un-normalised - don't try to convert
+        }
+        long xl = Double.doubleToLongBits(d);
+        xl = xl & MASK_30BITS; // Drop low order bits
+        return Double.longBitsToDouble(xl);
+    }
+
+    /** Compute the square root of a number.
+     * <p><b>Note:</b> this implementation currently delegates to {@link Math#sqrt}
+     * @param a number on which evaluation is done
+     * @return square root of a
+     */
+    public static double sqrt(final double a) {
+        return Math.sqrt(a);
+    }
+
+    /** Compute the hyperbolic cosine of a number.
+     * @param x number on which evaluation is done
+     * @return hyperbolic cosine of x
+     */
+    public static double cosh(double x) {
+      if (x != x) {
+          return x;
+      }
+
+      if (x > 20.0) {
+          return exp(x)/2.0;
+      }
+
+      if (x < -20) {
+          return exp(-x)/2.0;
+      }
+
+      double hiPrec[] = new double[2];
+      if (x < 0.0) {
+          x = -x;
+      }
+      exp(x, 0.0, hiPrec);
+
+      double ya = hiPrec[0] + hiPrec[1];
+      double yb = -(ya - hiPrec[0] - hiPrec[1]);
+
+      double temp = ya * HEX_40000000;
+      double yaa = ya + temp - temp;
+      double yab = ya - yaa;
+
+      // recip = 1/y
+      double recip = 1.0/ya;
+      temp = recip * HEX_40000000;
+      double recipa = recip + temp - temp;
+      double recipb = recip - recipa;
+
+      // Correct for rounding in division
+      recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
+      // Account for yb
+      recipb += -yb * recip * recip;
+
+      // y = y + 1/y
+      temp = ya + recipa;
+      yb += -(temp - ya - recipa);
+      ya = temp;
+      temp = ya + recipb;
+      yb += -(temp - ya - recipb);
+      ya = temp;
+
+      double result = ya + yb;
+      result *= 0.5;
+      return result;
+    }
+
+    /** Compute the hyperbolic sine of a number.
+     * @param x number on which evaluation is done
+     * @return hyperbolic sine of x
+     */
+    public static double sinh(double x) {
+      boolean negate = false;
+      if (x != x) {
+          return x;
+      }
+
+      if (x > 20.0) {
+          return exp(x)/2.0;
+      }
+
+      if (x < -20) {
+          return -exp(-x)/2.0;
+      }
+
+      if (x == 0) {
+          return x;
+      }
+
+      if (x < 0.0) {
+          x = -x;
+          negate = true;
+      }
+
+      double result;
+
+      if (x > 0.25) {
+          double hiPrec[] = new double[2];
+          exp(x, 0.0, hiPrec);
+
+          double ya = hiPrec[0] + hiPrec[1];
+          double yb = -(ya - hiPrec[0] - hiPrec[1]);
+
+          double temp = ya * HEX_40000000;
+          double yaa = ya + temp - temp;
+          double yab = ya - yaa;
+
+          // recip = 1/y
+          double recip = 1.0/ya;
+          temp = recip * HEX_40000000;
+          double recipa = recip + temp - temp;
+          double recipb = recip - recipa;
+
+          // Correct for rounding in division
+          recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
+          // Account for yb
+          recipb += -yb * recip * recip;
+
+          recipa = -recipa;
+          recipb = -recipb;
+
+          // y = y + 1/y
+          temp = ya + recipa;
+          yb += -(temp - ya - recipa);
+          ya = temp;
+          temp = ya + recipb;
+          yb += -(temp - ya - recipb);
+          ya = temp;
+
+          result = ya + yb;
+          result *= 0.5;
+      }
+      else {
+          double hiPrec[] = new double[2];
+          expm1(x, hiPrec);
+
+          double ya = hiPrec[0] + hiPrec[1];
+          double yb = -(ya - hiPrec[0] - hiPrec[1]);
+
+          /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */
+          double denom = 1.0 + ya;
+          double denomr = 1.0 / denom;
+          double denomb = -(denom - 1.0 - ya) + yb;
+          double ratio = ya * denomr;
+          double temp = ratio * HEX_40000000;
+          double ra = ratio + temp - temp;
+          double rb = ratio - ra;
+
+          temp = denom * HEX_40000000;
+          double za = denom + temp - temp;
+          double zb = denom - za;
+
+          rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr;
+
+          // Adjust for yb
+          rb += yb*denomr;                        // numerator
+          rb += -ya * denomb * denomr * denomr;   // denominator
+
+          // y = y - 1/y
+          temp = ya + ra;
+          yb += -(temp - ya - ra);
+          ya = temp;
+          temp = ya + rb;
+          yb += -(temp - ya - rb);
+          ya = temp;
+
+          result = ya + yb;
+          result *= 0.5;
+      }
+
+      if (negate) {
+          result = -result;
+      }
+
+      return result;
+    }
+
+    /** Compute the hyperbolic tangent of a number.
+     * @param x number on which evaluation is done
+     * @return hyperbolic tangent of x
+     */
+    public static double tanh(double x) {
+      boolean negate = false;
+
+      if (x != x) {
+          return x;
+      }
+
+      if (x > 20.0) {
+          return 1.0;
+      }
+
+      if (x < -20) {
+          return -1.0;
+      }
+
+      if (x == 0) {
+          return x;
+      }
+
+      if (x < 0.0) {
+          x = -x;
+          negate = true;
+      }
+
+      double result;
+      if (x >= 0.5) {
+          double hiPrec[] = new double[2];
+          // tanh(x) = (exp(2x) - 1) / (exp(2x) + 1)
+          exp(x*2.0, 0.0, hiPrec);
+
+          double ya = hiPrec[0] + hiPrec[1];
+          double yb = -(ya - hiPrec[0] - hiPrec[1]);
+
+          /* Numerator */
+          double na = -1.0 + ya;
+          double nb = -(na + 1.0 - ya);
+          double temp = na + yb;
+          nb += -(temp - na - yb);
+          na = temp;
+
+          /* Denominator */
+          double da = 1.0 + ya;
+          double db = -(da - 1.0 - ya);
+          temp = da + yb;
+          db += -(temp - da - yb);
+          da = temp;
+
+          temp = da * HEX_40000000;
+          double daa = da + temp - temp;
+          double dab = da - daa;
+
+          // ratio = na/da
+          double ratio = na/da;
+          temp = ratio * HEX_40000000;
+          double ratioa = ratio + temp - temp;
+          double ratiob = ratio - ratioa;
+
+          // Correct for rounding in division
+          ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da;
+
+          // Account for nb
+          ratiob += nb / da;
+          // Account for db
+          ratiob += -db * na / da / da;
+
+          result = ratioa + ratiob;
+      }
+      else {
+          double hiPrec[] = new double[2];
+          // tanh(x) = expm1(2x) / (expm1(2x) + 2)
+          expm1(x*2.0, hiPrec);
+
+          double ya = hiPrec[0] + hiPrec[1];
+          double yb = -(ya - hiPrec[0] - hiPrec[1]);
+
+          /* Numerator */
+          double na = ya;
+          double nb = yb;
+
+          /* Denominator */
+          double da = 2.0 + ya;
+          double db = -(da - 2.0 - ya);
+          double temp = da + yb;
+          db += -(temp - da - yb);
+          da = temp;
+
+          temp = da * HEX_40000000;
+          double daa = da + temp - temp;
+          double dab = da - daa;
+
+          // ratio = na/da
+          double ratio = na/da;
+          temp = ratio * HEX_40000000;
+          double ratioa = ratio + temp - temp;
+          double ratiob = ratio - ratioa;
+
+          // Correct for rounding in division
+          ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da;
+
+          // Account for nb
+          ratiob += nb / da;
+          // Account for db
+          ratiob += -db * na / da / da;
+
+          result = ratioa + ratiob;
+      }
+
+      if (negate) {
+          result = -result;
+      }
+
+      return result;
+    }
+
+    /** Compute the inverse hyperbolic cosine of a number.
+     * @param a number on which evaluation is done
+     * @return inverse hyperbolic cosine of a
+     */
+    public static double acosh(final double a) {
+        return FastMath.log(a + FastMath.sqrt(a * a - 1));
+    }
+
+    /** Compute the inverse hyperbolic sine of a number.
+     * @param a number on which evaluation is done
+     * @return inverse hyperbolic sine of a
+     */
+    public static double asinh(double a) {
+
+        boolean negative = false;
+        if (a < 0) {
+            negative = true;
+            a = -a;
+        }
+
+        double absAsinh;
+        if (a > 0.167) {
+            absAsinh = FastMath.log(FastMath.sqrt(a * a + 1) + a);
+        } else {
+            final double a2 = a * a;
+            if (a > 0.097) {
+                absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0 - a2 * (1.0 / 11.0 - a2 * (1.0 / 13.0 - a2 * (1.0 / 15.0 - a2 * (1.0 / 17.0) * 15.0 / 16.0) * 13.0 / 14.0) * 11.0 / 12.0) * 9.0 / 10.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0);
+            } else if (a > 0.036) {
+                absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0 - a2 * (1.0 / 11.0 - a2 * (1.0 / 13.0) * 11.0 / 12.0) * 9.0 / 10.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0);
+            } else if (a > 0.0036) {
+                absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0 - a2 * (1 / 7.0 - a2 * (1 / 9.0) * 7.0 / 8.0) * 5.0 / 6.0) * 3.0 / 4.0) / 2.0);
+            } else {
+                absAsinh = a * (1 - a2 * (1 / 3.0 - a2 * (1 / 5.0) * 3.0 / 4.0) / 2.0);
+            }
+        }
+
+        return negative ? -absAsinh : absAsinh;
+
+    }
+
+    /** Compute the inverse hyperbolic tangent of a number.
+     * @param a number on which evaluation is done
+     * @return inverse hyperbolic tangent of a
+     */
+    public static double atanh(double a) {
+
+        boolean negative = false;
+        if (a < 0) {
+            negative = true;
+            a = -a;
+        }
+
+        double absAtanh;
+        if (a > 0.15) {
+            absAtanh = 0.5 * FastMath.log((1 + a) / (1 - a));
+        } else {
+            final double a2 = a * a;
+            if (a > 0.087) {
+                absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0 + a2 * (1.0 / 11.0 + a2 * (1.0 / 13.0 + a2 * (1.0 / 15.0 + a2 * (1.0 / 17.0)))))))));
+            } else if (a > 0.031) {
+                absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0 + a2 * (1.0 / 11.0 + a2 * (1.0 / 13.0)))))));
+            } else if (a > 0.003) {
+                absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0 + a2 * (1.0 / 7.0 + a2 * (1.0 / 9.0)))));
+            } else {
+                absAtanh = a * (1 + a2 * (1.0 / 3.0 + a2 * (1.0 / 5.0)));
+            }
+        }
+
+        return negative ? -absAtanh : absAtanh;
+
+    }
+
+    /** Compute the signum of a number.
+     * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
+     * @param a number on which evaluation is done
+     * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
+     */
+    public static double signum(final double a) {
+        return (a < 0.0) ? -1.0 : ((a > 0.0) ? 1.0 : a); // return +0.0/-0.0/NaN depending on a
+    }
+
+    /** Compute the signum of a number.
+     * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
+     * @param a number on which evaluation is done
+     * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
+     */
+    public static float signum(final float a) {
+        return (a < 0.0f) ? -1.0f : ((a > 0.0f) ? 1.0f : a); // return +0.0/-0.0/NaN depending on a
+    }
+
+    /** Compute next number towards positive infinity.
+     * @param a number to which neighbor should be computed
+     * @return neighbor of a towards positive infinity
+     */
+    public static double nextUp(final double a) {
+        return nextAfter(a, Double.POSITIVE_INFINITY);
+    }
+
+    /** Compute next number towards positive infinity.
+     * @param a number to which neighbor should be computed
+     * @return neighbor of a towards positive infinity
+     */
+    public static float nextUp(final float a) {
+        return nextAfter(a, Float.POSITIVE_INFINITY);
+    }
+
+    /** Returns a pseudo-random number between 0.0 and 1.0.
+     * <p><b>Note:</b> this implementation currently delegates to {@link Math#random}
+     * @return a random number between 0.0 and 1.0
+     */
+    public static double random() {
+        return Math.random();
+    }
+
+    /**
+     * Exponential function.
+     *
+     * Computes exp(x), function result is nearly rounded.   It will be correctly
+     * rounded to the theoretical value for 99.9% of input values, otherwise it will
+     * have a 1 UPL error.
+     *
+     * Method:
+     *    Lookup intVal = exp(int(x))
+     *    Lookup fracVal = exp(int(x-int(x) / 1024.0) * 1024.0 );
+     *    Compute z as the exponential of the remaining bits by a polynomial minus one
+     *    exp(x) = intVal * fracVal * (1 + z)
+     *
+     * Accuracy:
+     *    Calculation is done with 63 bits of precision, so result should be correctly
+     *    rounded for 99.9% of input values, with less than 1 ULP error otherwise.
+     *
+     * @param x   a double
+     * @return double e<sup>x</sup>
+     */
+    public static double exp(double x) {
+        return exp(x, 0.0, null);
+    }
+
+    /**
+     * Internal helper method for exponential function.
+     * @param x original argument of the exponential function
+     * @param extra extra bits of precision on input (To Be Confirmed)
+     * @param hiPrec extra bits of precision on output (To Be Confirmed)
+     * @return exp(x)
+     */
+    private static double exp(double x, double extra, double[] hiPrec) {
+        double intPartA;
+        double intPartB;
+        int intVal;
+
+        /* Lookup exp(floor(x)).
+         * intPartA will have the upper 22 bits, intPartB will have the lower
+         * 52 bits.
+         */
+        if (x < 0.0) {
+            intVal = (int) -x;
+
+            if (intVal > 746) {
+                if (hiPrec != null) {
+                    hiPrec[0] = 0.0;
+                    hiPrec[1] = 0.0;
+                }
+                return 0.0;
+            }
+
+            if (intVal > 709) {
+                /* This will produce a subnormal output */
+                final double result = exp(x+40.19140625, extra, hiPrec) / 285040095144011776.0;
+                if (hiPrec != null) {
+                    hiPrec[0] /= 285040095144011776.0;
+                    hiPrec[1] /= 285040095144011776.0;
+                }
+                return result;
+            }
+
+            if (intVal == 709) {
+                /* exp(1.494140625) is nearly a machine number... */
+                final double result = exp(x+1.494140625, extra, hiPrec) / 4.455505956692756620;
+                if (hiPrec != null) {
+                    hiPrec[0] /= 4.455505956692756620;
+                    hiPrec[1] /= 4.455505956692756620;
+                }
+                return result;
+            }
+
+            intVal++;
+
+            intPartA = EXP_INT_TABLE_A[750-intVal];
+            intPartB = EXP_INT_TABLE_B[750-intVal];
+
+            intVal = -intVal;
+        } else {
+            intVal = (int) x;
+
+            if (intVal > 709) {
+                if (hiPrec != null) {
+                    hiPrec[0] = Double.POSITIVE_INFINITY;
+                    hiPrec[1] = 0.0;
+                }
+                return Double.POSITIVE_INFINITY;
+            }
+
+            intPartA = EXP_INT_TABLE_A[750+intVal];
+            intPartB = EXP_INT_TABLE_B[750+intVal];
+        }
+
+        /* Get the fractional part of x, find the greatest multiple of 2^-10 less than
+         * x and look up the exp function of it.
+         * fracPartA will have the upper 22 bits, fracPartB the lower 52 bits.
+         */
+        final int intFrac = (int) ((x - intVal) * 1024.0);
+        final double fracPartA = EXP_FRAC_TABLE_A[intFrac];
+        final double fracPartB = EXP_FRAC_TABLE_B[intFrac];
+
+        /* epsilon is the difference in x from the nearest multiple of 2^-10.  It
+         * has a value in the range 0 <= epsilon < 2^-10.
+         * Do the subtraction from x as the last step to avoid possible loss of percison.
+         */
+        final double epsilon = x - (intVal + intFrac / 1024.0);
+
+        /* Compute z = exp(epsilon) - 1.0 via a minimax polynomial.  z has
+       full double precision (52 bits).  Since z < 2^-10, we will have
+       62 bits of precision when combined with the contant 1.  This will be
+       used in the last addition below to get proper rounding. */
+
+        /* Remez generated polynomial.  Converges on the interval [0, 2^-10], error
+       is less than 0.5 ULP */
+        double z = 0.04168701738764507;
+        z = z * epsilon + 0.1666666505023083;
+        z = z * epsilon + 0.5000000000042687;
+        z = z * epsilon + 1.0;
+        z = z * epsilon + -3.940510424527919E-20;
+
+        /* Compute (intPartA+intPartB) * (fracPartA+fracPartB) by binomial
+       expansion.
+       tempA is exact since intPartA and intPartB only have 22 bits each.
+       tempB will have 52 bits of precision.
+         */
+        double tempA = intPartA * fracPartA;
+        double tempB = intPartA * fracPartB + intPartB * fracPartA + intPartB * fracPartB;
+
+        /* Compute the result.  (1+z)(tempA+tempB).  Order of operations is
+       important.  For accuracy add by increasing size.  tempA is exact and
+       much larger than the others.  If there are extra bits specified from the
+       pow() function, use them. */
+        final double tempC = tempB + tempA;
+        final double result;
+        if (extra != 0.0) {
+            result = tempC*extra*z + tempC*extra + tempC*z + tempB + tempA;
+        } else {
+            result = tempC*z + tempB + tempA;
+        }
+
+        if (hiPrec != null) {
+            // If requesting high precision
+            hiPrec[0] = tempA;
+            hiPrec[1] = tempC*extra*z + tempC*extra + tempC*z + tempB;
+        }
+
+        return result;
+    }
+
+    /** Compute exp(x) - 1
+     * @param x number to compute shifted exponential
+     * @return exp(x) - 1
+     */
+    public static double expm1(double x) {
+      return expm1(x, null);
+    }
+
+    /** Internal helper method for expm1
+     * @param x number to compute shifted exponential
+     * @param hiPrecOut receive high precision result for -1.0 < x < 1.0
+     * @return exp(x) - 1
+     */
+    private static double expm1(double x, double hiPrecOut[]) {
+        if (x != x || x == 0.0) { // NaN or zero
+            return x;
+        }
+
+        if (x <= -1.0 || x >= 1.0) {
+            // If not between +/- 1.0
+            //return exp(x) - 1.0;
+            double hiPrec[] = new double[2];
+            exp(x, 0.0, hiPrec);
+            if (x > 0.0) {
+                return -1.0 + hiPrec[0] + hiPrec[1];
+            } else {
+                final double ra = -1.0 + hiPrec[0];
+                double rb = -(ra + 1.0 - hiPrec[0]);
+                rb += hiPrec[1];
+                return ra + rb;
+            }
+        }
+
+        double baseA;
+        double baseB;
+        double epsilon;
+        boolean negative = false;
+
+        if (x < 0.0) {
+            x = -x;
+            negative = true;
+        }
+
+        {
+            int intFrac = (int) (x * 1024.0);
+            double tempA = EXP_FRAC_TABLE_A[intFrac] - 1.0;
+            double tempB = EXP_FRAC_TABLE_B[intFrac];
+
+            double temp = tempA + tempB;
+            tempB = -(temp - tempA - tempB);
+            tempA = temp;
+
+            temp = tempA * HEX_40000000;
+            baseA = tempA + temp - temp;
+            baseB = tempB + (tempA - baseA);
+
+            epsilon = x - intFrac/1024.0;
+        }
+
+
+        /* Compute expm1(epsilon) */
+        double zb = 0.008336750013465571;
+        zb = zb * epsilon + 0.041666663879186654;
+        zb = zb * epsilon + 0.16666666666745392;
+        zb = zb * epsilon + 0.49999999999999994;
+        zb = zb * epsilon;
+        zb = zb * epsilon;
+
+        double za = epsilon;
+        double temp = za + zb;
+        zb = -(temp - za - zb);
+        za = temp;
+
+        temp = za * HEX_40000000;
+        temp = za + temp - temp;
+        zb += za - temp;
+        za = temp;
+
+        /* Combine the parts.   expm1(a+b) = expm1(a) + expm1(b) + expm1(a)*expm1(b) */
+        double ya = za * baseA;
+        //double yb = za*baseB + zb*baseA + zb*baseB;
+        temp = ya + za * baseB;
+        double yb = -(temp - ya - za * baseB);
+        ya = temp;
+
+        temp = ya + zb * baseA;
+        yb += -(temp - ya - zb * baseA);
+        ya = temp;
+
+        temp = ya + zb * baseB;
+        yb += -(temp - ya - zb*baseB);
+        ya = temp;
+
+        //ya = ya + za + baseA;
+        //yb = yb + zb + baseB;
+        temp = ya + baseA;
+        yb += -(temp - baseA - ya);
+        ya = temp;
+
+        temp = ya + za;
+        //yb += (ya > za) ? -(temp - ya - za) : -(temp - za - ya);
+        yb += -(temp - ya - za);
+        ya = temp;
+
+        temp = ya + baseB;
+        //yb += (ya > baseB) ? -(temp - ya - baseB) : -(temp - baseB - ya);
+        yb += -(temp - ya - baseB);
+        ya = temp;
+
+        temp = ya + zb;
+        //yb += (ya > zb) ? -(temp - ya - zb) : -(temp - zb - ya);
+        yb += -(temp - ya - zb);
+        ya = temp;
+
+        if (negative) {
+            /* Compute expm1(-x) = -expm1(x) / (expm1(x) + 1) */
+            double denom = 1.0 + ya;
+            double denomr = 1.0 / denom;
+            double denomb = -(denom - 1.0 - ya) + yb;
+            double ratio = ya * denomr;
+            temp = ratio * HEX_40000000;
+            final double ra = ratio + temp - temp;
+            double rb = ratio - ra;
+
+            temp = denom * HEX_40000000;
+            za = denom + temp - temp;
+            zb = denom - za;
+
+            rb += (ya - za * ra - za * rb - zb * ra - zb * rb) * denomr;
+
+            // f(x) = x/1+x
+            // Compute f'(x)
+            // Product rule:  d(uv) = du*v + u*dv
+            // Chain rule:  d(f(g(x)) = f'(g(x))*f(g'(x))
+            // d(1/x) = -1/(x*x)
+            // d(1/1+x) = -1/( (1+x)^2) *  1 =  -1/((1+x)*(1+x))
+            // d(x/1+x) = -x/((1+x)(1+x)) + 1/1+x = 1 / ((1+x)(1+x))
+
+            // Adjust for yb
+            rb += yb * denomr;                      // numerator
+            rb += -ya * denomb * denomr * denomr;   // denominator
+
+            // negate
+            ya = -ra;
+            yb = -rb;
+        }
+
+        if (hiPrecOut != null) {
+            hiPrecOut[0] = ya;
+            hiPrecOut[1] = yb;
+        }
+
+        return ya + yb;
+    }
+
+    /**
+     *  For x between 0 and 1, returns exp(x), uses extended precision
+     *  @param x argument of exponential
+     *  @param result placeholder where to place exp(x) split in two terms
+     *  for extra precision (i.e. exp(x) = result[0] ° result[1]
+     *  @return exp(x)
+     */
+    private static double slowexp(final double x, final double result[]) {
+        final double xs[] = new double[2];
+        final double ys[] = new double[2];
+        final double facts[] = new double[2];
+        final double as[] = new double[2];
+        split(x, xs);
+        ys[0] = ys[1] = 0.0;
+
+        for (int i = 19; i >= 0; i--) {
+            splitMult(xs, ys, as);
+            ys[0] = as[0];
+            ys[1] = as[1];
+
+            split(FACT[i], as);
+            splitReciprocal(as, facts);
+
+            splitAdd(ys, facts, as);
+            ys[0] = as[0];
+            ys[1] = as[1];
+        }
+
+        if (result != null) {
+            result[0] = ys[0];
+            result[1] = ys[1];
+        }
+
+        return ys[0] + ys[1];
+    }
+
+    /** Compute split[0], split[1] such that their sum is equal to d,
+     * and split[0] has its 30 least significant bits as zero.
+     * @param d number to split
+     * @param split placeholder where to place the result
+     */
+    private static void split(final double d, final double split[]) {
+        if (d < 8e298 && d > -8e298) {
+            final double a = d * HEX_40000000;
+            split[0] = (d + a) - a;
+            split[1] = d - split[0];
+        } else {
+            final double a = d * 9.31322574615478515625E-10;
+            split[0] = (d + a - d) * HEX_40000000;
+            split[1] = d - split[0];
+        }
+    }
+
+    /** Recompute a split.
+     * @param a input/out array containing the split, changed
+     * on output
+     */
+    private static void resplit(final double a[]) {
+        final double c = a[0] + a[1];
+        final double d = -(c - a[0] - a[1]);
+
+        if (c < 8e298 && c > -8e298) {
+            double z = c * HEX_40000000;
+            a[0] = (c + z) - z;
+            a[1] = c - a[0] + d;
+        } else {
+            double z = c * 9.31322574615478515625E-10;
+            a[0] = (c + z - c) * HEX_40000000;
+            a[1] = c - a[0] + d;
+        }
+    }
+
+    /** Multiply two numbers in split form.
+     * @param a first term of multiplication
+     * @param b second term of multiplication
+     * @param ans placeholder where to put the result
+     */
+    private static void splitMult(double a[], double b[], double ans[]) {
+        ans[0] = a[0] * b[0];
+        ans[1] = a[0] * b[1] + a[1] * b[0] + a[1] * b[1];
+
+        /* Resplit */
+        resplit(ans);
+    }
+
+    /** Add two numbers in split form.
+     * @param a first term of addition
+     * @param b second term of addition
+     * @param ans placeholder where to put the result
+     */
+    private static void splitAdd(final double a[], final double b[], final double ans[]) {
+        ans[0] = a[0] + b[0];
+        ans[1] = a[1] + b[1];
+
+        resplit(ans);
+    }
+
+    /** Compute the reciprocal of in.  Use the following algorithm.
+     *  in = c + d.
+     *  want to find x + y such that x+y = 1/(c+d) and x is much
+     *  larger than y and x has several zero bits on the right.
+     *
+     *  Set b = 1/(2^22),  a = 1 - b.  Thus (a+b) = 1.
+     *  Use following identity to compute (a+b)/(c+d)
+     *
+     *  (a+b)/(c+d)  =   a/c   +    (bc - ad) / (c^2 + cd)
+     *  set x = a/c  and y = (bc - ad) / (c^2 + cd)
+     *  This will be close to the right answer, but there will be
+     *  some rounding in the calculation of X.  So by carefully
+     *  computing 1 - (c+d)(x+y) we can compute an error and
+     *  add that back in.   This is done carefully so that terms
+     *  of similar size are subtracted first.
+     *  @param in initial number, in split form
+     *  @param result placeholder where to put the result
+     */
+    private static void splitReciprocal(final double in[], final double result[]) {
+        final double b = 1.0/4194304.0;
+        final double a = 1.0 - b;
+
+        if (in[0] == 0.0) {
+            in[0] = in[1];
+            in[1] = 0.0;
+        }
+
+        result[0] = a / in[0];
+        result[1] = (b*in[0]-a*in[1]) / (in[0]*in[0] + in[0]*in[1]);
+
+        if (result[1] != result[1]) { // can happen if result[1] is NAN
+            result[1] = 0.0;
+        }
+
+        /* Resplit */
+        resplit(result);
+
+        for (int i = 0; i < 2; i++) {
+            /* this may be overkill, probably once is enough */
+            double err = 1.0 - result[0] * in[0] - result[0] * in[1] -
+            result[1] * in[0] - result[1] * in[1];
+            /*err = 1.0 - err; */
+            err = err * (result[0] + result[1]);
+            /*printf("err = %16e\n", err); */
+            result[1] += err;
+        }
+    }
+
+    /** Compute (a[0] + a[1]) * (b[0] + b[1]) in extended precision.
+     * @param a first term of the multiplication
+     * @param b second term of the multiplication
+     * @param result placeholder where to put the result
+     */
+    private static void quadMult(final double a[], final double b[], final double result[]) {
+        final double xs[] = new double[2];
+        final double ys[] = new double[2];
+        final double zs[] = new double[2];
+
+        /* a[0] * b[0] */
+        split(a[0], xs);
+        split(b[0], ys);
+        splitMult(xs, ys, zs);
+
+        result[0] = zs[0];
+        result[1] = zs[1];
+
+        /* a[0] * b[1] */
+        split(b[1], ys);
+        splitMult(xs, ys, zs);
+
+        double tmp = result[0] + zs[0];
+        result[1] = result[1] - (tmp - result[0] - zs[0]);
+        result[0] = tmp;
+        tmp = result[0] + zs[1];
+        result[1] = result[1] - (tmp - result[0] - zs[1]);
+        result[0] = tmp;
+
+        /* a[1] * b[0] */
+        split(a[1], xs);
+        split(b[0], ys);
+        splitMult(xs, ys, zs);
+
+        tmp = result[0] + zs[0];
+        result[1] = result[1] - (tmp - result[0] - zs[0]);
+        result[0] = tmp;
+        tmp = result[0] + zs[1];
+        result[1] = result[1] - (tmp - result[0] - zs[1]);
+        result[0] = tmp;
+
+        /* a[1] * b[0] */
+        split(a[1], xs);
+        split(b[1], ys);
+        splitMult(xs, ys, zs);
+
+        tmp = result[0] + zs[0];
+        result[1] = result[1] - (tmp - result[0] - zs[0]);
+        result[0] = tmp;
+        tmp = result[0] + zs[1];
+        result[1] = result[1] - (tmp - result[0] - zs[1]);
+        result[0] = tmp;
+    }
+
+    /** Compute exp(p) for a integer p in extended precision.
+     * @param p integer whose exponential is requested
+     * @param result placeholder where to put the result in extended precision
+     * @return exp(p) in standard precision (equal to result[0] + result[1])
+     */
+    private static double expint(int p, final double result[]) {
+        //double x = M_E;
+        final double xs[] = new double[2];
+        final double as[] = new double[2];
+        final double ys[] = new double[2];
+        //split(x, xs);
+        //xs[1] = (double)(2.7182818284590452353602874713526625L - xs[0]);
+        //xs[0] = 2.71827697753906250000;
+        //xs[1] = 4.85091998273542816811e-06;
+        //xs[0] = Double.longBitsToDouble(0x4005bf0800000000L);
+        //xs[1] = Double.longBitsToDouble(0x3ed458a2bb4a9b00L);
+
+        /* E */
+        xs[0] = 2.718281828459045;
+        xs[1] = 1.4456468917292502E-16;
+
+        split(1.0, ys);
+
+        while (p > 0) {
+            if ((p & 1) != 0) {
+                quadMult(ys, xs, as);
+                ys[0] = as[0]; ys[1] = as[1];
+            }
+
+            quadMult(xs, xs, as);
+            xs[0] = as[0]; xs[1] = as[1];
+
+            p >>= 1;
+        }
+
+        if (result != null) {
+            result[0] = ys[0];
+            result[1] = ys[1];
+
+            resplit(result);
+        }
+
+        return ys[0] + ys[1];
+    }
+
+
+    /**
+     * Natural logarithm.
+     *
+     * @param x   a double
+     * @return log(x)
+     */
+    public static double log(final double x) {
+        return log(x, null);
+    }
+
+    /**
+     * Internal helper method for natural logarithm function.
+     * @param x original argument of the natural logarithm function
+     * @param hiPrec extra bits of precision on output (To Be Confirmed)
+     * @return log(x)
+     */
+    private static double log(final double x, final double[] hiPrec) {
+        if (x==0) { // Handle special case of +0/-0
+            return Double.NEGATIVE_INFINITY;
+        }
+        long bits = Double.doubleToLongBits(x);
+
+        /* Handle special cases of negative input, and NaN */
+        if ((bits & 0x8000000000000000L) != 0 || x != x) {
+            if (x != 0.0) {
+                if (hiPrec != null) {
+                    hiPrec[0] = Double.NaN;
+                }
+
+                return Double.NaN;
+            }
+        }
+
+        /* Handle special cases of Positive infinity. */
+        if (x == Double.POSITIVE_INFINITY) {
+            if (hiPrec != null) {
+                hiPrec[0] = Double.POSITIVE_INFINITY;
+            }
+
+            return Double.POSITIVE_INFINITY;
+        }
+
+        /* Extract the exponent */
+        int exp = (int)(bits >> 52)-1023;
+
+        if ((bits & 0x7ff0000000000000L) == 0) {
+            // Subnormal!
+            if (x == 0) {
+                // Zero
+                if (hiPrec != null) {
+                    hiPrec[0] = Double.NEGATIVE_INFINITY;
+                }
+
+                return Double.NEGATIVE_INFINITY;
+            }
+
+            /* Normalize the subnormal number. */
+            bits <<= 1;
+            while ( (bits & 0x0010000000000000L) == 0) {
+                exp--;
+                bits <<= 1;
+            }
+        }
+
+
+        if (exp == -1 || exp == 0) {
+            if (x < 1.01 && x > 0.99 && hiPrec == null) {
+                /* The normal method doesn't work well in the range [0.99, 1.01], so call do a straight
+           polynomial expansion in higer precision. */
+
+               /* Compute x - 1.0 and split it */
+                double xa = x - 1.0;
+                double xb = xa - x + 1.0;
+                double tmp = xa * HEX_40000000;
+                double aa = xa + tmp - tmp;
+                double ab = xa - aa;
+                xa = aa;
+                xb = ab;
+
+                double ya = LN_QUICK_COEF[LN_QUICK_COEF.length-1][0];
+                double yb = LN_QUICK_COEF[LN_QUICK_COEF.length-1][1];
+
+                for (int i = LN_QUICK_COEF.length - 2; i >= 0; i--) {
+                    /* Multiply a = y * x */
+                    aa = ya * xa;
+                    ab = ya * xb + yb * xa + yb * xb;
+                    /* split, so now y = a */
+                    tmp = aa * HEX_40000000;
+                    ya = aa + tmp - tmp;
+                    yb = aa - ya + ab;
+
+                    /* Add  a = y + lnQuickCoef */
+                    aa = ya + LN_QUICK_COEF[i][0];
+                    ab = yb + LN_QUICK_COEF[i][1];
+                    /* Split y = a */
+                    tmp = aa * HEX_40000000;
+                    ya = aa + tmp - tmp;
+                    yb = aa - ya + ab;
+                }
+
+                /* Multiply a = y * x */
+                aa = ya * xa;
+                ab = ya * xb + yb * xa + yb * xb;
+                /* split, so now y = a */
+                tmp = aa * HEX_40000000;
+                ya = aa + tmp - tmp;
+                yb = aa - ya + ab;
+
+                return ya + yb;
+            }
+        }
+
+        // lnm is a log of a number in the range of 1.0 - 2.0, so 0 <= lnm < ln(2)
+        double lnm[] = LN_MANT[(int)((bits & 0x000ffc0000000000L) >> 42)];
+
+        /*
+    double epsilon = x / Double.longBitsToDouble(bits & 0xfffffc0000000000L);
+
+    epsilon -= 1.0;
+         */
+
+        // y is the most significant 10 bits of the mantissa
+        //double y = Double.longBitsToDouble(bits & 0xfffffc0000000000L);
+        //double epsilon = (x - y) / y;
+        double epsilon = (bits & 0x3ffffffffffL) / (TWO_POWER_52 + (bits & 0x000ffc0000000000L));
+
+        double lnza = 0.0;
+        double lnzb = 0.0;
+
+        if (hiPrec != null) {
+            /* split epsilon -> x */
+            double tmp = epsilon * HEX_40000000;
+            double aa = epsilon + tmp - tmp;
+            double ab = epsilon - aa;
+            double xa = aa;
+            double xb = ab;
+
+            /* Need a more accurate epsilon, so adjust the division. */
+            double numer = bits & 0x3ffffffffffL;
+            double denom = TWO_POWER_52 + (bits & 0x000ffc0000000000L);
+            aa = numer - xa*denom - xb * denom;
+            xb += aa / denom;
+
+            /* Remez polynomial evaluation */
+            double ya = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1][0];
+            double yb = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1][1];
+
+            for (int i = LN_HI_PREC_COEF.length - 2; i >= 0; i--) {
+                /* Multiply a = y * x */
+                aa = ya * xa;
+                ab = ya * xb + yb * xa + yb * xb;
+                /* split, so now y = a */
+                tmp = aa * HEX_40000000;
+                ya = aa + tmp - tmp;
+                yb = aa - ya + ab;
+
+                /* Add  a = y + lnHiPrecCoef */
+                aa = ya + LN_HI_PREC_COEF[i][0];
+                ab = yb + LN_HI_PREC_COEF[i][1];
+                /* Split y = a */
+                tmp = aa * HEX_40000000;
+                ya = aa + tmp - tmp;
+                yb = aa - ya + ab;
+            }
+
+            /* Multiply a = y * x */
+            aa = ya * xa;
+            ab = ya * xb + yb * xa + yb * xb;
+
+            /* split, so now lnz = a */
+            /*
+      tmp = aa * 1073741824.0;
+      lnza = aa + tmp - tmp;
+      lnzb = aa - lnza + ab;
+             */
+            lnza = aa + ab;
+            lnzb = -(lnza - aa - ab);
+        } else {
+            /* High precision not required.  Eval Remez polynomial
+         using standard double precision */
+            lnza = -0.16624882440418567;
+            lnza = lnza * epsilon + 0.19999954120254515;
+            lnza = lnza * epsilon + -0.2499999997677497;
+            lnza = lnza * epsilon + 0.3333333333332802;
+            lnza = lnza * epsilon + -0.5;
+            lnza = lnza * epsilon + 1.0;
+            lnza = lnza * epsilon;
+        }
+
+        /* Relative sizes:
+         * lnzb     [0, 2.33E-10]
+         * lnm[1]   [0, 1.17E-7]
+         * ln2B*exp [0, 1.12E-4]
+         * lnza      [0, 9.7E-4]
+         * lnm[0]   [0, 0.692]
+         * ln2A*exp [0, 709]
+         */
+
+        /* Compute the following sum:
+         * lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp;
+         */
+
+        //return lnzb + lnm[1] + ln2B*exp + lnza + lnm[0] + ln2A*exp;
+        double a = LN_2_A*exp;
+        double b = 0.0;
+        double c = a+lnm[0];
+        double d = -(c-a-lnm[0]);
+        a = c;
+        b = b + d;
+
+        c = a + lnza;
+        d = -(c - a - lnza);
+        a = c;
+        b = b + d;
+
+        c = a + LN_2_B*exp;
+        d = -(c - a - LN_2_B*exp);
+        a = c;
+        b = b + d;
+
+        c = a + lnm[1];
+        d = -(c - a - lnm[1]);
+        a = c;
+        b = b + d;
+
+        c = a + lnzb;
+        d = -(c - a - lnzb);
+        a = c;
+        b = b + d;
+
+        if (hiPrec != null) {
+            hiPrec[0] = a;
+            hiPrec[1] = b;
+        }
+
+        return a + b;
+    }
+
+    /** Compute log(1 + x).
+     * @param x a number
+     * @return log(1 + x)
+     */
+    public static double log1p(final double x) {
+        double xpa = 1.0 + x;
+        double xpb = -(xpa - 1.0 - x);
+
+        if (x == -1) {
+            return x/0.0;   // -Infinity
+        }
+
+        if (x > 0 && 1/x == 0) { // x = Infinity
+            return x;
+        }
+
+        if (x>1e-6 || x<-1e-6) {
+            double hiPrec[] = new double[2];
+
+            final double lores = log(xpa, hiPrec);
+            if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN
+                return lores;
+            }
+
+            /* Do a taylor series expansion around xpa */
+            /* f(x+y) = f(x) + f'(x)*y + f''(x)/2 y^2 */
+            double fx1 = xpb/xpa;
+
+            double epsilon = 0.5 * fx1 + 1.0;
+            epsilon = epsilon * fx1;
+
+            return epsilon + hiPrec[1] + hiPrec[0];
+        }
+
+        /* Value is small |x| < 1e6, do a Taylor series centered on 1.0 */
+        double y = x * 0.333333333333333 - 0.5;
+        y = y * x + 1.0;
+        y = y * x;
+
+        return y;
+    }
+
+    /** Compute the base 10 logarithm.
+     * @param x a number
+     * @return log10(x)
+     */
+    public static double log10(final double x) {
+        final double hiPrec[] = new double[2];
+
+        final double lores = log(x, hiPrec);
+        if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN
+            return lores;
+        }
+
+        final double tmp = hiPrec[0] * HEX_40000000;
+        final double lna = hiPrec[0] + tmp - tmp;
+        final double lnb = hiPrec[0] - lna + hiPrec[1];
+
+        final double rln10a = 0.4342944622039795;
+        final double rln10b = 1.9699272335463627E-8;
+
+        return rln10b * lnb + rln10b * lna + rln10a * lnb + rln10a * lna;
+    }
+
+    /**
+     * Power function.  Compute x^y.
+     *
+     * @param x   a double
+     * @param y   a double
+     * @return double
+     */
+    public static double pow(double x, double y) {
+        final double lns[] = new double[2];
+
+        if (y == 0.0) {
+            return 1.0;
+        }
+
+        if (x != x) { // X is NaN
+            return x;
+        }
+
+
+        if (x == 0) {
+            long bits = Double.doubleToLongBits(x);
+            if ((bits & 0x8000000000000000L) != 0) {
+                // -zero
+                long yi = (long) y;
+
+                if (y < 0 && y == yi && (yi & 1) == 1) {
+                    return Double.NEGATIVE_INFINITY;
+                }
+
+                if (y < 0 && y == yi && (yi & 1) == 1) {
+                    return -0.0;
+                }
+
+                if (y > 0 && y == yi && (yi & 1) == 1) {
+                    return -0.0;
+                }
+            }
+
+            if (y < 0) {
+                return Double.POSITIVE_INFINITY;
+            }
+            if (y > 0) {
+                return 0.0;
+            }
+
+            return Double.NaN;
+        }
+
+        if (x == Double.POSITIVE_INFINITY) {
+            if (y != y) { // y is NaN
+                return y;
+            }
+            if (y < 0.0) {
+                return 0.0;
+            } else {
+                return Double.POSITIVE_INFINITY;
+            }
+        }
+
+        if (y == Double.POSITIVE_INFINITY) {
+            if (x * x == 1.0)
+              return Double.NaN;
+
+            if (x * x > 1.0) {
+                return Double.POSITIVE_INFINITY;
+            } else {
+                return 0.0;
+            }
+        }
+
+        if (x == Double.NEGATIVE_INFINITY) {
+            if (y != y) { // y is NaN
+                return y;
+            }
+
+            if (y < 0) {
+                long yi = (long) y;
+                if (y == yi && (yi & 1) == 1) {
+                    return -0.0;
+                }
+
+                return 0.0;
+            }
+
+            if (y > 0)  {
+                long yi = (long) y;
+                if (y == yi && (yi & 1) == 1) {
+                    return Double.NEGATIVE_INFINITY;
+                }
+
+                return Double.POSITIVE_INFINITY;
+            }
+        }
+
+        if (y == Double.NEGATIVE_INFINITY) {
+
+            if (x * x == 1.0) {
+                return Double.NaN;
+            }
+
+            if (x * x < 1.0) {
+                return Double.POSITIVE_INFINITY;
+            } else {
+                return 0.0;
+            }
+        }
+
+        /* Handle special case x<0 */
+        if (x < 0) {
+            // y is an even integer in this case
+            if (y >= TWO_POWER_52 || y <= -TWO_POWER_52) {
+                return pow(-x, y);
+            }
+
+            if (y == (long) y) {
+                // If y is an integer
+                return ((long)y & 1) == 0 ? pow(-x, y) : -pow(-x, y);
+            } else {
+                return Double.NaN;
+            }
+        }
+
+        /* Split y into ya and yb such that y = ya+yb */
+        double ya;
+        double yb;
+        if (y < 8e298 && y > -8e298) {
+            double tmp1 = y * HEX_40000000;
+            ya = y + tmp1 - tmp1;
+            yb = y - ya;
+        } else {
+            double tmp1 = y * 9.31322574615478515625E-10;
+            double tmp2 = tmp1 * 9.31322574615478515625E-10;
+            ya = (tmp1 + tmp2 - tmp1) * HEX_40000000 * HEX_40000000;
+            yb = y - ya;
+        }
+
+        /* Compute ln(x) */
+        final double lores = log(x, lns);
+        if (Double.isInfinite(lores)){ // don't allow this to be converted to NaN
+            return lores;
+        }
+
+        double lna = lns[0];
+        double lnb = lns[1];
+
+        /* resplit lns */
+        double tmp1 = lna * HEX_40000000;
+        double tmp2 = lna + tmp1 - tmp1;
+        lnb += lna - tmp2;
+        lna = tmp2;
+
+        // y*ln(x) = (aa+ab)
+        final double aa = lna * ya;
+        final double ab = lna * yb + lnb * ya + lnb * yb;
+
+        lna = aa+ab;
+        lnb = -(lna - aa - ab);
+
+        double z = 1.0 / 120.0;
+        z = z * lnb + (1.0 / 24.0);
+        z = z * lnb + (1.0 / 6.0);
+        z = z * lnb + 0.5;
+        z = z * lnb + 1.0;
+        z = z * lnb;
+
+        final double result = exp(lna, z, null);
+        //result = result + result * z;
+        return result;
+    }
+
+    /** xi in the range of [1, 2].
+     *                                3        5        7
+     *      x+1           /          x        x        x          \
+     *  ln ----- =   2 *  |  x  +   ----  +  ----  +  ---- + ...  |
+     *      1-x           \          3        5        7          /
+     *
+     * So, compute a Remez approximation of the following function
+     *
+     *  ln ((sqrt(x)+1)/(1-sqrt(x)))  /  x
+     *
+     * This will be an even function with only positive coefficents.
+     * x is in the range [0 - 1/3].
+     *
+     * Transform xi for input to the above function by setting
+     * x = (xi-1)/(xi+1).   Input to the polynomial is x^2, then
+     * the result is multiplied by x.
+     * @param xi number from which log is requested
+     * @return log(xi)
+     */
+    private static double[] slowLog(double xi) {
+        double x[] = new double[2];
+        double x2[] = new double[2];
+        double y[] = new double[2];
+        double a[] = new double[2];
+
+        split(xi, x);
+
+        /* Set X = (x-1)/(x+1) */
+        x[0] += 1.0;
+        resplit(x);
+        splitReciprocal(x, a);
+        x[0] -= 2.0;
+        resplit(x);
+        splitMult(x, a, y);
+        x[0] = y[0];
+        x[1] = y[1];
+
+        /* Square X -> X2*/
+        splitMult(x, x, x2);
+
+
+        //x[0] -= 1.0;
+        //resplit(x);
+
+        y[0] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][0];
+        y[1] = LN_SPLIT_COEF[LN_SPLIT_COEF.length-1][1];
+
+        for (int i = LN_SPLIT_COEF.length-2; i >= 0; i--) {
+            splitMult(y, x2, a);
+            y[0] = a[0];
+            y[1] = a[1];
+            splitAdd(y, LN_SPLIT_COEF[i], a);
+            y[0] = a[0];
+            y[1] = a[1];
+        }
+
+        splitMult(y, x, a);
+        y[0] = a[0];
+        y[1] = a[1];
+
+        return y;
+    }
+
+    /**
+     * For x between 0 and pi/4 compute sine.
+     * @param x number from which sine is requested
+     * @param result placeholder where to put the result in extended precision
+     * @return sin(x)
+     */
+    private static double slowSin(final double x, final double result[]) {
+        final double xs[] = new double[2];
+        final double ys[] = new double[2];
+        final double facts[] = new double[2];
+        final double as[] = new double[2];
+        split(x, xs);
+        ys[0] = ys[1] = 0.0;
+
+        for (int i = 19; i >= 0; i--) {
+            splitMult(xs, ys, as);
+            ys[0] = as[0]; ys[1] = as[1];
+
+            if ( (i & 1) == 0) {
+                continue;
+            }
+
+            split(FACT[i], as);
+            splitReciprocal(as, facts);
+
+            if ( (i & 2) != 0 ) {
+                facts[0] = -facts[0];
+                facts[1] = -facts[1];
+            }
+
+            splitAdd(ys, facts, as);
+            ys[0] = as[0]; ys[1] = as[1];
+        }
+
+        if (result != null) {
+            result[0] = ys[0];
+            result[1] = ys[1];
+        }
+
+        return ys[0] + ys[1];
+    }
+
+    /**
+     *  For x between 0 and pi/4 compute cosine
+     * @param x number from which cosine is requested
+     * @param result placeholder where to put the result in extended precision
+     * @return cos(x)
+     */
+    private static double slowCos(final double x, final double result[]) {
+
+        final double xs[] = new double[2];
+        final double ys[] = new double[2];
+        final double facts[] = new double[2];
+        final double as[] = new double[2];
+        split(x, xs);
+        ys[0] = ys[1] = 0.0;
+
+        for (int i = 19; i >= 0; i--) {
+            splitMult(xs, ys, as);
+            ys[0] = as[0]; ys[1] = as[1];
+
+            if ( (i & 1) != 0) {
+                continue;
+            }
+
+            split(FACT[i], as);
+            splitReciprocal(as, facts);
+
+            if ( (i & 2) != 0 ) {
+                facts[0] = -facts[0];
+                facts[1] = -facts[1];
+            }
+
+            splitAdd(ys, facts, as);
+            ys[0] = as[0]; ys[1] = as[1];
+        }
+
+        if (result != null) {
+            result[0] = ys[0];
+            result[1] = ys[1];
+        }
+
+        return ys[0] + ys[1];
+    }
+
+    /** Build the sine and cosine tables.
+     */
+    private static void buildSinCosTables() {
+        final double result[] = new double[2];
+
+        /* Use taylor series for 0 <= x <= 6/8 */
+        for (int i = 0; i < 7; i++) {
+            double x = i / 8.0;
+
+            slowSin(x, result);
+            SINE_TABLE_A[i] = result[0];
+            SINE_TABLE_B[i] = result[1];
+
+            slowCos(x, result);
+            COSINE_TABLE_A[i] = result[0];
+            COSINE_TABLE_B[i] = result[1];
+        }
+
+        /* Use angle addition formula to complete table to 13/8, just beyond pi/2 */
+        for (int i = 7; i < 14; i++) {
+            double xs[] = new double[2];
+            double ys[] = new double[2];
+            double as[] = new double[2];
+            double bs[] = new double[2];
+            double temps[] = new double[2];
+
+            if ( (i & 1) == 0) {
+                // Even, use double angle
+                xs[0] = SINE_TABLE_A[i/2];
+                xs[1] = SINE_TABLE_B[i/2];
+                ys[0] = COSINE_TABLE_A[i/2];
+                ys[1] = COSINE_TABLE_B[i/2];
+
+                /* compute sine */
+                splitMult(xs, ys, result);
+                SINE_TABLE_A[i] = result[0] * 2.0;
+                SINE_TABLE_B[i] = result[1] * 2.0;
+
+                /* Compute cosine */
+                splitMult(ys, ys, as);
+                splitMult(xs, xs, temps);
+                temps[0] = -temps[0];
+                temps[1] = -temps[1];
+                splitAdd(as, temps, result);
+                COSINE_TABLE_A[i] = result[0];
+                COSINE_TABLE_B[i] = result[1];
+            } else {
+                xs[0] = SINE_TABLE_A[i/2];
+                xs[1] = SINE_TABLE_B[i/2];
+                ys[0] = COSINE_TABLE_A[i/2];
+                ys[1] = COSINE_TABLE_B[i/2];
+                as[0] = SINE_TABLE_A[i/2+1];
+                as[1] = SINE_TABLE_B[i/2+1];
+                bs[0] = COSINE_TABLE_A[i/2+1];
+                bs[1] = COSINE_TABLE_B[i/2+1];
+
+                /* compute sine */
+                splitMult(xs, bs, temps);
+                splitMult(ys, as, result);
+                splitAdd(result, temps, result);
+                SINE_TABLE_A[i] = result[0];
+                SINE_TABLE_B[i] = result[1];
+
+                /* Compute cosine */
+                splitMult(ys, bs, result);
+                splitMult(xs, as, temps);
+                temps[0] = -temps[0];
+                temps[1] = -temps[1];
+                splitAdd(result, temps, result);
+                COSINE_TABLE_A[i] = result[0];
+                COSINE_TABLE_B[i] = result[1];
+            }
+        }
+
+        /* Compute tangent = sine/cosine */
+        for (int i = 0; i < 14; i++) {
+            double xs[] = new double[2];
+            double ys[] = new double[2];
+            double as[] = new double[2];
+
+            as[0] = COSINE_TABLE_A[i];
+            as[1] = COSINE_TABLE_B[i];
+
+            splitReciprocal(as, ys);
+
+            xs[0] = SINE_TABLE_A[i];
+            xs[1] = SINE_TABLE_B[i];
+
+            splitMult(xs, ys, as);
+
+            TANGENT_TABLE_A[i] = as[0];
+            TANGENT_TABLE_B[i] = as[1];
+        }
+
+    }
+
+    /**
+     *  Computes sin(x) - x, where |x| < 1/16.
+     *  Use a Remez polynomial approximation.
+     *  @param x a number smaller than 1/16
+     *  @return sin(x) - x
+     */
+    private static double polySine(final double x)
+    {
+        double x2 = x*x;
+
+        double p = 2.7553817452272217E-6;
+        p = p * x2 + -1.9841269659586505E-4;
+        p = p * x2 + 0.008333333333329196;
+        p = p * x2 + -0.16666666666666666;
+        //p *= x2;
+        //p *= x;
+        p = p * x2 * x;
+
+        return p;
+    }
+
+    /**
+     *  Computes cos(x) - 1, where |x| < 1/16.
+     *  Use a Remez polynomial approximation.
+     *  @param x a number smaller than 1/16
+     *  @return cos(x) - 1
+     */
+    private static double polyCosine(double x) {
+        double x2 = x*x;
+
+        double p = 2.479773539153719E-5;
+        p = p * x2 + -0.0013888888689039883;
+        p = p * x2 + 0.041666666666621166;
+        p = p * x2 + -0.49999999999999994;
+        p *= x2;
+
+        return p;
+    }
+
+    /**
+     *  Compute sine over the first quadrant (0 < x < pi/2).
+     *  Use combination of table lookup and rational polynomial expansion.
+     *  @param xa number from which sine is requested
+     *  @param xb extra bits for x (may be 0.0)
+     *  @return sin(xa + xb)
+     */
+    private static double sinQ(double xa, double xb) {
+        int idx = (int) ((xa * 8.0) + 0.5);
+        final double epsilon = xa - EIGHTHS[idx]; //idx*0.125;
+
+        // Table lookups
+        final double sintA = SINE_TABLE_A[idx];
+        final double sintB = SINE_TABLE_B[idx];
+        final double costA = COSINE_TABLE_A[idx];
+        final double costB = COSINE_TABLE_B[idx];
+
+        // Polynomial eval of sin(epsilon), cos(epsilon)
+        double sinEpsA = epsilon;
+        double sinEpsB = polySine(epsilon);
+        final double cosEpsA = 1.0;
+        final double cosEpsB = polyCosine(epsilon);
+
+        // Split epsilon   xa + xb = x
+        final double temp = sinEpsA * HEX_40000000;
+        double temp2 = (sinEpsA + temp) - temp;
+        sinEpsB +=  sinEpsA - temp2;
+        sinEpsA = temp2;
+
+        /* Compute sin(x) by angle addition formula */
+        double result;
+
+        /* Compute the following sum:
+         *
+         * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
+         *          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
+         *
+         * Ranges of elements
+         *
+         * xxxtA   0            PI/2
+         * xxxtB   -1.5e-9      1.5e-9
+         * sinEpsA -0.0625      0.0625
+         * sinEpsB -6e-11       6e-11
+         * cosEpsA  1.0
+         * cosEpsB  0           -0.0625
+         *
+         */
+
+        //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
+        //          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
+
+        //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB;
+        //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB;
+        double a = 0;
+        double b = 0;
+
+        double t = sintA;
+        double c = a + t;
+        double d = -(c - a - t);
+        a = c;
+        b = b + d;
+
+        t = costA * sinEpsA;
+        c = a + t;
+        d = -(c - a - t);
+        a = c;
+        b = b + d;
+
+        b = b + sintA * cosEpsB + costA * sinEpsB;
+        /*
+    t = sintA*cosEpsB;
+    c = a + t;
+    d = -(c - a - t);
+    a = c;
+    b = b + d;
+
+    t = costA*sinEpsB;
+    c = a + t;
+    d = -(c - a - t);
+    a = c;
+    b = b + d;
+         */
+
+        b = b + sintB + costB * sinEpsA + sintB * cosEpsB + costB * sinEpsB;
+        /*
+    t = sintB;
+    c = a + t;
+    d = -(c - a - t);
+    a = c;
+    b = b + d;
+
+    t = costB*sinEpsA;
+    c = a + t;
+    d = -(c - a - t);
+    a = c;
+    b = b + d;
+
+    t = sintB*cosEpsB;
+    c = a + t;
+    d = -(c - a - t);
+    a = c;
+    b = b + d;
+
+    t = costB*sinEpsB;
+    c = a + t;
+    d = -(c - a - t);
+    a = c;
+    b = b + d;
+         */
+
+        if (xb != 0.0) {
+            t = ((costA + costB) * (cosEpsA + cosEpsB) -
+                 (sintA + sintB) * (sinEpsA + sinEpsB)) * xb;  // approximate cosine*xb
+            c = a + t;
+            d = -(c - a - t);
+            a = c;
+            b = b + d;
+        }
+
+        result = a + b;
+
+        return result;
+    }
+
+    /**
+     * Compute cosine in the first quadrant by subtracting input from PI/2 and
+     * then calling sinQ.  This is more accurate as the input approaches PI/2.
+     *  @param xa number from which cosine is requested
+     *  @param xb extra bits for x (may be 0.0)
+     *  @return cos(xa + xb)
+     */
+    private static double cosQ(double xa, double xb) {
+        final double pi2a = 1.5707963267948966;
+        final double pi2b = 6.123233995736766E-17;
+
+        final double a = pi2a - xa;
+        double b = -(a - pi2a + xa);
+        b += pi2b - xb;
+
+        return sinQ(a, b);
+    }
+
+    /**
+     *  Compute tangent (or cotangent) over the first quadrant.   0 < x < pi/2
+     *  Use combination of table lookup and rational polynomial expansion.
+     *  @param xa number from which sine is requested
+     *  @param xb extra bits for x (may be 0.0)
+     *  @param cotanFlag if true, compute the cotangent instead of the tangent
+     *  @return tan(xa+xb) (or cotangent, depending on cotanFlag)
+     */
+    private static double tanQ(double xa, double xb, boolean cotanFlag) {
+
+        int idx = (int) ((xa * 8.0) + 0.5);
+        final double epsilon = xa - EIGHTHS[idx]; //idx*0.125;
+
+        // Table lookups
+        final double sintA = SINE_TABLE_A[idx];
+        final double sintB = SINE_TABLE_B[idx];
+        final double costA = COSINE_TABLE_A[idx];
+        final double costB = COSINE_TABLE_B[idx];
+
+        // Polynomial eval of sin(epsilon), cos(epsilon)
+        double sinEpsA = epsilon;
+        double sinEpsB = polySine(epsilon);
+        final double cosEpsA = 1.0;
+        final double cosEpsB = polyCosine(epsilon);
+
+        // Split epsilon   xa + xb = x
+        double temp = sinEpsA * HEX_40000000;
+        double temp2 = (sinEpsA + temp) - temp;
+        sinEpsB +=  sinEpsA - temp2;
+        sinEpsA = temp2;
+
+        /* Compute sin(x) by angle addition formula */
+
+        /* Compute the following sum:
+         *
+         * result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
+         *          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
+         *
+         * Ranges of elements
+         *
+         * xxxtA   0            PI/2
+         * xxxtB   -1.5e-9      1.5e-9
+         * sinEpsA -0.0625      0.0625
+         * sinEpsB -6e-11       6e-11
+         * cosEpsA  1.0
+         * cosEpsB  0           -0.0625
+         *
+         */
+
+        //result = sintA + costA*sinEpsA + sintA*cosEpsB + costA*sinEpsB +
+        //          sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
+
+        //result = sintA + sintA*cosEpsB + sintB + sintB * cosEpsB;
+        //result += costA*sinEpsA + costA*sinEpsB + costB*sinEpsA + costB * sinEpsB;
+        double a = 0;
+        double b = 0;
+
+        // Compute sine
+        double t = sintA;
+        double c = a + t;
+        double d = -(c - a - t);
+        a = c;
+        b = b + d;
+
+        t = costA*sinEpsA;
+        c = a + t;
+        d = -(c - a - t);
+        a = c;
+        b = b + d;
+
+        b = b + sintA*cosEpsB + costA*sinEpsB;
+        b = b + sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
+
+        double sina = a + b;
+        double sinb = -(sina - a - b);
+
+        // Compute cosine
+
+        a = b = c = d = 0.0;
+
+        t = costA*cosEpsA;
+        c = a + t;
+        d = -(c - a - t);
+        a = c;
+        b = b + d;
+
+        t = -sintA*sinEpsA;
+        c = a + t;
+        d = -(c - a - t);
+        a = c;
+        b = b + d;
+
+        b = b + costB*cosEpsA + costA*cosEpsB + costB*cosEpsB;
+        b = b - (sintB*sinEpsA + sintA*sinEpsB + sintB*sinEpsB);
+
+        double cosa = a + b;
+        double cosb = -(cosa - a - b);
+
+        if (cotanFlag) {
+            double tmp;
+            tmp = cosa; cosa = sina; sina = tmp;
+            tmp = cosb; cosb = sinb; sinb = tmp;
+        }
+
+
+        /* estimate and correct, compute 1.0/(cosa+cosb) */
+        /*
+    double est = (sina+sinb)/(cosa+cosb);
+    double err = (sina - cosa*est) + (sinb - cosb*est);
+    est += err/(cosa+cosb);
+    err = (sina - cosa*est) + (sinb - cosb*est);
+         */
+
+        // f(x) = 1/x,   f'(x) = -1/x^2
+
+        double est = sina/cosa;
+
+        /* Split the estimate to get more accurate read on division rounding */
+        temp = est * HEX_40000000;
+        double esta = (est + temp) - temp;
+        double estb =  est - esta;
+
+        temp = cosa * HEX_40000000;
+        double cosaa = (cosa + temp) - temp;
+        double cosab =  cosa - cosaa;
+
+        //double err = (sina - est*cosa)/cosa;  // Correction for division rounding
+        double err = (sina - esta*cosaa - esta*cosab - estb*cosaa - estb*cosab)/cosa;  // Correction for division rounding
+        err += sinb/cosa;                     // Change in est due to sinb
+        err += -sina * cosb / cosa / cosa;    // Change in est due to cosb
+
+        if (xb != 0.0) {
+            // tan' = 1 + tan^2      cot' = -(1 + cot^2)
+            // Approximate impact of xb
+            double xbadj = xb + est*est*xb;
+            if (cotanFlag) {
+                xbadj = -xbadj;
+            }
+
+            err += xbadj;
+        }
+
+        return est+err;
+    }
+
+    /** Reduce the input argument using the Payne and Hanek method.
+     *  This is good for all inputs 0.0 < x < inf
+     *  Output is remainder after dividing by PI/2
+     *  The result array should contain 3 numbers.
+     *  result[0] is the integer portion, so mod 4 this gives the quadrant.
+     *  result[1] is the upper bits of the remainder
+     *  result[2] is the lower bits of the remainder
+     *
+     * @param x number to reduce
+     * @param result placeholder where to put the result
+     */
+    private static void reducePayneHanek(double x, double result[])
+    {
+        /* Convert input double to bits */
+        long inbits = Double.doubleToLongBits(x);
+        int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
+
+        /* Convert to fixed point representation */
+        inbits &= 0x000fffffffffffffL;
+        inbits |= 0x0010000000000000L;
+
+        /* Normalize input to be between 0.5 and 1.0 */
+        exponent++;
+        inbits <<= 11;
+
+        /* Based on the exponent, get a shifted copy of recip2pi */
+        long shpi0;
+        long shpiA;
+        long shpiB;
+        int idx = exponent >> 6;
+        int shift = exponent - (idx << 6);
+
+        if (shift != 0) {
+            shpi0 = (idx == 0) ? 0 : (RECIP_2PI[idx-1] << shift);
+            shpi0 |= RECIP_2PI[idx] >>> (64-shift);
+            shpiA = (RECIP_2PI[idx] << shift) | (RECIP_2PI[idx+1] >>> (64-shift));
+            shpiB = (RECIP_2PI[idx+1] << shift) | (RECIP_2PI[idx+2] >>> (64-shift));
+        } else {
+            shpi0 = (idx == 0) ? 0 : RECIP_2PI[idx-1];
+            shpiA = RECIP_2PI[idx];
+            shpiB = RECIP_2PI[idx+1];
+        }
+
+        /* Multiply input by shpiA */
+        long a = inbits >>> 32;
+        long b = inbits & 0xffffffffL;
+
+        long c = shpiA >>> 32;
+        long d = shpiA & 0xffffffffL;
+
+        long ac = a * c;
+        long bd = b * d;
+        long bc = b * c;
+        long ad = a * d;
+
+        long prodB = bd + (ad << 32);
+        long prodA = ac + (ad >>> 32);
+
+        boolean bita = (bd & 0x8000000000000000L) != 0;
+        boolean bitb = (ad & 0x80000000L ) != 0;
+        boolean bitsum = (prodB & 0x8000000000000000L) != 0;
+
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prodA++;
+        }
+
+        bita = (prodB & 0x8000000000000000L) != 0;
+        bitb = (bc & 0x80000000L ) != 0;
+
+        prodB = prodB + (bc << 32);
+        prodA = prodA + (bc >>> 32);
+
+        bitsum = (prodB & 0x8000000000000000L) != 0;
+
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prodA++;
+        }
+
+        /* Multiply input by shpiB */
+        c = shpiB >>> 32;
+        d = shpiB & 0xffffffffL;
+        ac = a * c;
+        bc = b * c;
+        ad = a * d;
+
+        /* Collect terms */
+        ac = ac + ((bc + ad) >>> 32);
+
+        bita = (prodB & 0x8000000000000000L) != 0;
+        bitb = (ac & 0x8000000000000000L ) != 0;
+        prodB += ac;
+        bitsum = (prodB & 0x8000000000000000L) != 0;
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prodA++;
+        }
+
+        /* Multiply by shpi0 */
+        c = shpi0 >>> 32;
+        d = shpi0 & 0xffffffffL;
+
+        bd = b * d;
+        bc = b * c;
+        ad = a * d;
+
+        prodA += bd + ((bc + ad) << 32);
+
+        /*
+         * prodA, prodB now contain the remainder as a fraction of PI.  We want this as a fraction of
+         * PI/2, so use the following steps:
+         * 1.) multiply by 4.
+         * 2.) do a fixed point muliply by PI/4.
+         * 3.) Convert to floating point.
+         * 4.) Multiply by 2
+         */
+
+        /* This identifies the quadrant */
+        int intPart = (int)(prodA >>> 62);
+
+        /* Multiply by 4 */
+        prodA <<= 2;
+        prodA |= prodB >>> 62;
+        prodB <<= 2;
+
+        /* Multiply by PI/4 */
+        a = prodA >>> 32;
+        b = prodA & 0xffffffffL;
+
+        c = PI_O_4_BITS[0] >>> 32;
+        d = PI_O_4_BITS[0] & 0xffffffffL;
+
+        ac = a * c;
+        bd = b * d;
+        bc = b * c;
+        ad = a * d;
+
+        long prod2B = bd + (ad << 32);
+        long prod2A = ac + (ad >>> 32);
+
+        bita = (bd & 0x8000000000000000L) != 0;
+        bitb = (ad & 0x80000000L ) != 0;
+        bitsum = (prod2B & 0x8000000000000000L) != 0;
+
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prod2A++;
+        }
+
+        bita = (prod2B & 0x8000000000000000L) != 0;
+        bitb = (bc & 0x80000000L ) != 0;
+
+        prod2B = prod2B + (bc << 32);
+        prod2A = prod2A + (bc >>> 32);
+
+        bitsum = (prod2B & 0x8000000000000000L) != 0;
+
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prod2A++;
+        }
+
+        /* Multiply input by pio4bits[1] */
+        c = PI_O_4_BITS[1] >>> 32;
+        d = PI_O_4_BITS[1] & 0xffffffffL;
+        ac = a * c;
+        bc = b * c;
+        ad = a * d;
+
+        /* Collect terms */
+        ac = ac + ((bc + ad) >>> 32);
+
+        bita = (prod2B & 0x8000000000000000L) != 0;
+        bitb = (ac & 0x8000000000000000L ) != 0;
+        prod2B += ac;
+        bitsum = (prod2B & 0x8000000000000000L) != 0;
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prod2A++;
+        }
+
+        /* Multiply inputB by pio4bits[0] */
+        a = prodB >>> 32;
+        b = prodB & 0xffffffffL;
+        c = PI_O_4_BITS[0] >>> 32;
+        d = PI_O_4_BITS[0] & 0xffffffffL;
+        ac = a * c;
+        bc = b * c;
+        ad = a * d;
+
+        /* Collect terms */
+        ac = ac + ((bc + ad) >>> 32);
+
+        bita = (prod2B & 0x8000000000000000L) != 0;
+        bitb = (ac & 0x8000000000000000L ) != 0;
+        prod2B += ac;
+        bitsum = (prod2B & 0x8000000000000000L) != 0;
+        /* Carry */
+        if ( (bita && bitb) ||
+                ((bita || bitb) && !bitsum) ) {
+            prod2A++;
+        }
+
+        /* Convert to double */
+        double tmpA = (prod2A >>> 12) / TWO_POWER_52;  // High order 52 bits
+        double tmpB = (((prod2A & 0xfffL) << 40) + (prod2B >>> 24)) / TWO_POWER_52 / TWO_POWER_52; // Low bits
+
+        double sumA = tmpA + tmpB;
+        double sumB = -(sumA - tmpA - tmpB);
+
+        /* Multiply by PI/2 and return */
+        result[0] = intPart;
+        result[1] = sumA * 2.0;
+        result[2] = sumB * 2.0;
+    }
+
+    /**
+     *  Sine function.
+     *  @param x a number
+     *  @return sin(x)
+     */
+    public static double sin(double x) {
+        boolean negative = false;
+        int quadrant = 0;
+        double xa;
+        double xb = 0.0;
+
+        /* Take absolute value of the input */
+        xa = x;
+        if (x < 0) {
+            negative = true;
+            xa = -xa;
+        }
+
+        /* Check for zero and negative zero */
+        if (xa == 0.0) {
+            long bits = Double.doubleToLongBits(x);
+            if (bits < 0) {
+                return -0.0;
+            }
+            return 0.0;
+        }
+
+        if (xa != xa || xa == Double.POSITIVE_INFINITY) {
+            return Double.NaN;
+        }
+
+        /* Perform any argument reduction */
+        if (xa > 3294198.0) {
+            // PI * (2**20)
+            // Argument too big for CodyWaite reduction.  Must use
+            // PayneHanek.
+            double reduceResults[] = new double[3];
+            reducePayneHanek(xa, reduceResults);
+            quadrant = ((int) reduceResults[0]) & 3;
+            xa = reduceResults[1];
+            xb = reduceResults[2];
+        } else if (xa > 1.5707963267948966) {
+            /* Inline the Cody/Waite reduction for performance */
+
+            // Estimate k
+            //k = (int)(xa / 1.5707963267948966);
+            int k = (int)(xa * 0.6366197723675814);
+
+            // Compute remainder
+            double remA;
+            double remB;
+            while (true) {
+                double a = -k * 1.570796251296997;
+                remA = xa + a;
+                remB = -(remA - xa - a);
+
+                a = -k * 7.549789948768648E-8;
+                double b = remA;
+                remA = a + b;
+                remB += -(remA - b - a);
+
+                a = -k * 6.123233995736766E-17;
+                b = remA;
+                remA = a + b;
+                remB += -(remA - b - a);
+
+                if (remA > 0.0)
+                    break;
+
+                // Remainder is negative, so decrement k and try again.
+                // This should only happen if the input is very close
+                // to an even multiple of pi/2
+                k--;
+            }
+            quadrant = k & 3;
+            xa = remA;
+            xb = remB;
+        }
+
+        if (negative) {
+            quadrant ^= 2;  // Flip bit 1
+        }
+
+        switch (quadrant) {
+            case 0:
+                return sinQ(xa, xb);
+            case 1:
+                return cosQ(xa, xb);
+            case 2:
+                return -sinQ(xa, xb);
+            case 3:
+                return -cosQ(xa, xb);
+            default:
+                return Double.NaN;
+        }
+    }
+
+    /**
+     *  Cosine function
+     *  @param x a number
+     *  @return cos(x)
+     */
+    public static double cos(double x) {
+        int quadrant = 0;
+
+        /* Take absolute value of the input */
+        double xa = x;
+        if (x < 0) {
+            xa = -xa;
+        }
+
+        if (xa != xa || xa == Double.POSITIVE_INFINITY) {
+            return Double.NaN;
+        }
+
+        /* Perform any argument reduction */
+        double xb = 0;
+        if (xa > 3294198.0) {
+            // PI * (2**20)
+            // Argument too big for CodyWaite reduction.  Must use
+            // PayneHanek.
+            double reduceResults[] = new double[3];
+            reducePayneHanek(xa, reduceResults);
+            quadrant = ((int) reduceResults[0]) & 3;
+            xa = reduceResults[1];
+            xb = reduceResults[2];
+        } else if (xa > 1.5707963267948966) {
+            /* Inline the Cody/Waite reduction for performance */
+
+            // Estimate k
+            //k = (int)(xa / 1.5707963267948966);
+            int k = (int)(xa * 0.6366197723675814);
+
+            // Compute remainder
+            double remA;
+            double remB;
+            while (true) {
+                double a = -k * 1.570796251296997;
+                remA = xa + a;
+                remB = -(remA - xa - a);
+
+                a = -k * 7.549789948768648E-8;
+                double b = remA;
+                remA = a + b;
+                remB += -(remA - b - a);
+
+                a = -k * 6.123233995736766E-17;
+                b = remA;
+                remA = a + b;
+                remB += -(remA - b - a);
+
+                if (remA > 0.0)
+                    break;
+
+                // Remainder is negative, so decrement k and try again.
+                // This should only happen if the input is very close
+                // to an even multiple of pi/2
+                k--;
+            }
+            quadrant = k & 3;
+            xa = remA;
+            xb = remB;
+        }
+
+        //if (negative)
+        //  quadrant = (quadrant + 2) % 4;
+
+        switch (quadrant) {
+            case 0:
+                return cosQ(xa, xb);
+            case 1:
+                return -sinQ(xa, xb);
+            case 2:
+                return -cosQ(xa, xb);
+            case 3:
+                return sinQ(xa, xb);
+            default:
+                return Double.NaN;
+        }
+    }
+
+    /**
+     *   Tangent function
+     *  @param x a number
+     *  @return tan(x)
+     */
+    public static double tan(double x) {
+        boolean negative = false;
+        int quadrant = 0;
+
+        /* Take absolute value of the input */
+        double xa = x;
+        if (x < 0) {
+            negative = true;
+            xa = -xa;
+        }
+
+        /* Check for zero and negative zero */
+        if (xa == 0.0) {
+            long bits = Double.doubleToLongBits(x);
+            if (bits < 0) {
+                return -0.0;
+            }
+            return 0.0;
+        }
+
+        if (xa != xa || xa == Double.POSITIVE_INFINITY) {
+            return Double.NaN;
+        }
+
+        /* Perform any argument reduction */
+        double xb = 0;
+        if (xa > 3294198.0) {
+            // PI * (2**20)
+            // Argument too big for CodyWaite reduction.  Must use
+            // PayneHanek.
+            double reduceResults[] = new double[3];
+            reducePayneHanek(xa, reduceResults);
+            quadrant = ((int) reduceResults[0]) & 3;
+            xa = reduceResults[1];
+            xb = reduceResults[2];
+        } else if (xa > 1.5707963267948966) {
+            /* Inline the Cody/Waite reduction for performance */
+
+            // Estimate k
+            //k = (int)(xa / 1.5707963267948966);
+            int k = (int)(xa * 0.6366197723675814);
+
+            // Compute remainder
+            double remA;
+            double remB;
+            while (true) {
+                double a = -k * 1.570796251296997;
+                remA = xa + a;
+                remB = -(remA - xa - a);
+
+                a = -k * 7.549789948768648E-8;
+                double b = remA;
+                remA = a + b;
+                remB += -(remA - b - a);
+
+                a = -k * 6.123233995736766E-17;
+                b = remA;
+                remA = a + b;
+                remB += -(remA - b - a);
+
+                if (remA > 0.0)
+                    break;
+
+                // Remainder is negative, so decrement k and try again.
+                // This should only happen if the input is very close
+                // to an even multiple of pi/2
+                k--;
+            }
+            quadrant = k & 3;
+            xa = remA;
+            xb = remB;
+        }
+
+        if (xa > 1.5) {
+            // Accurracy suffers between 1.5 and PI/2
+            final double pi2a = 1.5707963267948966;
+            final double pi2b = 6.123233995736766E-17;
+
+            final double a = pi2a - xa;
+            double b = -(a - pi2a + xa);
+            b += pi2b - xb;
+
+            xa = a + b;
+            xb = -(xa - a - b);
+            quadrant ^= 1;
+            negative ^= true;
+        }
+
+        double result;
+        if ((quadrant & 1) == 0) {
+            result = tanQ(xa, xb, false);
+        } else {
+            result = -tanQ(xa, xb, true);
+        }
+
+        if (negative) {
+            result = -result;
+        }
+
+        return result;
+    }
+
+    /**
+     * Arctangent function
+     *  @param x a number
+     *  @return atan(x)
+     */
+    public static double atan(double x) {
+        return atan(x, 0.0, false);
+    }
+
+    /** Internal helper function to compute arctangent.
+     * @param xa number from which arctangent is requested
+     * @param xb extra bits for x (may be 0.0)
+     * @param leftPlane if true, result angle must be put in the left half plane
+     * @return atan(xa + xb) (or angle shifted by {@code PI} if leftPlane is true)
+     */
+    private static double atan(double xa, double xb, boolean leftPlane) {
+        boolean negate = false;
+        int idx;
+
+        if (xa == 0.0) { // Matches +/- 0.0; return correct sign
+            return leftPlane ? copySign(Math.PI, xa) : xa;
+        }
+
+        if (xa < 0) {
+            // negative
+            xa = -xa;
+            xb = -xb;
+            negate = true;
+        }
+
+        if (xa > 1.633123935319537E16) { // Very large input
+            return (negate ^ leftPlane) ? (-Math.PI/2.0) : (Math.PI/2.0);
+        }
+
+        /* Estimate the closest tabulated arctan value, compute eps = xa-tangentTable */
+        if (xa < 1.0) {
+            idx = (int) (((-1.7168146928204136 * xa * xa + 8.0) * xa) + 0.5);
+        } else {
+            double temp = 1.0/xa;
+            idx = (int) (-((-1.7168146928204136 * temp * temp + 8.0) * temp) + 13.07);
+        }
+        double epsA = xa - TANGENT_TABLE_A[idx];
+        double epsB = -(epsA - xa + TANGENT_TABLE_A[idx]);
+        epsB += xb - TANGENT_TABLE_B[idx];
+
+        double temp = epsA + epsB;
+        epsB = -(temp - epsA - epsB);
+        epsA = temp;
+
+        /* Compute eps = eps / (1.0 + xa*tangent) */
+        temp = xa * HEX_40000000;
+        double ya = xa + temp - temp;
+        double yb = xb + xa - ya;
+        xa = ya;
+        xb += yb;
+
+        //if (idx > 8 || idx == 0)
+        if (idx == 0) {
+            /* If the slope of the arctan is gentle enough (< 0.45), this approximation will suffice */
+            //double denom = 1.0 / (1.0 + xa*tangentTableA[idx] + xb*tangentTableA[idx] + xa*tangentTableB[idx] + xb*tangentTableB[idx]);
+            double denom = 1.0 / (1.0 + (xa + xb) * (TANGENT_TABLE_A[idx] + TANGENT_TABLE_B[idx]));
+            //double denom = 1.0 / (1.0 + xa*tangentTableA[idx]);
+            ya = epsA * denom;
+            yb = epsB * denom;
+        } else {
+            double temp2 = xa * TANGENT_TABLE_A[idx];
+            double za = 1.0 + temp2;
+            double zb = -(za - 1.0 - temp2);
+            temp2 = xb * TANGENT_TABLE_A[idx] + xa * TANGENT_TABLE_B[idx];
+            temp = za + temp2;
+            zb += -(temp - za - temp2);
+            za = temp;
+
+            zb += xb * TANGENT_TABLE_B[idx];
+            ya = epsA / za;
+
+            temp = ya * HEX_40000000;
+            final double yaa = (ya + temp) - temp;
+            final double yab = ya - yaa;
+
+            temp = za * HEX_40000000;
+            final double zaa = (za + temp) - temp;
+            final double zab = za - zaa;
+
+            /* Correct for rounding in division */
+            yb = (epsA - yaa * zaa - yaa * zab - yab * zaa - yab * zab) / za;
+
+            yb += -epsA * zb / za / za;
+            yb += epsB / za;
+        }
+
+
+        epsA = ya;
+        epsB = yb;
+
+        /* Evaluate polynomial */
+        double epsA2 = epsA*epsA;
+
+        /*
+    yb = -0.09001346640161823;
+    yb = yb * epsA2 + 0.11110718400605211;
+    yb = yb * epsA2 + -0.1428571349122913;
+    yb = yb * epsA2 + 0.19999999999273194;
+    yb = yb * epsA2 + -0.33333333333333093;
+    yb = yb * epsA2 * epsA;
+         */
+
+        yb = 0.07490822288864472;
+        yb = yb * epsA2 + -0.09088450866185192;
+        yb = yb * epsA2 + 0.11111095942313305;
+        yb = yb * epsA2 + -0.1428571423679182;
+        yb = yb * epsA2 + 0.19999999999923582;
+        yb = yb * epsA2 + -0.33333333333333287;
+        yb = yb * epsA2 * epsA;
+
+
+        ya = epsA;
+
+        temp = ya + yb;
+        yb = -(temp - ya - yb);
+        ya = temp;
+
+        /* Add in effect of epsB.   atan'(x) = 1/(1+x^2) */
+        yb += epsB / (1.0 + epsA * epsA);
+
+        double result;
+        double resultb;
+
+        //result = yb + eighths[idx] + ya;
+        double za = EIGHTHS[idx] + ya;
+        double zb = -(za - EIGHTHS[idx] - ya);
+        temp = za + yb;
+        zb += -(temp - za - yb);
+        za = temp;
+
+        result = za + zb;
+        resultb = -(result - za - zb);
+
+        if (leftPlane) {
+            // Result is in the left plane
+            final double pia = 1.5707963267948966*2.0;
+            final double pib = 6.123233995736766E-17*2.0;
+
+            za = pia - result;
+            zb = -(za - pia + result);
+            zb += pib - resultb;
+
+            result = za + zb;
+            resultb = -(result - za - zb);
+        }
+
+
+        if (negate ^ leftPlane) {
+            result = -result;
+        }
+
+        return result;
+    }
+
+    /**
+     * Two arguments arctangent function
+     * @param y ordinate
+     * @param x abscissa
+     * @return phase angle of point (x,y) between {@code -PI} and {@code PI}
+     */
+    public static double atan2(double y, double x) {
+        if (x !=x || y != y) {
+            return Double.NaN;
+        }
+
+        if (y == 0.0) {
+            double result = x*y;
+            double invx = 1.0/x;
+            double invy = 1.0/y;
+
+            if (invx == 0.0) { // X is infinite
+                if (x > 0) {
+                    return y; // return +/- 0.0
+                } else {
+                    return copySign(Math.PI, y);
+                }
+            }
+
+            if (x < 0.0 || invx < 0.0) {
+                if (y < 0.0 || invy < 0.0) {
+                    return -Math.PI;
+                } else {
+                    return Math.PI;
+                }
+            } else {
+                return result;
+            }
+        }
+
+        // y cannot now be zero
+
+        if (y == Double.POSITIVE_INFINITY) {
+            if (x == Double.POSITIVE_INFINITY) {
+                return Math.PI/4.0;
+            }
+
+            if (x == Double.NEGATIVE_INFINITY) {
+                return Math.PI*3.0/4.0;
+            }
+
+            return Math.PI/2.0;
+        }
+
+        if (y == Double.NEGATIVE_INFINITY) {
+            if (x == Double.POSITIVE_INFINITY) {
+                return -Math.PI/4.0;
+            }
+
+            if (x == Double.NEGATIVE_INFINITY) {
+                return -Math.PI*3.0/4.0;
+            }
+
+            return -Math.PI/2.0;
+        }
+
+        if (x == Double.POSITIVE_INFINITY) {
+            if (y > 0.0 || 1/y > 0.0) {
+                return 0.0;
+            }
+
+            if (y < 0.0 || 1/y < 0.0) {
+                return -0.0;
+            }
+        }
+
+        if (x == Double.NEGATIVE_INFINITY)
+        {
+            if (y > 0.0 || 1/y > 0.0) {
+                return Math.PI;
+            }
+
+            if (y < 0.0 || 1/y < 0.0) {
+                return -Math.PI;
+            }
+        }
+
+        // Neither y nor x can be infinite or NAN here
+
+        if (x == 0) {
+            if (y > 0.0 || 1/y > 0.0) {
+                return Math.PI/2.0;
+            }
+
+            if (y < 0.0 || 1/y < 0.0) {
+                return -Math.PI/2.0;
+            }
+        }
+
+        // Compute ratio r = y/x
+        final double r = y/x;
+        if (Double.isInfinite(r)) { // bypass calculations that can create NaN
+            return atan(r, 0, x < 0);
+        }
+
+        double ra = doubleHighPart(r);
+        double rb = r - ra;
+
+        // Split x
+        final double xa = doubleHighPart(x);
+        final double xb = x - xa;
+
+        rb += (y - ra * xa - ra * xb - rb * xa - rb * xb) / x;
+
+        double temp = ra + rb;
+        rb = -(temp - ra - rb);
+        ra = temp;
+
+        if (ra == 0) { // Fix up the sign so atan works correctly
+            ra = copySign(0.0, y);
+        }
+
+        // Call atan
+        double result = atan(ra, rb, x < 0);
+
+        return result;
+    }
+
+    /** Compute the arc sine of a number.
+     * @param x number on which evaluation is done
+     * @return arc sine of x
+     */
+    public static double asin(double x) {
+      if (x != x) {
+          return Double.NaN;
+      }
+
+      if (x > 1.0 || x < -1.0) {
+          return Double.NaN;
+      }
+
+      if (x == 1.0) {
+          return Math.PI/2.0;
+      }
+
+      if (x == -1.0) {
+          return -Math.PI/2.0;
+      }
+
+      if (x == 0.0) { // Matches +/- 0.0; return correct sign
+          return x;
+      }
+
+      /* Compute asin(x) = atan(x/sqrt(1-x*x)) */
+
+      /* Split x */
+      double temp = x * HEX_40000000;
+      final double xa = x + temp - temp;
+      final double xb = x - xa;
+
+      /* Square it */
+      double ya = xa*xa;
+      double yb = xa*xb*2.0 + xb*xb;
+
+      /* Subtract from 1 */
+      ya = -ya;
+      yb = -yb;
+
+      double za = 1.0 + ya;
+      double zb = -(za - 1.0 - ya);
+
+      temp = za + yb;
+      zb += -(temp - za - yb);
+      za = temp;
+
+      /* Square root */
+      double y;
+      y = sqrt(za);
+      temp = y * HEX_40000000;
+      ya = y + temp - temp;
+      yb = y - ya;
+
+      /* Extend precision of sqrt */
+      yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y);
+
+      /* Contribution of zb to sqrt */
+      double dx = zb / (2.0*y);
+
+      // Compute ratio r = x/y
+      double r = x/y;
+      temp = r * HEX_40000000;
+      double ra = r + temp - temp;
+      double rb = r - ra;
+
+      rb += (x - ra*ya - ra*yb - rb*ya - rb*yb) / y;  // Correct for rounding in division
+      rb += -x * dx / y / y;  // Add in effect additional bits of sqrt.
+
+      temp = ra + rb;
+      rb = -(temp - ra - rb);
+      ra = temp;
+
+      return atan(ra, rb, false);
+    }
+
+    /** Compute the arc cosine of a number.
+     * @param x number on which evaluation is done
+     * @return arc cosine of x
+     */
+    public static double acos(double x) {
+      if (x != x) {
+          return Double.NaN;
+      }
+
+      if (x > 1.0 || x < -1.0) {
+          return Double.NaN;
+      }
+
+      if (x == -1.0) {
+          return Math.PI;
+      }
+
+      if (x == 1.0) {
+          return 0.0;
+      }
+
+      if (x == 0) {
+          return Math.PI/2.0;
+      }
+
+      /* Compute acos(x) = atan(sqrt(1-x*x)/x) */
+
+      /* Split x */
+      double temp = x * HEX_40000000;
+      final double xa = x + temp - temp;
+      final double xb = x - xa;
+
+      /* Square it */
+      double ya = xa*xa;
+      double yb = xa*xb*2.0 + xb*xb;
+
+      /* Subtract from 1 */
+      ya = -ya;
+      yb = -yb;
+
+      double za = 1.0 + ya;
+      double zb = -(za - 1.0 - ya);
+
+      temp = za + yb;
+      zb += -(temp - za - yb);
+      za = temp;
+
+      /* Square root */
+      double y = sqrt(za);
+      temp = y * HEX_40000000;
+      ya = y + temp - temp;
+      yb = y - ya;
+
+      /* Extend precision of sqrt */
+      yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y);
+
+      /* Contribution of zb to sqrt */
+      yb += zb / (2.0*y);
+      y = ya+yb;
+      yb = -(y - ya - yb);
+
+      // Compute ratio r = y/x
+      double r = y/x;
+
+      // Did r overflow?
+      if (Double.isInfinite(r)) { // x is effectively zero
+          return Math.PI/2; // so return the appropriate value
+      }
+
+      double ra = doubleHighPart(r);
+      double rb = r - ra;
+
+      rb += (y - ra*xa - ra*xb - rb*xa - rb*xb) / x;  // Correct for rounding in division
+      rb += yb / x;  // Add in effect additional bits of sqrt.
+
+      temp = ra + rb;
+      rb = -(temp - ra - rb);
+      ra = temp;
+
+      return atan(ra, rb, x<0);
+    }
+
+    /** Compute the cubic root of a number.
+     * @param x number on which evaluation is done
+     * @return cubic root of x
+     */
+    public static double cbrt(double x) {
+      /* Convert input double to bits */
+      long inbits = Double.doubleToLongBits(x);
+      int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
+      boolean subnormal = false;
+
+      if (exponent == -1023) {
+          if (x == 0) {
+              return x;
+          }
+
+          /* Subnormal, so normalize */
+          subnormal = true;
+          x *= 1.8014398509481984E16;  // 2^54
+          inbits = Double.doubleToLongBits(x);
+          exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
+      }
+
+      if (exponent == 1024) {
+          // Nan or infinity.  Don't care which.
+          return x;
+      }
+
+      /* Divide the exponent by 3 */
+      int exp3 = exponent / 3;
+
+      /* p2 will be the nearest power of 2 to x with its exponent divided by 3 */
+      double p2 = Double.longBitsToDouble((inbits & 0x8000000000000000L) |
+                                          (long)(((exp3 + 1023) & 0x7ff)) << 52);
+
+      /* This will be a number between 1 and 2 */
+      final double mant = Double.longBitsToDouble((inbits & 0x000fffffffffffffL) | 0x3ff0000000000000L);
+
+      /* Estimate the cube root of mant by polynomial */
+      double est = -0.010714690733195933;
+      est = est * mant + 0.0875862700108075;
+      est = est * mant + -0.3058015757857271;
+      est = est * mant + 0.7249995199969751;
+      est = est * mant + 0.5039018405998233;
+
+      est *= CBRTTWO[exponent % 3 + 2];
+
+      // est should now be good to about 15 bits of precision.   Do 2 rounds of
+      // Newton's method to get closer,  this should get us full double precision
+      // Scale down x for the purpose of doing newtons method.  This avoids over/under flows.
+      final double xs = x / (p2*p2*p2);
+      est += (xs - est*est*est) / (3*est*est);
+      est += (xs - est*est*est) / (3*est*est);
+
+      // Do one round of Newton's method in extended precision to get the last bit right.
+      double temp = est * HEX_40000000;
+      double ya = est + temp - temp;
+      double yb = est - ya;
+
+      double za = ya * ya;
+      double zb = ya * yb * 2.0 + yb * yb;
+      temp = za * HEX_40000000;
+      double temp2 = za + temp - temp;
+      zb += za - temp2;
+      za = temp2;
+
+      zb = za * yb + ya * zb + zb * yb;
+      za = za * ya;
+
+      double na = xs - za;
+      double nb = -(na - xs + za);
+      nb -= zb;
+
+      est += (na+nb)/(3*est*est);
+
+      /* Scale by a power of two, so this is exact. */
+      est *= p2;
+
+      if (subnormal) {
+          est *= 3.814697265625E-6;  // 2^-18
+      }
+
+      return est;
+    }
+
+    /**
+     *  Convert degrees to radians, with error of less than 0.5 ULP
+     *  @param x angle in degrees
+     *  @return x converted into radians
+     */
+    public static double toRadians(double x)
+    {
+        if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign
+            return x;
+        }
+
+        // These are PI/180 split into high and low order bits
+        final double facta = 0.01745329052209854;
+        final double factb = 1.997844754509471E-9;
+
+        double xa = doubleHighPart(x);
+        double xb = x - xa;
+
+        double result = xb * factb + xb * facta + xa * factb + xa * facta;
+        if (result == 0) {
+            result = result * x; // ensure correct sign if calculation underflows
+        }
+        return result;
+    }
+
+    /**
+     *  Convert radians to degrees, with error of less than 0.5 ULP
+     *  @param x angle in radians
+     *  @return x converted into degrees
+     */
+    public static double toDegrees(double x)
+    {
+        if (Double.isInfinite(x) || x == 0.0) { // Matches +/- 0.0; return correct sign
+            return x;
+        }
+
+        // These are 180/PI split into high and low order bits
+        final double facta = 57.2957763671875;
+        final double factb = 3.145894820876798E-6;
+
+        double xa = doubleHighPart(x);
+        double xb = x - xa;
+
+        return xb * factb + xb * facta + xa * factb + xa * facta;
+    }
+
+    /**
+     * Absolute value.
+     * @param x number from which absolute value is requested
+     * @return abs(x)
+     */
+    public static int abs(final int x) {
+        return (x < 0) ? -x : x;
+    }
+
+    /**
+     * Absolute value.
+     * @param x number from which absolute value is requested
+     * @return abs(x)
+     */
+    public static long abs(final long x) {
+        return (x < 0l) ? -x : x;
+    }
+
+    /**
+     * Absolute value.
+     * @param x number from which absolute value is requested
+     * @return abs(x)
+     */
+    public static float abs(final float x) {
+        return (x < 0.0f) ? -x : (x == 0.0f) ? 0.0f : x; // -0.0 => +0.0
+    }
+
+    /**
+     * Absolute value.
+     * @param x number from which absolute value is requested
+     * @return abs(x)
+     */
+    public static double abs(double x) {
+        return (x < 0.0) ? -x : (x == 0.0) ? 0.0 : x; // -0.0 => +0.0
+    }
+
+    /**
+     * Compute least significant bit (Unit in Last Position) for a number.
+     * @param x number from which ulp is requested
+     * @return ulp(x)
+     */
+    public static double ulp(double x) {
+        if (Double.isInfinite(x)) {
+            return Double.POSITIVE_INFINITY;
+        }
+        return abs(x - Double.longBitsToDouble(Double.doubleToLongBits(x) ^ 1));
+    }
+
+    /**
+     * Compute least significant bit (Unit in Last Position) for a number.
+     * @param x number from which ulp is requested
+     * @return ulp(x)
+     */
+    public static float ulp(float x) {
+        if (Float.isInfinite(x)) {
+            return Float.POSITIVE_INFINITY;
+        }
+        return abs(x - Float.intBitsToFloat(Float.floatToIntBits(x) ^ 1));
+    }
+
+    /**
+     * Multiply a double number by a power of 2.
+     * @param d number to multiply
+     * @param n power of 2
+     * @return d &times; 2<sup>n</sup>
+     */
+    public static double scalb(final double d, final int n) {
+
+        // first simple and fast handling when 2^n can be represented using normal numbers
+        if ((n > -1023) && (n < 1024)) {
+            return d * Double.longBitsToDouble(((long) (n + 1023)) << 52);
+        }
+
+        // handle special cases
+        if (Double.isNaN(d) || Double.isInfinite(d) || (d == 0)) {
+            return d;
+        }
+        if (n < -2098) {
+            return (d > 0) ? 0.0 : -0.0;
+        }
+        if (n > 2097) {
+            return (d > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
+        }
+
+        // decompose d
+        final long bits = Double.doubleToLongBits(d);
+        final long sign = bits & 0x8000000000000000L;
+        int  exponent   = ((int) (bits >>> 52)) & 0x7ff;
+        long mantissa   = bits & 0x000fffffffffffffL;
+
+        // compute scaled exponent
+        int scaledExponent = exponent + n;
+
+        if (n < 0) {
+            // we are really in the case n <= -1023
+            if (scaledExponent > 0) {
+                // both the input and the result are normal numbers, we only adjust the exponent
+                return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
+            } else if (scaledExponent > -53) {
+                // the input is a normal number and the result is a subnormal number
+
+                // recover the hidden mantissa bit
+                mantissa = mantissa | (1L << 52);
+
+                // scales down complete mantissa, hence losing least significant bits
+                final long mostSignificantLostBit = mantissa & (1L << (-scaledExponent));
+                mantissa = mantissa >>> (1 - scaledExponent);
+                if (mostSignificantLostBit != 0) {
+                    // we need to add 1 bit to round up the result
+                    mantissa++;
+                }
+                return Double.longBitsToDouble(sign | mantissa);
+
+            } else {
+                // no need to compute the mantissa, the number scales down to 0
+                return (sign == 0L) ? 0.0 : -0.0;
+            }
+        } else {
+            // we are really in the case n >= 1024
+            if (exponent == 0) {
+
+                // the input number is subnormal, normalize it
+                while ((mantissa >>> 52) != 1) {
+                    mantissa = mantissa << 1;
+                    --scaledExponent;
+                }
+                ++scaledExponent;
+                mantissa = mantissa & 0x000fffffffffffffL;
+
+                if (scaledExponent < 2047) {
+                    return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
+                } else {
+                    return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
+                }
+
+            } else if (scaledExponent < 2047) {
+                return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
+            } else {
+                return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
+            }
+        }
+
+    }
+
+    /**
+     * Multiply a float number by a power of 2.
+     * @param f number to multiply
+     * @param n power of 2
+     * @return f &times; 2<sup>n</sup>
+     */
+    public static float scalb(final float f, final int n) {
+
+        // first simple and fast handling when 2^n can be represented using normal numbers
+        if ((n > -127) && (n < 128)) {
+            return f * Float.intBitsToFloat((n + 127) << 23);
+        }
+
+        // handle special cases
+        if (Float.isNaN(f) || Float.isInfinite(f) || (f == 0f)) {
+            return f;
+        }
+        if (n < -277) {
+            return (f > 0) ? 0.0f : -0.0f;
+        }
+        if (n > 276) {
+            return (f > 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
+        }
+
+        // decompose f
+        final int bits = Float.floatToIntBits(f);
+        final int sign = bits & 0x80000000;
+        int  exponent  = (bits >>> 23) & 0xff;
+        int mantissa   = bits & 0x007fffff;
+
+        // compute scaled exponent
+        int scaledExponent = exponent + n;
+
+        if (n < 0) {
+            // we are really in the case n <= -127
+            if (scaledExponent > 0) {
+                // both the input and the result are normal numbers, we only adjust the exponent
+                return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
+            } else if (scaledExponent > -24) {
+                // the input is a normal number and the result is a subnormal number
+
+                // recover the hidden mantissa bit
+                mantissa = mantissa | (1 << 23);
+
+                // scales down complete mantissa, hence losing least significant bits
+                final int mostSignificantLostBit = mantissa & (1 << (-scaledExponent));
+                mantissa = mantissa >>> (1 - scaledExponent);
+                if (mostSignificantLostBit != 0) {
+                    // we need to add 1 bit to round up the result
+                    mantissa++;
+                }
+                return Float.intBitsToFloat(sign | mantissa);
+
+            } else {
+                // no need to compute the mantissa, the number scales down to 0
+                return (sign == 0) ? 0.0f : -0.0f;
+            }
+        } else {
+            // we are really in the case n >= 128
+            if (exponent == 0) {
+
+                // the input number is subnormal, normalize it
+                while ((mantissa >>> 23) != 1) {
+                    mantissa = mantissa << 1;
+                    --scaledExponent;
+                }
+                ++scaledExponent;
+                mantissa = mantissa & 0x007fffff;
+
+                if (scaledExponent < 255) {
+                    return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
+                } else {
+                    return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
+                }
+
+            } else if (scaledExponent < 255) {
+                return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
+            } else {
+                return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
+            }
+        }
+
+    }
+
+    /**
+     * Get the next machine representable number after a number, moving
+     * in the direction of another number.
+     * <p>
+     * The ordering is as follows (increasing):
+     * <ul>
+     * <li>-INFINITY</li>
+     * <li>-MAX_VALUE</li>
+     * <li>-MIN_VALUE</li>
+     * <li>-0.0</li>
+     * <li>+0.0</li>
+     * <li>+MIN_VALUE</li>
+     * <li>+MAX_VALUE</li>
+     * <li>+INFINITY</li>
+     * <li></li>
+     * <p>
+     * If arguments compare equal, then the second argument is returned.
+     * <p>
+     * If {@code direction} is greater than {@code d},
+     * the smallest machine representable number strictly greater than
+     * {@code d} is returned; if less, then the largest representable number
+     * strictly less than {@code d} is returned.</p>
+     * <p>
+     * If {@code d} is infinite and direction does not
+     * bring it back to finite numbers, it is returned unchanged.</p>
+     *
+     * @param d base number
+     * @param direction (the only important thing is whether
+     * {@code direction} is greater or smaller than {@code d})
+     * @return the next machine representable number in the specified direction
+     */
+    public static double nextAfter(double d, double direction) {
+
+        // handling of some important special cases
+        if (Double.isNaN(d) || Double.isNaN(direction)) {
+            return Double.NaN;
+        } else if (d == direction) {
+            return direction;
+        } else if (Double.isInfinite(d)) {
+            return (d < 0) ? -Double.MAX_VALUE : Double.MAX_VALUE;
+        } else if (d == 0) {
+            return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE;
+        }
+        // special cases MAX_VALUE to infinity and  MIN_VALUE to 0
+        // are handled just as normal numbers
+
+        final long bits = Double.doubleToLongBits(d);
+        final long sign = bits & 0x8000000000000000L;
+        if ((direction < d) ^ (sign == 0L)) {
+            return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1));
+        } else {
+            return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) - 1));
+        }
+
+    }
+
+    /**
+     * Get the next machine representable number after a number, moving
+     * in the direction of another number.
+     * <p>
+     * The ordering is as follows (increasing):
+     * <ul>
+     * <li>-INFINITY</li>
+     * <li>-MAX_VALUE</li>
+     * <li>-MIN_VALUE</li>
+     * <li>-0.0</li>
+     * <li>+0.0</li>
+     * <li>+MIN_VALUE</li>
+     * <li>+MAX_VALUE</li>
+     * <li>+INFINITY</li>
+     * <li></li>
+     * <p>
+     * If arguments compare equal, then the second argument is returned.
+     * <p>
+     * If {@code direction} is greater than {@code f},
+     * the smallest machine representable number strictly greater than
+     * {@code f} is returned; if less, then the largest representable number
+     * strictly less than {@code f} is returned.</p>
+     * <p>
+     * If {@code f} is infinite and direction does not
+     * bring it back to finite numbers, it is returned unchanged.</p>
+     *
+     * @param f base number
+     * @param direction (the only important thing is whether
+     * {@code direction} is greater or smaller than {@code f})
+     * @return the next machine representable number in the specified direction
+     */
+    public static float nextAfter(final float f, final double direction) {
+
+        // handling of some important special cases
+        if (Double.isNaN(f) || Double.isNaN(direction)) {
+            return Float.NaN;
+        } else if (f == direction) {
+            return (float) direction;
+        } else if (Float.isInfinite(f)) {
+            return (f < 0f) ? -Float.MAX_VALUE : Float.MAX_VALUE;
+        } else if (f == 0f) {
+            return (direction < 0) ? -Float.MIN_VALUE : Float.MIN_VALUE;
+        }
+        // special cases MAX_VALUE to infinity and  MIN_VALUE to 0
+        // are handled just as normal numbers
+
+        final int bits = Float.floatToIntBits(f);
+        final int sign = bits & 0x80000000;
+        if ((direction < f) ^ (sign == 0)) {
+            return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) + 1));
+        } else {
+            return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) - 1));
+        }
+
+    }
+
+    /** Get the largest whole number smaller than x.
+     * @param x number from which floor is requested
+     * @return a double number f such that f is an integer f <= x < f + 1.0
+     */
+    public static double floor(double x) {
+        long y;
+
+        if (x != x) { // NaN
+            return x;
+        }
+
+        if (x >= TWO_POWER_52 || x <= -TWO_POWER_52) {
+            return x;
+        }
+
+        y = (long) x;
+        if (x < 0 && y != x) {
+            y--;
+        }
+
+        if (y == 0) {
+            return x*y;
+        }
+
+        return y;
+    }
+
+    /** Get the smallest whole number larger than x.
+     * @param x number from which ceil is requested
+     * @return a double number c such that c is an integer c - 1.0 < x <= c
+     */
+    public static double ceil(double x) {
+        double y;
+
+        if (x != x) { // NaN
+            return x;
+        }
+
+        y = floor(x);
+        if (y == x) {
+            return y;
+        }
+
+        y += 1.0;
+
+        if (y == 0) {
+            return x*y;
+        }
+
+        return y;
+    }
+
+    /** Get the whole number that is the nearest to x, or the even one if x is exactly half way between two integers.
+     * @param x number from which nearest whole number is requested
+     * @return a double number r such that r is an integer r - 0.5 <= x <= r + 0.5
+     */
+    public static double rint(double x) {
+        double y = floor(x);
+        double d = x - y;
+
+        if (d > 0.5) {
+            if (y == -1.0) {
+                return -0.0; // Preserve sign of operand
+            }
+            return y+1.0;
+        }
+        if (d < 0.5) {
+            return y;
+        }
+
+        /* half way, round to even */
+        long z = (long) y;
+        return (z & 1) == 0 ? y : y + 1.0;
+    }
+
+    /** Get the closest long to x.
+     * @param x number from which closest long is requested
+     * @return closest long to x
+     */
+    public static long round(double x) {
+        return (long) floor(x + 0.5);
+    }
+
+    /** Get the closest int to x.
+     * @param x number from which closest int is requested
+     * @return closest int to x
+     */
+    public static int round(final float x) {
+        return (int) floor(x + 0.5f);
+    }
+
+    /** Compute the minimum of two values
+     * @param a first value
+     * @param b second value
+     * @return a if a is lesser or equal to b, b otherwise
+     */
+    public static int min(final int a, final int b) {
+        return (a <= b) ? a : b;
+    }
+
+    /** Compute the minimum of two values
+     * @param a first value
+     * @param b second value
+     * @return a if a is lesser or equal to b, b otherwise
+     */
+    public static long min(final long a, final long b) {
+        return (a <= b) ? a : b;
+    }
+
+    /** Compute the minimum of two values
+     * @param a first value
+     * @param b second value
+     * @return a if a is lesser or equal to b, b otherwise
+     */
+    public static float min(final float a, final float b) {
+        if (a > b) {
+            return b;
+        }
+        if (a < b) {
+            return a;
+        }
+        /* if either arg is NaN, return NaN */
+        if (a != b) {
+            return Float.NaN;
+        }
+        /* min(+0.0,-0.0) == -0.0 */
+        /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */
+        int bits = Float.floatToRawIntBits(a);
+        if (bits == 0x80000000) {
+            return a;
+        }
+        return b;
+    }
+
+    /** Compute the minimum of two values
+     * @param a first value
+     * @param b second value
+     * @return a if a is lesser or equal to b, b otherwise
+     */
+    public static double min(final double a, final double b) {
+        if (a > b) {
+            return b;
+        }
+        if (a < b) {
+            return a;
+        }
+        /* if either arg is NaN, return NaN */
+        if (a != b) {
+            return Double.NaN;
+        }
+        /* min(+0.0,-0.0) == -0.0 */
+        /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */
+        long bits = Double.doubleToRawLongBits(a);
+        if (bits == 0x8000000000000000L) {
+            return a;
+        }
+        return b;
+    }
+
+    /** Compute the maximum of two values
+     * @param a first value
+     * @param b second value
+     * @return b if a is lesser or equal to b, a otherwise
+     */
+    public static int max(final int a, final int b) {
+        return (a <= b) ? b : a;
+    }
+
+    /** Compute the maximum of two values
+     * @param a first value
+     * @param b second value
+     * @return b if a is lesser or equal to b, a otherwise
+     */
+    public static long max(final long a, final long b) {
+        return (a <= b) ? b : a;
+    }
+
+    /** Compute the maximum of two values
+     * @param a first value
+     * @param b second value
+     * @return b if a is lesser or equal to b, a otherwise
+     */
+    public static float max(final float a, final float b) {
+        if (a > b) {
+            return a;
+        }
+        if (a < b) {
+            return b;
+        }
+        /* if either arg is NaN, return NaN */
+        if (a != b) {
+            return Float.NaN;
+        }
+        /* min(+0.0,-0.0) == -0.0 */
+        /* 0x80000000 == Float.floatToRawIntBits(-0.0d) */
+        int bits = Float.floatToRawIntBits(a);
+        if (bits == 0x80000000) {
+            return b;
+        }
+        return a;
+    }
+
+    /** Compute the maximum of two values
+     * @param a first value
+     * @param b second value
+     * @return b if a is lesser or equal to b, a otherwise
+     */
+    public static double max(final double a, final double b) {
+        if (a > b) {
+            return a;
+        }
+        if (a < b) {
+            return b;
+        }
+        /* if either arg is NaN, return NaN */
+        if (a != b) {
+            return Double.NaN;
+        }
+        /* min(+0.0,-0.0) == -0.0 */
+        /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */
+        long bits = Double.doubleToRawLongBits(a);
+        if (bits == 0x8000000000000000L) {
+            return b;
+        }
+        return a;
+    }
+
+    /**
+     * Returns the hypotenuse of a triangle with sides {@code x} and {@code y}
+     * - sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)<br/>
+     * avoiding intermediate overflow or underflow.
+     *
+     * <ul>
+     * <li> If either argument is infinite, then the result is positive infinity.</li>
+     * <li> else, if either argument is NaN then the result is NaN.</li>
+     * </ul>
+     *
+     * @param x a value
+     * @param y a value
+     * @return sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
+     */
+    public static double hypot(final double x, final double y) {
+        if (Double.isInfinite(x) || Double.isInfinite(y)) {
+            return Double.POSITIVE_INFINITY;
+        } else if (Double.isNaN(x) || Double.isNaN(y)) {
+            return Double.NaN;
+        } else {
+
+            final int expX = getExponent(x);
+            final int expY = getExponent(y);
+            if (expX > expY + 27) {
+                // y is neglectible with respect to x
+                return abs(x);
+            } else if (expY > expX + 27) {
+                // x is neglectible with respect to y
+                return abs(y);
+            } else {
+
+                // find an intermediate scale to avoid both overflow and underflow
+                final int middleExp = (expX + expY) / 2;
+
+                // scale parameters without losing precision
+                final double scaledX = scalb(x, -middleExp);
+                final double scaledY = scalb(y, -middleExp);
+
+                // compute scaled hypotenuse
+                final double scaledH = sqrt(scaledX * scaledX + scaledY * scaledY);
+
+                // remove scaling
+                return scalb(scaledH, middleExp);
+
+            }
+
+        }
+    }
+
+    /**
+     * Computes the remainder as prescribed by the IEEE 754 standard.
+     * The remainder value is mathematically equal to {@code x - y*n}
+     * where {@code n} is the mathematical integer closest to the exact mathematical value
+     * of the quotient {@code x/y}.
+     * If two mathematical integers are equally close to {@code x/y} then
+     * {@code n} is the integer that is even.
+     * <p>
+     * <ul>
+     * <li>If either operand is NaN, the result is NaN.</li>
+     * <li>If the result is not NaN, the sign of the result equals the sign of the dividend.</li>
+     * <li>If the dividend is an infinity, or the divisor is a zero, or both, the result is NaN.</li>
+     * <li>If the dividend is finite and the divisor is an infinity, the result equals the dividend.</li>
+     * <li>If the dividend is a zero and the divisor is finite, the result equals the dividend.</li>
+     * </ul>
+     * <p><b>Note:</b> this implementation currently delegates to {@link StrictMath#IEEEremainder}
+     * @param dividend the number to be divided
+     * @param divisor the number by which to divide
+     * @return the remainder, rounded
+     */
+    public static double IEEEremainder(double dividend, double divisor) {
+        return StrictMath.IEEEremainder(dividend, divisor); // TODO provide our own implementation
+    }
+
+    /**
+     * Returns the first argument with the sign of the second argument.
+     * A NaN {@code sign} argument is treated as positive.
+     *
+     * @param magnitude the value to return
+     * @param sign the sign for the returned value
+     * @return the magnitude with the same sign as the {@code sign} argument
+     */
+    public static double copySign(double magnitude, double sign){
+        long m = Double.doubleToLongBits(magnitude);
+        long s = Double.doubleToLongBits(sign);
+        if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
+            return magnitude;
+        }
+        return -magnitude; // flip sign
+    }
+
+    /**
+     * Returns the first argument with the sign of the second argument.
+     * A NaN {@code sign} argument is treated as positive.
+     *
+     * @param magnitude the value to return
+     * @param sign the sign for the returned value
+     * @return the magnitude with the same sign as the {@code sign} argument
+     */
+    public static float copySign(float magnitude, float sign){
+        int m = Float.floatToIntBits(magnitude);
+        int s = Float.floatToIntBits(sign);
+        if ((m >= 0 && s >= 0) || (m < 0 && s < 0)) { // Sign is currently OK
+            return magnitude;
+        }
+        return -magnitude; // flip sign
+    }
+
+    /**
+     * Return the exponent of a double number, removing the bias.
+     * <p>
+     * For double numbers of the form 2<sup>x</sup>, the unbiased
+     * exponent is exactly x.
+     * </p>
+     * @param d number from which exponent is requested
+     * @return exponent for d in IEEE754 representation, without bias
+     */
+    public static int getExponent(final double d) {
+        return (int) ((Double.doubleToLongBits(d) >>> 52) & 0x7ff) - 1023;
+    }
+
+    /**
+     * Return the exponent of a float number, removing the bias.
+     * <p>
+     * For float numbers of the form 2<sup>x</sup>, the unbiased
+     * exponent is exactly x.
+     * </p>
+     * @param f number from which exponent is requested
+     * @return exponent for d in IEEE754 representation, without bias
+     */
+    public static int getExponent(final float f) {
+        return ((Float.floatToIntBits(f) >>> 23) & 0xff) - 127;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/MathUtils.java b/src/main/java/org/apache/commons/math/util/MathUtils.java
new file mode 100644
index 0000000..c1999bd
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/MathUtils.java
@@ -0,0 +1,2265 @@
+/*
+ * 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.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.Localizable;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.exception.NonMonotonousSequenceException;
+
+/**
+ * Some useful additions to the built-in functions in {@link Math}.
+ * @version $Revision: 1073472 $ $Date: 2011-02-22 20:49:07 +0100 (mar. 22 févr. 2011) $
+ */
+public final class MathUtils {
+
+    /** Smallest positive number such that 1 - EPSILON is not numerically equal to 1. */
+    public static final double EPSILON = 0x1.0p-53;
+
+    /** Safe minimum, such that 1 / SAFE_MIN does not overflow.
+     * <p>In IEEE 754 arithmetic, this is also the smallest normalized
+     * number 2<sup>-1022</sup>.</p>
+     */
+    public static final double SAFE_MIN = 0x1.0p-1022;
+
+    /**
+     * 2 &pi;.
+     * @since 2.1
+     */
+    public static final double TWO_PI = 2 * FastMath.PI;
+
+    /** -1.0 cast as a byte. */
+    private static final byte  NB = (byte)-1;
+
+    /** -1.0 cast as a short. */
+    private static final short NS = (short)-1;
+
+    /** 1.0 cast as a byte. */
+    private static final byte  PB = (byte)1;
+
+    /** 1.0 cast as a short. */
+    private static final short PS = (short)1;
+
+    /** 0.0 cast as a byte. */
+    private static final byte  ZB = (byte)0;
+
+    /** 0.0 cast as a short. */
+    private static final short ZS = (short)0;
+
+    /** Gap between NaN and regular numbers. */
+    private static final int NAN_GAP = 4 * 1024 * 1024;
+
+    /** Offset to order signed double numbers lexicographically. */
+    private static final long SGN_MASK = 0x8000000000000000L;
+
+    /** Offset to order signed double numbers lexicographically. */
+    private static final int SGN_MASK_FLOAT = 0x80000000;
+
+    /** All long-representable factorials */
+    private static final long[] FACTORIALS = new long[] {
+                       1l,                  1l,                   2l,
+                       6l,                 24l,                 120l,
+                     720l,               5040l,               40320l,
+                  362880l,            3628800l,            39916800l,
+               479001600l,         6227020800l,         87178291200l,
+           1307674368000l,     20922789888000l,     355687428096000l,
+        6402373705728000l, 121645100408832000l, 2432902008176640000l };
+
+    /**
+     * Private Constructor
+     */
+    private MathUtils() {
+        super();
+    }
+
+    /**
+     * Add two integers, checking for overflow.
+     *
+     * @param x an addend
+     * @param y an addend
+     * @return the sum <code>x+y</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         int
+     * @since 1.1
+     */
+    public static int addAndCheck(int x, int y) {
+        long s = (long)x + (long)y;
+        if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y);
+        }
+        return (int)s;
+    }
+
+    /**
+     * Add two long integers, checking for overflow.
+     *
+     * @param a an addend
+     * @param b an addend
+     * @return the sum <code>a+b</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         long
+     * @since 1.2
+     */
+    public static long addAndCheck(long a, long b) {
+        return addAndCheck(a, b, LocalizedFormats.OVERFLOW_IN_ADDITION);
+    }
+
+    /**
+     * Add two long integers, checking for overflow.
+     *
+     * @param a an addend
+     * @param b an addend
+     * @param pattern the pattern to use for any thrown exception.
+     * @return the sum <code>a+b</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         long
+     * @since 1.2
+     */
+    private static long addAndCheck(long a, long b, Localizable pattern) {
+        long ret;
+        if (a > b) {
+            // use symmetry to reduce boundary cases
+            ret = addAndCheck(b, a, pattern);
+        } else {
+            // assert a <= b
+
+            if (a < 0) {
+                if (b < 0) {
+                    // check for negative overflow
+                    if (Long.MIN_VALUE - b <= a) {
+                        ret = a + b;
+                    } else {
+                        throw MathRuntimeException.createArithmeticException(pattern, a, b);
+                    }
+                } else {
+                    // opposite sign addition is always safe
+                    ret = a + b;
+                }
+            } else {
+                // assert a >= 0
+                // assert b >= 0
+
+                // check for positive overflow
+                if (a <= Long.MAX_VALUE - b) {
+                    ret = a + b;
+                } else {
+                    throw MathRuntimeException.createArithmeticException(pattern, a, b);
+                }
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Returns an exact representation of the <a
+     * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial
+     * Coefficient</a>, "<code>n choose k</code>", the number of
+     * <code>k</code>-element subsets that can be selected from an
+     * <code>n</code>-element set.
+     * <p>
+     * <Strong>Preconditions</strong>:
+     * <ul>
+     * <li> <code>0 <= k <= n </code> (otherwise
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * <li> The result is small enough to fit into a <code>long</code>. The
+     * largest value of <code>n</code> for which all coefficients are
+     * <code> < Long.MAX_VALUE</code> is 66. If the computed value exceeds
+     * <code>Long.MAX_VALUE</code> an <code>ArithMeticException</code> is
+     * thrown.</li>
+     * </ul></p>
+     *
+     * @param n the size of the set
+     * @param k the size of the subsets to be counted
+     * @return <code>n choose k</code>
+     * @throws IllegalArgumentException if preconditions are not met.
+     * @throws ArithmeticException if the result is too large to be represented
+     *         by a long integer.
+     */
+    public static long binomialCoefficient(final int n, final int k) {
+        checkBinomial(n, k);
+        if ((n == k) || (k == 0)) {
+            return 1;
+        }
+        if ((k == 1) || (k == n - 1)) {
+            return n;
+        }
+        // Use symmetry for large k
+        if (k > n / 2)
+            return binomialCoefficient(n, n - k);
+
+        // We use the formula
+        // (n choose k) = n! / (n-k)! / k!
+        // (n choose k) == ((n-k+1)*...*n) / (1*...*k)
+        // which could be written
+        // (n choose k) == (n-1 choose k-1) * n / k
+        long result = 1;
+        if (n <= 61) {
+            // For n <= 61, the naive implementation cannot overflow.
+            int i = n - k + 1;
+            for (int j = 1; j <= k; j++) {
+                result = result * i / j;
+                i++;
+            }
+        } else if (n <= 66) {
+            // For n > 61 but n <= 66, the result cannot overflow,
+            // but we must take care not to overflow intermediate values.
+            int i = n - k + 1;
+            for (int j = 1; j <= k; j++) {
+                // We know that (result * i) is divisible by j,
+                // but (result * i) may overflow, so we split j:
+                // Filter out the gcd, d, so j/d and i/d are integer.
+                // result is divisible by (j/d) because (j/d)
+                // is relative prime to (i/d) and is a divisor of
+                // result * (i/d).
+                final long d = gcd(i, j);
+                result = (result / (j / d)) * (i / d);
+                i++;
+            }
+        } else {
+            // For n > 66, a result overflow might occur, so we check
+            // the multiplication, taking care to not overflow
+            // unnecessary.
+            int i = n - k + 1;
+            for (int j = 1; j <= k; j++) {
+                final long d = gcd(i, j);
+                result = mulAndCheck(result / (j / d), i / d);
+                i++;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns a <code>double</code> representation of the <a
+     * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial
+     * Coefficient</a>, "<code>n choose k</code>", the number of
+     * <code>k</code>-element subsets that can be selected from an
+     * <code>n</code>-element set.
+     * <p>
+     * <Strong>Preconditions</strong>:
+     * <ul>
+     * <li> <code>0 <= k <= n </code> (otherwise
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * <li> The result is small enough to fit into a <code>double</code>. The
+     * largest value of <code>n</code> for which all coefficients are <
+     * Double.MAX_VALUE is 1029. If the computed value exceeds Double.MAX_VALUE,
+     * Double.POSITIVE_INFINITY is returned</li>
+     * </ul></p>
+     *
+     * @param n the size of the set
+     * @param k the size of the subsets to be counted
+     * @return <code>n choose k</code>
+     * @throws IllegalArgumentException if preconditions are not met.
+     */
+    public static double binomialCoefficientDouble(final int n, final int k) {
+        checkBinomial(n, k);
+        if ((n == k) || (k == 0)) {
+            return 1d;
+        }
+        if ((k == 1) || (k == n - 1)) {
+            return n;
+        }
+        if (k > n/2) {
+            return binomialCoefficientDouble(n, n - k);
+        }
+        if (n < 67) {
+            return binomialCoefficient(n,k);
+        }
+
+        double result = 1d;
+        for (int i = 1; i <= k; i++) {
+             result *= (double)(n - k + i) / (double)i;
+        }
+
+        return FastMath.floor(result + 0.5);
+    }
+
+    /**
+     * Returns the natural <code>log</code> of the <a
+     * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial
+     * Coefficient</a>, "<code>n choose k</code>", the number of
+     * <code>k</code>-element subsets that can be selected from an
+     * <code>n</code>-element set.
+     * <p>
+     * <Strong>Preconditions</strong>:
+     * <ul>
+     * <li> <code>0 <= k <= n </code> (otherwise
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * </ul></p>
+     *
+     * @param n the size of the set
+     * @param k the size of the subsets to be counted
+     * @return <code>n choose k</code>
+     * @throws IllegalArgumentException if preconditions are not met.
+     */
+    public static double binomialCoefficientLog(final int n, final int k) {
+        checkBinomial(n, k);
+        if ((n == k) || (k == 0)) {
+            return 0;
+        }
+        if ((k == 1) || (k == n - 1)) {
+            return FastMath.log(n);
+        }
+
+        /*
+         * For values small enough to do exact integer computation,
+         * return the log of the exact value
+         */
+        if (n < 67) {
+            return FastMath.log(binomialCoefficient(n,k));
+        }
+
+        /*
+         * Return the log of binomialCoefficientDouble for values that will not
+         * overflow binomialCoefficientDouble
+         */
+        if (n < 1030) {
+            return FastMath.log(binomialCoefficientDouble(n, k));
+        }
+
+        if (k > n / 2) {
+            return binomialCoefficientLog(n, n - k);
+        }
+
+        /*
+         * Sum logs for values that could overflow
+         */
+        double logSum = 0;
+
+        // n!/(n-k)!
+        for (int i = n - k + 1; i <= n; i++) {
+            logSum += FastMath.log(i);
+        }
+
+        // divide by k!
+        for (int i = 2; i <= k; i++) {
+            logSum -= FastMath.log(i);
+        }
+
+        return logSum;
+    }
+
+    /**
+     * Check binomial preconditions.
+     * @param n the size of the set
+     * @param k the size of the subsets to be counted
+     * @exception IllegalArgumentException if preconditions are not met.
+     */
+    private static void checkBinomial(final int n, final int k)
+        throws IllegalArgumentException {
+        if (n < k) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.BINOMIAL_INVALID_PARAMETERS_ORDER,
+                n, k);
+        }
+        if (n < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.BINOMIAL_NEGATIVE_PARAMETER,
+                  n);
+        }
+    }
+
+    /**
+     * Compares two numbers given some amount of allowed error.
+     *
+     * @param x the first number
+     * @param y the second number
+     * @param eps the amount of error to allow when checking for equality
+     * @return <ul><li>0 if  {@link #equals(double, double, double) equals(x, y, eps)}</li>
+     *       <li>&lt; 0 if !{@link #equals(double, double, double) equals(x, y, eps)} &amp;&amp; x &lt; y</li>
+     *       <li>> 0 if !{@link #equals(double, double, double) equals(x, y, eps)} &amp;&amp; x > y</li></ul>
+     */
+    public static int compareTo(double x, double y, double eps) {
+        if (equals(x, y, eps)) {
+            return 0;
+        } else if (x < y) {
+          return -1;
+        }
+        return 1;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html">
+     * hyperbolic cosine</a> of x.
+     *
+     * @param x double value for which to find the hyperbolic cosine
+     * @return hyperbolic cosine of x
+     */
+    public static double cosh(double x) {
+        return (FastMath.exp(x) + FastMath.exp(-x)) / 2.0;
+    }
+
+    /**
+     * Returns true iff they are strictly equal.
+     *
+     * @param x first value
+     * @param y second value
+     * @return {@code true} if the values are equal.
+     * @deprecated as of 2.2 his method considers that {@code NaN == NaN}. In release
+     * 3.0, the semantics will change in order to comply with IEEE754 where it
+     * is specified that {@code NaN != NaN}.
+     * New methods have been added for those cases wher the old semantics is
+     * useful (see e.g. {@link #equalsIncludingNaN(float,float)
+     * equalsIncludingNaN}.
+     */
+    @Deprecated
+    public static boolean equals(float x, float y) {
+        return (Float.isNaN(x) && Float.isNaN(y)) || x == y;
+    }
+
+    /**
+     * Returns true if both arguments are NaN or neither is NaN and they are
+     * equal as defined by {@link #equals(float,float,int) equals(x, y, 1)}.
+     *
+     * @param x first value
+     * @param y second value
+     * @return {@code true} if the values are equal or both are NaN.
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(float x, float y) {
+        return (Float.isNaN(x) && Float.isNaN(y)) || equals(x, y, 1);
+    }
+
+    /**
+     * Returns true if both arguments are equal or within the range of allowed
+     * error (inclusive).
+     *
+     * @param x first value
+     * @param y second value
+     * @param eps the amount of absolute error to allow.
+     * @return {@code true} if the values are equal or within range of each other.
+     * @since 2.2
+     */
+    public static boolean equals(float x, float y, float eps) {
+        return equals(x, y, 1) || FastMath.abs(y - x) <= eps;
+    }
+
+    /**
+     * Returns true if both arguments are NaN or are equal or within the range
+     * of allowed error (inclusive).
+     *
+     * @param x first value
+     * @param y second value
+     * @param eps the amount of absolute error to allow.
+     * @return {@code true} if the values are equal or within range of each other,
+     * or both are NaN.
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(float x, float y, float eps) {
+        return equalsIncludingNaN(x, y) || (FastMath.abs(y - x) <= eps);
+    }
+
+    /**
+     * Returns true if both arguments are equal or within the range of allowed
+     * error (inclusive).
+     * Two float numbers are considered equal if there are {@code (maxUlps - 1)}
+     * (or fewer) floating point numbers between them, i.e. two adjacent floating
+     * point numbers are considered equal.
+     * Adapted from <a
+     * href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">
+     * Bruce Dawson</a>
+     *
+     * @param x first value
+     * @param y second value
+     * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
+     * values between {@code x} and {@code y}.
+     * @return {@code true} if there are fewer than {@code maxUlps} floating
+     * point values between {@code x} and {@code y}.
+     * @since 2.2
+     */
+    public static boolean equals(float x, float y, int maxUlps) {
+        // Check that "maxUlps" is non-negative and small enough so that
+        // NaN won't compare as equal to anything (except another NaN).
+        assert maxUlps > 0 && maxUlps < NAN_GAP;
+
+        int xInt = Float.floatToIntBits(x);
+        int yInt = Float.floatToIntBits(y);
+
+        // Make lexicographically ordered as a two's-complement integer.
+        if (xInt < 0) {
+            xInt = SGN_MASK_FLOAT - xInt;
+        }
+        if (yInt < 0) {
+            yInt = SGN_MASK_FLOAT - yInt;
+        }
+
+        final boolean isEqual = FastMath.abs(xInt - yInt) <= maxUlps;
+
+        return isEqual && !Float.isNaN(x) && !Float.isNaN(y);
+    }
+
+    /**
+     * Returns true if both arguments are NaN or if they are equal as defined
+     * by {@link #equals(float,float,int) equals(x, y, maxUlps)}.
+     *
+     * @param x first value
+     * @param y second value
+     * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
+     * values between {@code x} and {@code y}.
+     * @return {@code true} if both arguments are NaN or if there are less than
+     * {@code maxUlps} floating point values between {@code x} and {@code y}.
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(float x, float y, int maxUlps) {
+        return (Float.isNaN(x) && Float.isNaN(y)) || equals(x, y, maxUlps);
+    }
+
+    /**
+     * Returns true iff both arguments are null or have same dimensions and all
+     * their elements are equal as defined by
+     * {@link #equals(float,float)}.
+     *
+     * @param x first array
+     * @param y second array
+     * @return true if the values are both null or have same dimension
+     * and equal elements.
+     * @deprecated as of 2.2 this method considers that {@code NaN == NaN}. In release
+     * 3.0, the semantics will change in order to comply with IEEE754 where it
+     * is specified that {@code NaN != NaN}.
+     * New methods have been added for those cases where the old semantics is
+     * useful (see e.g. {@link #equalsIncludingNaN(float[],float[])
+     * equalsIncludingNaN}.
+     */
+    @Deprecated
+    public static boolean equals(float[] x, float[] y) {
+        if ((x == null) || (y == null)) {
+            return !((x == null) ^ (y == null));
+        }
+        if (x.length != y.length) {
+            return false;
+        }
+        for (int i = 0; i < x.length; ++i) {
+            if (!equals(x[i], y[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true iff both arguments are null or have same dimensions and all
+     * their elements are equal as defined by
+     * {@link #equalsIncludingNaN(float,float)}.
+     *
+     * @param x first array
+     * @param y second array
+     * @return true if the values are both null or have same dimension and
+     * equal elements
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(float[] x, float[] y) {
+        if ((x == null) || (y == null)) {
+            return !((x == null) ^ (y == null));
+        }
+        if (x.length != y.length) {
+            return false;
+        }
+        for (int i = 0; i < x.length; ++i) {
+            if (!equalsIncludingNaN(x[i], y[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true iff both arguments are NaN or neither is NaN and they are
+     * equal
+     *
+     * <p>This method considers that {@code NaN == NaN}. In release
+     * 3.0, the semantics will change in order to comply with IEEE754 where it
+     * is specified that {@code NaN != NaN}.
+     * New methods have been added for those cases where the old semantics
+     * (w.r.t. NaN) is useful (see e.g.
+     * {@link #equalsIncludingNaN(double,double, double) equalsIncludingNaN}.
+     * </p>
+     *
+     * @param x first value
+     * @param y second value
+     * @return {@code true} if the values are equal.
+     */
+    public static boolean equals(double x, double y) {
+        return (Double.isNaN(x) && Double.isNaN(y)) || x == y;
+    }
+
+    /**
+     * Returns true if both arguments are NaN or neither is NaN and they are
+     * equal as defined by {@link #equals(double,double,int) equals(x, y, 1)}.
+     *
+     * @param x first value
+     * @param y second value
+     * @return {@code true} if the values are equal or both are NaN.
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(double x, double y) {
+        return (Double.isNaN(x) && Double.isNaN(y)) || equals(x, y, 1);
+    }
+
+    /**
+     * Returns true if both arguments are equal or within the range of allowed
+     * error (inclusive).
+     * <p>
+     * Two NaNs are considered equals, as are two infinities with same sign.
+     * </p>
+     * <p>This method considers that {@code NaN == NaN}. In release
+     * 3.0, the semantics will change in order to comply with IEEE754 where it
+     * is specified that {@code NaN != NaN}.
+     * New methods have been added for those cases where the old semantics
+     * (w.r.t. NaN) is useful (see e.g.
+     * {@link #equalsIncludingNaN(double,double, double) equalsIncludingNaN}.
+     * </p>
+     * @param x first value
+     * @param y second value
+     * @param eps the amount of absolute error to allow.
+     * @return {@code true} if the values are equal or within range of each other.
+     */
+    public static boolean equals(double x, double y, double eps) {
+        return equals(x, y) || FastMath.abs(y - x) <= eps;
+    }
+
+    /**
+     * Returns true if both arguments are NaN or are equal or within the range
+     * of allowed error (inclusive).
+     *
+     * @param x first value
+     * @param y second value
+     * @param eps the amount of absolute error to allow.
+     * @return {@code true} if the values are equal or within range of each other,
+     * or both are NaN.
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(double x, double y, double eps) {
+        return equalsIncludingNaN(x, y) || (FastMath.abs(y - x) <= eps);
+    }
+
+    /**
+     * Returns true if both arguments are equal or within the range of allowed
+     * error (inclusive).
+     * Two float numbers are considered equal if there are {@code (maxUlps - 1)}
+     * (or fewer) floating point numbers between them, i.e. two adjacent floating
+     * point numbers are considered equal.
+     * Adapted from <a
+     * href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm">
+     * Bruce Dawson</a>
+     *
+     * <p>This method considers that {@code NaN == NaN}. In release
+     * 3.0, the semantics will change in order to comply with IEEE754 where it
+     * is specified that {@code NaN != NaN}.
+     * New methods have been added for those cases where the old semantics
+     * (w.r.t. NaN) is useful (see e.g.
+     * {@link #equalsIncludingNaN(double,double, int) equalsIncludingNaN}.
+     * </p>
+     *
+     * @param x first value
+     * @param y second value
+     * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
+     * values between {@code x} and {@code y}.
+     * @return {@code true} if there are fewer than {@code maxUlps} floating
+     * point values between {@code x} and {@code y}.
+     */
+    public static boolean equals(double x, double y, int maxUlps) {
+        // Check that "maxUlps" is non-negative and small enough so that
+        // NaN won't compare as equal to anything (except another NaN).
+        assert maxUlps > 0 && maxUlps < NAN_GAP;
+
+        long xInt = Double.doubleToLongBits(x);
+        long yInt = Double.doubleToLongBits(y);
+
+        // Make lexicographically ordered as a two's-complement integer.
+        if (xInt < 0) {
+            xInt = SGN_MASK - xInt;
+        }
+        if (yInt < 0) {
+            yInt = SGN_MASK - yInt;
+        }
+
+        return FastMath.abs(xInt - yInt) <= maxUlps;
+    }
+
+    /**
+     * Returns true if both arguments are NaN or if they are equal as defined
+     * by {@link #equals(double,double,int) equals(x, y, maxUlps}.
+     *
+     * @param x first value
+     * @param y second value
+     * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
+     * values between {@code x} and {@code y}.
+     * @return {@code true} if both arguments are NaN or if there are less than
+     * {@code maxUlps} floating point values between {@code x} and {@code y}.
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(double x, double y, int maxUlps) {
+        return (Double.isNaN(x) && Double.isNaN(y)) || equals(x, y, maxUlps);
+    }
+
+    /**
+     * Returns true iff both arguments are null or have same dimensions and all
+     * their elements are equal as defined by
+     * {@link #equals(double,double)}.
+     *
+     * <p>This method considers that {@code NaN == NaN}. In release
+     * 3.0, the semantics will change in order to comply with IEEE754 where it
+     * is specified that {@code NaN != NaN}.
+     * New methods have been added for those cases wher the old semantics is
+     * useful (see e.g. {@link #equalsIncludingNaN(double[],double[])
+     * equalsIncludingNaN}.
+     * </p>
+     * @param x first array
+     * @param y second array
+     * @return true if the values are both null or have same dimension
+     * and equal elements.
+     */
+    public static boolean equals(double[] x, double[] y) {
+        if ((x == null) || (y == null)) {
+            return !((x == null) ^ (y == null));
+        }
+        if (x.length != y.length) {
+            return false;
+        }
+        for (int i = 0; i < x.length; ++i) {
+            if (!equals(x[i], y[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true iff both arguments are null or have same dimensions and all
+     * their elements are equal as defined by
+     * {@link #equalsIncludingNaN(double,double)}.
+     *
+     * @param x first array
+     * @param y second array
+     * @return true if the values are both null or have same dimension and
+     * equal elements
+     * @since 2.2
+     */
+    public static boolean equalsIncludingNaN(double[] x, double[] y) {
+        if ((x == null) || (y == null)) {
+            return !((x == null) ^ (y == null));
+        }
+        if (x.length != y.length) {
+            return false;
+        }
+        for (int i = 0; i < x.length; ++i) {
+            if (!equalsIncludingNaN(x[i], y[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns n!. Shorthand for <code>n</code> <a
+     * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the
+     * product of the numbers <code>1,...,n</code>.
+     * <p>
+     * <Strong>Preconditions</strong>:
+     * <ul>
+     * <li> <code>n >= 0</code> (otherwise
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * <li> The result is small enough to fit into a <code>long</code>. The
+     * largest value of <code>n</code> for which <code>n!</code> <
+     * Long.MAX_VALUE</code> is 20. If the computed value exceeds <code>Long.MAX_VALUE</code>
+     * an <code>ArithMeticException </code> is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param n argument
+     * @return <code>n!</code>
+     * @throws ArithmeticException if the result is too large to be represented
+     *         by a long integer.
+     * @throws IllegalArgumentException if n < 0
+     */
+    public static long factorial(final int n) {
+        if (n < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
+                  n);
+        }
+        if (n > 20) {
+            throw new ArithmeticException(
+                    "factorial value is too large to fit in a long");
+        }
+        return FACTORIALS[n];
+    }
+
+    /**
+     * Returns n!. Shorthand for <code>n</code> <a
+     * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the
+     * product of the numbers <code>1,...,n</code> as a <code>double</code>.
+     * <p>
+     * <Strong>Preconditions</strong>:
+     * <ul>
+     * <li> <code>n >= 0</code> (otherwise
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * <li> The result is small enough to fit into a <code>double</code>. The
+     * largest value of <code>n</code> for which <code>n!</code> <
+     * Double.MAX_VALUE</code> is 170. If the computed value exceeds
+     * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned</li>
+     * </ul>
+     * </p>
+     *
+     * @param n argument
+     * @return <code>n!</code>
+     * @throws IllegalArgumentException if n < 0
+     */
+    public static double factorialDouble(final int n) {
+        if (n < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
+                  n);
+        }
+        if (n < 21) {
+            return factorial(n);
+        }
+        return FastMath.floor(FastMath.exp(factorialLog(n)) + 0.5);
+    }
+
+    /**
+     * Returns the natural logarithm of n!.
+     * <p>
+     * <Strong>Preconditions</strong>:
+     * <ul>
+     * <li> <code>n >= 0</code> (otherwise
+     * <code>IllegalArgumentException</code> is thrown)</li>
+     * </ul></p>
+     *
+     * @param n argument
+     * @return <code>n!</code>
+     * @throws IllegalArgumentException if preconditions are not met.
+     */
+    public static double factorialLog(final int n) {
+        if (n < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
+                  n);
+        }
+        if (n < 21) {
+            return FastMath.log(factorial(n));
+        }
+        double logSum = 0;
+        for (int i = 2; i <= n; i++) {
+            logSum += FastMath.log(i);
+        }
+        return logSum;
+    }
+
+    /**
+     * <p>
+     * Gets the greatest common divisor of the absolute value of two numbers,
+     * using the "binary gcd" method which avoids division and modulo
+     * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef
+     * Stein (1961).
+     * </p>
+     * Special cases:
+     * <ul>
+     * <li>The invocations
+     * <code>gcd(Integer.MIN_VALUE, Integer.MIN_VALUE)</code>,
+     * <code>gcd(Integer.MIN_VALUE, 0)</code> and
+     * <code>gcd(0, Integer.MIN_VALUE)</code> throw an
+     * <code>ArithmeticException</code>, because the result would be 2^31, which
+     * is too large for an int value.</li>
+     * <li>The result of <code>gcd(x, x)</code>, <code>gcd(0, x)</code> and
+     * <code>gcd(x, 0)</code> is the absolute value of <code>x</code>, except
+     * for the special cases above.
+     * <li>The invocation <code>gcd(0, 0)</code> is the only one which returns
+     * <code>0</code>.</li>
+     * </ul>
+     *
+     * @param p any number
+     * @param q any number
+     * @return the greatest common divisor, never negative
+     * @throws ArithmeticException if the result cannot be represented as a
+     * nonnegative int value
+     * @since 1.1
+     */
+    public static int gcd(final int p, final int q) {
+        int u = p;
+        int v = q;
+        if ((u == 0) || (v == 0)) {
+            if ((u == Integer.MIN_VALUE) || (v == Integer.MIN_VALUE)) {
+                throw MathRuntimeException.createArithmeticException(
+                        LocalizedFormats.GCD_OVERFLOW_32_BITS,
+                        p, q);
+            }
+            return FastMath.abs(u) + FastMath.abs(v);
+        }
+        // keep u and v negative, as negative integers range down to
+        // -2^31, while positive numbers can only be as large as 2^31-1
+        // (i.e. we can't necessarily negate a negative number without
+        // overflow)
+        /* assert u!=0 && v!=0; */
+        if (u > 0) {
+            u = -u;
+        } // make u negative
+        if (v > 0) {
+            v = -v;
+        } // make v negative
+        // B1. [Find power of 2]
+        int k = 0;
+        while ((u & 1) == 0 && (v & 1) == 0 && k < 31) { // while u and v are
+                                                            // both even...
+            u /= 2;
+            v /= 2;
+            k++; // cast out twos.
+        }
+        if (k == 31) {
+            throw MathRuntimeException.createArithmeticException(
+                    LocalizedFormats.GCD_OVERFLOW_32_BITS,
+                    p, q);
+        }
+        // B2. Initialize: u and v have been divided by 2^k and at least
+        // one is odd.
+        int t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */;
+        // t negative: u was odd, v may be even (t replaces v)
+        // t positive: u was even, v is odd (t replaces u)
+        do {
+            /* assert u<0 && v<0; */
+            // B4/B3: cast out twos from t.
+            while ((t & 1) == 0) { // while t is even..
+                t /= 2; // cast out twos
+            }
+            // B5 [reset max(u,v)]
+            if (t > 0) {
+                u = -t;
+            } else {
+                v = t;
+            }
+            // B6/B3. at this point both u and v should be odd.
+            t = (v - u) / 2;
+            // |u| larger: t positive (replace u)
+            // |v| larger: t negative (replace v)
+        } while (t != 0);
+        return -u * (1 << k); // gcd is u*2^k
+    }
+
+    /**
+     * <p>
+     * Gets the greatest common divisor of the absolute value of two numbers,
+     * using the "binary gcd" method which avoids division and modulo
+     * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef
+     * Stein (1961).
+     * </p>
+     * Special cases:
+     * <ul>
+     * <li>The invocations
+     * <code>gcd(Long.MIN_VALUE, Long.MIN_VALUE)</code>,
+     * <code>gcd(Long.MIN_VALUE, 0L)</code> and
+     * <code>gcd(0L, Long.MIN_VALUE)</code> throw an
+     * <code>ArithmeticException</code>, because the result would be 2^63, which
+     * is too large for a long value.</li>
+     * <li>The result of <code>gcd(x, x)</code>, <code>gcd(0L, x)</code> and
+     * <code>gcd(x, 0L)</code> is the absolute value of <code>x</code>, except
+     * for the special cases above.
+     * <li>The invocation <code>gcd(0L, 0L)</code> is the only one which returns
+     * <code>0L</code>.</li>
+     * </ul>
+     *
+     * @param p any number
+     * @param q any number
+     * @return the greatest common divisor, never negative
+     * @throws ArithmeticException if the result cannot be represented as a nonnegative long
+     * value
+     * @since 2.1
+     */
+    public static long gcd(final long p, final long q) {
+        long u = p;
+        long v = q;
+        if ((u == 0) || (v == 0)) {
+            if ((u == Long.MIN_VALUE) || (v == Long.MIN_VALUE)){
+                throw MathRuntimeException.createArithmeticException(
+                        LocalizedFormats.GCD_OVERFLOW_64_BITS,
+                        p, q);
+            }
+            return FastMath.abs(u) + FastMath.abs(v);
+        }
+        // keep u and v negative, as negative integers range down to
+        // -2^63, while positive numbers can only be as large as 2^63-1
+        // (i.e. we can't necessarily negate a negative number without
+        // overflow)
+        /* assert u!=0 && v!=0; */
+        if (u > 0) {
+            u = -u;
+        } // make u negative
+        if (v > 0) {
+            v = -v;
+        } // make v negative
+        // B1. [Find power of 2]
+        int k = 0;
+        while ((u & 1) == 0 && (v & 1) == 0 && k < 63) { // while u and v are
+                                                            // both even...
+            u /= 2;
+            v /= 2;
+            k++; // cast out twos.
+        }
+        if (k == 63) {
+            throw MathRuntimeException.createArithmeticException(
+                    LocalizedFormats.GCD_OVERFLOW_64_BITS,
+                    p, q);
+        }
+        // B2. Initialize: u and v have been divided by 2^k and at least
+        // one is odd.
+        long t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */;
+        // t negative: u was odd, v may be even (t replaces v)
+        // t positive: u was even, v is odd (t replaces u)
+        do {
+            /* assert u<0 && v<0; */
+            // B4/B3: cast out twos from t.
+            while ((t & 1) == 0) { // while t is even..
+                t /= 2; // cast out twos
+            }
+            // B5 [reset max(u,v)]
+            if (t > 0) {
+                u = -t;
+            } else {
+                v = t;
+            }
+            // B6/B3. at this point both u and v should be odd.
+            t = (v - u) / 2;
+            // |u| larger: t positive (replace u)
+            // |v| larger: t negative (replace v)
+        } while (t != 0);
+        return -u * (1L << k); // gcd is u*2^k
+    }
+
+    /**
+     * Returns an integer hash code representing the given double value.
+     *
+     * @param value the value to be hashed
+     * @return the hash code
+     */
+    public static int hash(double value) {
+        return new Double(value).hashCode();
+    }
+
+    /**
+     * Returns an integer hash code representing the given double array.
+     *
+     * @param value the value to be hashed (may be null)
+     * @return the hash code
+     * @since 1.2
+     */
+    public static int hash(double[] value) {
+        return Arrays.hashCode(value);
+    }
+
+    /**
+     * For a byte value x, this method returns (byte)(+1) if x >= 0 and
+     * (byte)(-1) if x < 0.
+     *
+     * @param x the value, a byte
+     * @return (byte)(+1) or (byte)(-1), depending on the sign of x
+     */
+    public static byte indicator(final byte x) {
+        return (x >= ZB) ? PB : NB;
+    }
+
+    /**
+     * For a double precision value x, this method returns +1.0 if x >= 0 and
+     * -1.0 if x < 0. Returns <code>NaN</code> if <code>x</code> is
+     * <code>NaN</code>.
+     *
+     * @param x the value, a double
+     * @return +1.0 or -1.0, depending on the sign of x
+     */
+    public static double indicator(final double x) {
+        if (Double.isNaN(x)) {
+            return Double.NaN;
+        }
+        return (x >= 0.0) ? 1.0 : -1.0;
+    }
+
+    /**
+     * For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x <
+     * 0. Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>.
+     *
+     * @param x the value, a float
+     * @return +1.0F or -1.0F, depending on the sign of x
+     */
+    public static float indicator(final float x) {
+        if (Float.isNaN(x)) {
+            return Float.NaN;
+        }
+        return (x >= 0.0F) ? 1.0F : -1.0F;
+    }
+
+    /**
+     * For an int value x, this method returns +1 if x >= 0 and -1 if x < 0.
+     *
+     * @param x the value, an int
+     * @return +1 or -1, depending on the sign of x
+     */
+    public static int indicator(final int x) {
+        return (x >= 0) ? 1 : -1;
+    }
+
+    /**
+     * For a long value x, this method returns +1L if x >= 0 and -1L if x < 0.
+     *
+     * @param x the value, a long
+     * @return +1L or -1L, depending on the sign of x
+     */
+    public static long indicator(final long x) {
+        return (x >= 0L) ? 1L : -1L;
+    }
+
+    /**
+     * For a short value x, this method returns (short)(+1) if x >= 0 and
+     * (short)(-1) if x < 0.
+     *
+     * @param x the value, a short
+     * @return (short)(+1) or (short)(-1), depending on the sign of x
+     */
+    public static short indicator(final short x) {
+        return (x >= ZS) ? PS : NS;
+    }
+
+    /**
+     * <p>
+     * Returns the least common multiple of the absolute value of two numbers,
+     * using the formula <code>lcm(a,b) = (a / gcd(a,b)) * b</code>.
+     * </p>
+     * Special cases:
+     * <ul>
+     * <li>The invocations <code>lcm(Integer.MIN_VALUE, n)</code> and
+     * <code>lcm(n, Integer.MIN_VALUE)</code>, where <code>abs(n)</code> is a
+     * power of 2, throw an <code>ArithmeticException</code>, because the result
+     * would be 2^31, which is too large for an int value.</li>
+     * <li>The result of <code>lcm(0, x)</code> and <code>lcm(x, 0)</code> is
+     * <code>0</code> for any <code>x</code>.
+     * </ul>
+     *
+     * @param a any number
+     * @param b any number
+     * @return the least common multiple, never negative
+     * @throws ArithmeticException
+     *             if the result cannot be represented as a nonnegative int
+     *             value
+     * @since 1.1
+     */
+    public static int lcm(int a, int b) {
+        if (a==0 || b==0){
+            return 0;
+        }
+        int lcm = FastMath.abs(mulAndCheck(a / gcd(a, b), b));
+        if (lcm == Integer.MIN_VALUE) {
+            throw MathRuntimeException.createArithmeticException(
+                LocalizedFormats.LCM_OVERFLOW_32_BITS,
+                a, b);
+        }
+        return lcm;
+    }
+
+    /**
+     * <p>
+     * Returns the least common multiple of the absolute value of two numbers,
+     * using the formula <code>lcm(a,b) = (a / gcd(a,b)) * b</code>.
+     * </p>
+     * Special cases:
+     * <ul>
+     * <li>The invocations <code>lcm(Long.MIN_VALUE, n)</code> and
+     * <code>lcm(n, Long.MIN_VALUE)</code>, where <code>abs(n)</code> is a
+     * power of 2, throw an <code>ArithmeticException</code>, because the result
+     * would be 2^63, which is too large for an int value.</li>
+     * <li>The result of <code>lcm(0L, x)</code> and <code>lcm(x, 0L)</code> is
+     * <code>0L</code> for any <code>x</code>.
+     * </ul>
+     *
+     * @param a any number
+     * @param b any number
+     * @return the least common multiple, never negative
+     * @throws ArithmeticException if the result cannot be represented as a nonnegative long
+     * value
+     * @since 2.1
+     */
+    public static long lcm(long a, long b) {
+        if (a==0 || b==0){
+            return 0;
+        }
+        long lcm = FastMath.abs(mulAndCheck(a / gcd(a, b), b));
+        if (lcm == Long.MIN_VALUE){
+            throw MathRuntimeException.createArithmeticException(
+                LocalizedFormats.LCM_OVERFLOW_64_BITS,
+                a, b);
+        }
+        return lcm;
+    }
+
+    /**
+     * <p>Returns the
+     * <a href="http://mathworld.wolfram.com/Logarithm.html">logarithm</a>
+     * for base <code>b</code> of <code>x</code>.
+     * </p>
+     * <p>Returns <code>NaN<code> if either argument is negative.  If
+     * <code>base</code> is 0 and <code>x</code> is positive, 0 is returned.
+     * If <code>base</code> is positive and <code>x</code> is 0,
+     * <code>Double.NEGATIVE_INFINITY</code> is returned.  If both arguments
+     * are 0, the result is <code>NaN</code>.</p>
+     *
+     * @param base the base of the logarithm, must be greater than 0
+     * @param x argument, must be greater than 0
+     * @return the value of the logarithm - the number y such that base^y = x.
+     * @since 1.2
+     */
+    public static double log(double base, double x) {
+        return FastMath.log(x)/FastMath.log(base);
+    }
+
+    /**
+     * Multiply two integers, checking for overflow.
+     *
+     * @param x a factor
+     * @param y a factor
+     * @return the product <code>x*y</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         int
+     * @since 1.1
+     */
+    public static int mulAndCheck(int x, int y) {
+        long m = ((long)x) * ((long)y);
+        if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) {
+            throw new ArithmeticException("overflow: mul");
+        }
+        return (int)m;
+    }
+
+    /**
+     * Multiply two long integers, checking for overflow.
+     *
+     * @param a first value
+     * @param b second value
+     * @return the product <code>a * b</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         long
+     * @since 1.2
+     */
+    public static long mulAndCheck(long a, long b) {
+        long ret;
+        String msg = "overflow: multiply";
+        if (a > b) {
+            // use symmetry to reduce boundary cases
+            ret = mulAndCheck(b, a);
+        } else {
+            if (a < 0) {
+                if (b < 0) {
+                    // check for positive overflow with negative a, negative b
+                    if (a >= Long.MAX_VALUE / b) {
+                        ret = a * b;
+                    } else {
+                        throw new ArithmeticException(msg);
+                    }
+                } else if (b > 0) {
+                    // check for negative overflow with negative a, positive b
+                    if (Long.MIN_VALUE / b <= a) {
+                        ret = a * b;
+                    } else {
+                        throw new ArithmeticException(msg);
+
+                    }
+                } else {
+                    // assert b == 0
+                    ret = 0;
+                }
+            } else if (a > 0) {
+                // assert a > 0
+                // assert b > 0
+
+                // check for positive overflow with positive a, positive b
+                if (a <= Long.MAX_VALUE / b) {
+                    ret = a * b;
+                } else {
+                    throw new ArithmeticException(msg);
+                }
+            } else {
+                // assert a == 0
+                ret = 0;
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Get the next machine representable number after a number, moving
+     * in the direction of another number.
+     * <p>
+     * If <code>direction</code> is greater than or equal to<code>d</code>,
+     * the smallest machine representable number strictly greater than
+     * <code>d</code> is returned; otherwise the largest representable number
+     * strictly less than <code>d</code> is returned.</p>
+     * <p>
+     * If <code>d</code> is NaN or Infinite, it is returned unchanged.</p>
+     *
+     * @param d base number
+     * @param direction (the only important thing is whether
+     * direction is greater or smaller than d)
+     * @return the next machine representable number in the specified direction
+     * @since 1.2
+     * @deprecated as of 2.2, replaced by {@link FastMath#nextAfter(double, double)}
+     * which handles Infinities differently, and returns direction if d and direction compare equal.
+     */
+    @Deprecated
+    public static double nextAfter(double d, double direction) {
+
+        // handling of some important special cases
+        if (Double.isNaN(d) || Double.isInfinite(d)) {
+                return d;
+        } else if (d == 0) {
+                return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE;
+        }
+        // special cases MAX_VALUE to infinity and  MIN_VALUE to 0
+        // are handled just as normal numbers
+
+        // split the double in raw components
+        long bits     = Double.doubleToLongBits(d);
+        long sign     = bits & 0x8000000000000000L;
+        long exponent = bits & 0x7ff0000000000000L;
+        long mantissa = bits & 0x000fffffffffffffL;
+
+        if (d * (direction - d) >= 0) {
+                // we should increase the mantissa
+                if (mantissa == 0x000fffffffffffffL) {
+                        return Double.longBitsToDouble(sign |
+                                        (exponent + 0x0010000000000000L));
+                } else {
+                        return Double.longBitsToDouble(sign |
+                                        exponent | (mantissa + 1));
+                }
+        } else {
+                // we should decrease the mantissa
+                if (mantissa == 0L) {
+                        return Double.longBitsToDouble(sign |
+                                        (exponent - 0x0010000000000000L) |
+                                        0x000fffffffffffffL);
+                } else {
+                        return Double.longBitsToDouble(sign |
+                                        exponent | (mantissa - 1));
+                }
+        }
+    }
+
+    /**
+     * Scale a number by 2<sup>scaleFactor</sup>.
+     * <p>If <code>d</code> is 0 or NaN or Infinite, it is returned unchanged.</p>
+     *
+     * @param d base number
+     * @param scaleFactor power of two by which d should be multiplied
+     * @return d &times; 2<sup>scaleFactor</sup>
+     * @since 2.0
+     * @deprecated as of 2.2, replaced by {@link FastMath#scalb(double, int)}
+     */
+    @Deprecated
+    public static double scalb(final double d, final int scaleFactor) {
+        return FastMath.scalb(d, scaleFactor);
+    }
+
+    /**
+     * Normalize an angle in a 2&pi wide interval around a center value.
+     * <p>This method has three main uses:</p>
+     * <ul>
+     *   <li>normalize an angle between 0 and 2&pi;:<br/>
+     *       <code>a = MathUtils.normalizeAngle(a, FastMath.PI);</code></li>
+     *   <li>normalize an angle between -&pi; and +&pi;<br/>
+     *       <code>a = MathUtils.normalizeAngle(a, 0.0);</code></li>
+     *   <li>compute the angle between two defining angular positions:<br>
+     *       <code>angle = MathUtils.normalizeAngle(end, start) - start;</code></li>
+     * </ul>
+     * <p>Note that due to numerical accuracy and since &pi; cannot be represented
+     * exactly, the result interval is <em>closed</em>, it cannot be half-closed
+     * as would be more satisfactory in a purely mathematical view.</p>
+     * @param a angle to normalize
+     * @param center center of the desired 2&pi; interval for the result
+     * @return a-2k&pi; with integer k and center-&pi; &lt;= a-2k&pi; &lt;= center+&pi;
+     * @since 1.2
+     */
+     public static double normalizeAngle(double a, double center) {
+         return a - TWO_PI * FastMath.floor((a + FastMath.PI - center) / TWO_PI);
+     }
+
+     /**
+      * <p>Normalizes an array to make it sum to a specified value.
+      * Returns the result of the transformation <pre>
+      *    x |-> x * normalizedSum / sum
+      * </pre>
+      * applied to each non-NaN element x of the input array, where sum is the
+      * sum of the non-NaN entries in the input array.</p>
+      *
+      * <p>Throws IllegalArgumentException if <code>normalizedSum</code> is infinite
+      * or NaN and ArithmeticException if the input array contains any infinite elements
+      * or sums to 0</p>
+      *
+      * <p>Ignores (i.e., copies unchanged to the output array) NaNs in the input array.</p>
+      *
+      * @param values input array to be normalized
+      * @param normalizedSum target sum for the normalized array
+      * @return normalized array
+      * @throws ArithmeticException if the input array contains infinite elements or sums to zero
+      * @throws IllegalArgumentException if the target sum is infinite or NaN
+      * @since 2.1
+      */
+     public static double[] normalizeArray(double[] values, double normalizedSum)
+       throws ArithmeticException, IllegalArgumentException {
+         if (Double.isInfinite(normalizedSum)) {
+             throw MathRuntimeException.createIllegalArgumentException(
+                     LocalizedFormats.NORMALIZE_INFINITE);
+         }
+         if (Double.isNaN(normalizedSum)) {
+             throw MathRuntimeException.createIllegalArgumentException(
+                     LocalizedFormats.NORMALIZE_NAN);
+         }
+         double sum = 0d;
+         final int len = values.length;
+         double[] out = new double[len];
+         for (int i = 0; i < len; i++) {
+             if (Double.isInfinite(values[i])) {
+                 throw MathRuntimeException.createArithmeticException(
+                         LocalizedFormats.INFINITE_ARRAY_ELEMENT, values[i], i);
+             }
+             if (!Double.isNaN(values[i])) {
+                 sum += values[i];
+             }
+         }
+         if (sum == 0) {
+             throw MathRuntimeException.createArithmeticException(LocalizedFormats.ARRAY_SUMS_TO_ZERO);
+         }
+         for (int i = 0; i < len; i++) {
+             if (Double.isNaN(values[i])) {
+                 out[i] = Double.NaN;
+             } else {
+                 out[i] = values[i] * normalizedSum / sum;
+             }
+         }
+         return out;
+     }
+
+    /**
+     * Round the given value to the specified number of decimal places. The
+     * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method.
+     *
+     * @param x the value to round.
+     * @param scale the number of digits to the right of the decimal point.
+     * @return the rounded value.
+     * @since 1.1
+     */
+    public static double round(double x, int scale) {
+        return round(x, scale, BigDecimal.ROUND_HALF_UP);
+    }
+
+    /**
+     * Round the given value to the specified number of decimal places. The
+     * value is rounded using the given method which is any method defined in
+     * {@link BigDecimal}.
+     *
+     * @param x the value to round.
+     * @param scale the number of digits to the right of the decimal point.
+     * @param roundingMethod the rounding method as defined in
+     *        {@link BigDecimal}.
+     * @return the rounded value.
+     * @since 1.1
+     */
+    public static double round(double x, int scale, int roundingMethod) {
+        try {
+            return (new BigDecimal
+                   (Double.toString(x))
+                   .setScale(scale, roundingMethod))
+                   .doubleValue();
+        } catch (NumberFormatException ex) {
+            if (Double.isInfinite(x)) {
+                return x;
+            } else {
+                return Double.NaN;
+            }
+        }
+    }
+
+    /**
+     * Round the given value to the specified number of decimal places. The
+     * value is rounding using the {@link BigDecimal#ROUND_HALF_UP} method.
+     *
+     * @param x the value to round.
+     * @param scale the number of digits to the right of the decimal point.
+     * @return the rounded value.
+     * @since 1.1
+     */
+    public static float round(float x, int scale) {
+        return round(x, scale, BigDecimal.ROUND_HALF_UP);
+    }
+
+    /**
+     * Round the given value to the specified number of decimal places. The
+     * value is rounded using the given method which is any method defined in
+     * {@link BigDecimal}.
+     *
+     * @param x the value to round.
+     * @param scale the number of digits to the right of the decimal point.
+     * @param roundingMethod the rounding method as defined in
+     *        {@link BigDecimal}.
+     * @return the rounded value.
+     * @since 1.1
+     */
+    public static float round(float x, int scale, int roundingMethod) {
+        float sign = indicator(x);
+        float factor = (float)FastMath.pow(10.0f, scale) * sign;
+        return (float)roundUnscaled(x * factor, sign, roundingMethod) / factor;
+    }
+
+    /**
+     * Round the given non-negative, value to the "nearest" integer. Nearest is
+     * determined by the rounding method specified. Rounding methods are defined
+     * in {@link BigDecimal}.
+     *
+     * @param unscaled the value to round.
+     * @param sign the sign of the original, scaled value.
+     * @param roundingMethod the rounding method as defined in
+     *        {@link BigDecimal}.
+     * @return the rounded value.
+     * @since 1.1
+     */
+    private static double roundUnscaled(double unscaled, double sign,
+        int roundingMethod) {
+        switch (roundingMethod) {
+        case BigDecimal.ROUND_CEILING :
+            if (sign == -1) {
+                unscaled = FastMath.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY));
+            } else {
+                unscaled = FastMath.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY));
+            }
+            break;
+        case BigDecimal.ROUND_DOWN :
+            unscaled = FastMath.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY));
+            break;
+        case BigDecimal.ROUND_FLOOR :
+            if (sign == -1) {
+                unscaled = FastMath.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY));
+            } else {
+                unscaled = FastMath.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY));
+            }
+            break;
+        case BigDecimal.ROUND_HALF_DOWN : {
+            unscaled = nextAfter(unscaled, Double.NEGATIVE_INFINITY);
+            double fraction = unscaled - FastMath.floor(unscaled);
+            if (fraction > 0.5) {
+                unscaled = FastMath.ceil(unscaled);
+            } else {
+                unscaled = FastMath.floor(unscaled);
+            }
+            break;
+        }
+        case BigDecimal.ROUND_HALF_EVEN : {
+            double fraction = unscaled - FastMath.floor(unscaled);
+            if (fraction > 0.5) {
+                unscaled = FastMath.ceil(unscaled);
+            } else if (fraction < 0.5) {
+                unscaled = FastMath.floor(unscaled);
+            } else {
+                // The following equality test is intentional and needed for rounding purposes
+                if (FastMath.floor(unscaled) / 2.0 == FastMath.floor(Math
+                    .floor(unscaled) / 2.0)) { // even
+                    unscaled = FastMath.floor(unscaled);
+                } else { // odd
+                    unscaled = FastMath.ceil(unscaled);
+                }
+            }
+            break;
+        }
+        case BigDecimal.ROUND_HALF_UP : {
+            unscaled = nextAfter(unscaled, Double.POSITIVE_INFINITY);
+            double fraction = unscaled - FastMath.floor(unscaled);
+            if (fraction >= 0.5) {
+                unscaled = FastMath.ceil(unscaled);
+            } else {
+                unscaled = FastMath.floor(unscaled);
+            }
+            break;
+        }
+        case BigDecimal.ROUND_UNNECESSARY :
+            if (unscaled != FastMath.floor(unscaled)) {
+                throw new ArithmeticException("Inexact result from rounding");
+            }
+            break;
+        case BigDecimal.ROUND_UP :
+            unscaled = FastMath.ceil(nextAfter(unscaled,  Double.POSITIVE_INFINITY));
+            break;
+        default :
+            throw MathRuntimeException.createIllegalArgumentException(
+                  LocalizedFormats.INVALID_ROUNDING_METHOD,
+                  roundingMethod,
+                  "ROUND_CEILING",     BigDecimal.ROUND_CEILING,
+                  "ROUND_DOWN",        BigDecimal.ROUND_DOWN,
+                  "ROUND_FLOOR",       BigDecimal.ROUND_FLOOR,
+                  "ROUND_HALF_DOWN",   BigDecimal.ROUND_HALF_DOWN,
+                  "ROUND_HALF_EVEN",   BigDecimal.ROUND_HALF_EVEN,
+                  "ROUND_HALF_UP",     BigDecimal.ROUND_HALF_UP,
+                  "ROUND_UNNECESSARY", BigDecimal.ROUND_UNNECESSARY,
+                  "ROUND_UP",          BigDecimal.ROUND_UP);
+        }
+        return unscaled;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
+     * for byte value <code>x</code>.
+     * <p>
+     * For a byte value x, this method returns (byte)(+1) if x > 0, (byte)(0) if
+     * x = 0, and (byte)(-1) if x < 0.</p>
+     *
+     * @param x the value, a byte
+     * @return (byte)(+1), (byte)(0), or (byte)(-1), depending on the sign of x
+     */
+    public static byte sign(final byte x) {
+        return (x == ZB) ? ZB : (x > ZB) ? PB : NB;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
+     * for double precision <code>x</code>.
+     * <p>
+     * For a double value <code>x</code>, this method returns
+     * <code>+1.0</code> if <code>x > 0</code>, <code>0.0</code> if
+     * <code>x = 0.0</code>, and <code>-1.0</code> if <code>x < 0</code>.
+     * Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>.</p>
+     *
+     * @param x the value, a double
+     * @return +1.0, 0.0, or -1.0, depending on the sign of x
+     */
+    public static double sign(final double x) {
+        if (Double.isNaN(x)) {
+            return Double.NaN;
+        }
+        return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
+     * for float value <code>x</code>.
+     * <p>
+     * For a float value x, this method returns +1.0F if x > 0, 0.0F if x =
+     * 0.0F, and -1.0F if x < 0. Returns <code>NaN</code> if <code>x</code>
+     * is <code>NaN</code>.</p>
+     *
+     * @param x the value, a float
+     * @return +1.0F, 0.0F, or -1.0F, depending on the sign of x
+     */
+    public static float sign(final float x) {
+        if (Float.isNaN(x)) {
+            return Float.NaN;
+        }
+        return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
+     * for int value <code>x</code>.
+     * <p>
+     * For an int value x, this method returns +1 if x > 0, 0 if x = 0, and -1
+     * if x < 0.</p>
+     *
+     * @param x the value, an int
+     * @return +1, 0, or -1, depending on the sign of x
+     */
+    public static int sign(final int x) {
+        return (x == 0) ? 0 : (x > 0) ? 1 : -1;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
+     * for long value <code>x</code>.
+     * <p>
+     * For a long value x, this method returns +1L if x > 0, 0L if x = 0, and
+     * -1L if x < 0.</p>
+     *
+     * @param x the value, a long
+     * @return +1L, 0L, or -1L, depending on the sign of x
+     */
+    public static long sign(final long x) {
+        return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
+     * for short value <code>x</code>.
+     * <p>
+     * For a short value x, this method returns (short)(+1) if x > 0, (short)(0)
+     * if x = 0, and (short)(-1) if x < 0.</p>
+     *
+     * @param x the value, a short
+     * @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of
+     *         x
+     */
+    public static short sign(final short x) {
+        return (x == ZS) ? ZS : (x > ZS) ? PS : NS;
+    }
+
+    /**
+     * Returns the <a href="http://mathworld.wolfram.com/HyperbolicSine.html">
+     * hyperbolic sine</a> of x.
+     *
+     * @param x double value for which to find the hyperbolic sine
+     * @return hyperbolic sine of x
+     */
+    public static double sinh(double x) {
+        return (FastMath.exp(x) - FastMath.exp(-x)) / 2.0;
+    }
+
+    /**
+     * Subtract two integers, checking for overflow.
+     *
+     * @param x the minuend
+     * @param y the subtrahend
+     * @return the difference <code>x-y</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         int
+     * @since 1.1
+     */
+    public static int subAndCheck(int x, int y) {
+        long s = (long)x - (long)y;
+        if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
+            throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, x, y);
+        }
+        return (int)s;
+    }
+
+    /**
+     * Subtract two long integers, checking for overflow.
+     *
+     * @param a first value
+     * @param b second value
+     * @return the difference <code>a-b</code>
+     * @throws ArithmeticException if the result can not be represented as an
+     *         long
+     * @since 1.2
+     */
+    public static long subAndCheck(long a, long b) {
+        long ret;
+        String msg = "overflow: subtract";
+        if (b == Long.MIN_VALUE) {
+            if (a < 0) {
+                ret = a - b;
+            } else {
+                throw new ArithmeticException(msg);
+            }
+        } else {
+            // use additive inverse
+            ret = addAndCheck(a, -b, LocalizedFormats.OVERFLOW_IN_ADDITION);
+        }
+        return ret;
+    }
+
+    /**
+     * Raise an int to an int power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static int pow(final int k, int e)
+        throws IllegalArgumentException {
+
+        if (e < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        int result = 1;
+        int k2p    = k;
+        while (e != 0) {
+            if ((e & 0x1) != 0) {
+                result *= k2p;
+            }
+            k2p *= k2p;
+            e = e >> 1;
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Raise an int to a long power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static int pow(final int k, long e)
+        throws IllegalArgumentException {
+
+        if (e < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        int result = 1;
+        int k2p    = k;
+        while (e != 0) {
+            if ((e & 0x1) != 0) {
+                result *= k2p;
+            }
+            k2p *= k2p;
+            e = e >> 1;
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Raise a long to an int power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static long pow(final long k, int e)
+        throws IllegalArgumentException {
+
+        if (e < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        long result = 1l;
+        long k2p    = k;
+        while (e != 0) {
+            if ((e & 0x1) != 0) {
+                result *= k2p;
+            }
+            k2p *= k2p;
+            e = e >> 1;
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Raise a long to a long power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static long pow(final long k, long e)
+        throws IllegalArgumentException {
+
+        if (e < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        long result = 1l;
+        long k2p    = k;
+        while (e != 0) {
+            if ((e & 0x1) != 0) {
+                result *= k2p;
+            }
+            k2p *= k2p;
+            e = e >> 1;
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Raise a BigInteger to an int power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static BigInteger pow(final BigInteger k, int e)
+        throws IllegalArgumentException {
+
+        if (e < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        return k.pow(e);
+
+    }
+
+    /**
+     * Raise a BigInteger to a long power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static BigInteger pow(final BigInteger k, long e)
+        throws IllegalArgumentException {
+
+        if (e < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        BigInteger result = BigInteger.ONE;
+        BigInteger k2p    = k;
+        while (e != 0) {
+            if ((e & 0x1) != 0) {
+                result = result.multiply(k2p);
+            }
+            k2p = k2p.multiply(k2p);
+            e = e >> 1;
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Raise a BigInteger to a BigInteger power.
+     * @param k number to raise
+     * @param e exponent (must be positive or null)
+     * @return k<sup>e</sup>
+     * @exception IllegalArgumentException if e is negative
+     */
+    public static BigInteger pow(final BigInteger k, BigInteger e)
+        throws IllegalArgumentException {
+
+        if (e.compareTo(BigInteger.ZERO) < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
+                k, e);
+        }
+
+        BigInteger result = BigInteger.ONE;
+        BigInteger k2p    = k;
+        while (!BigInteger.ZERO.equals(e)) {
+            if (e.testBit(0)) {
+                result = result.multiply(k2p);
+            }
+            k2p = k2p.multiply(k2p);
+            e = e.shiftRight(1);
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Calculates the L<sub>1</sub> (sum of abs) distance between two points.
+     *
+     * @param p1 the first point
+     * @param p2 the second point
+     * @return the L<sub>1</sub> distance between the two points
+     */
+    public static double distance1(double[] p1, double[] p2) {
+        double sum = 0;
+        for (int i = 0; i < p1.length; i++) {
+            sum += FastMath.abs(p1[i] - p2[i]);
+        }
+        return sum;
+    }
+
+    /**
+     * Calculates the L<sub>1</sub> (sum of abs) distance between two points.
+     *
+     * @param p1 the first point
+     * @param p2 the second point
+     * @return the L<sub>1</sub> distance between the two points
+     */
+    public static int distance1(int[] p1, int[] p2) {
+      int sum = 0;
+      for (int i = 0; i < p1.length; i++) {
+          sum += FastMath.abs(p1[i] - p2[i]);
+      }
+      return sum;
+    }
+
+    /**
+     * Calculates the L<sub>2</sub> (Euclidean) distance between two points.
+     *
+     * @param p1 the first point
+     * @param p2 the second point
+     * @return the L<sub>2</sub> distance between the two points
+     */
+    public static double distance(double[] p1, double[] p2) {
+        double sum = 0;
+        for (int i = 0; i < p1.length; i++) {
+            final double dp = p1[i] - p2[i];
+            sum += dp * dp;
+        }
+        return FastMath.sqrt(sum);
+    }
+
+    /**
+     * Calculates the L<sub>2</sub> (Euclidean) distance between two points.
+     *
+     * @param p1 the first point
+     * @param p2 the second point
+     * @return the L<sub>2</sub> distance between the two points
+     */
+    public static double distance(int[] p1, int[] p2) {
+      double sum = 0;
+      for (int i = 0; i < p1.length; i++) {
+          final double dp = p1[i] - p2[i];
+          sum += dp * dp;
+      }
+      return FastMath.sqrt(sum);
+    }
+
+    /**
+     * Calculates the L<sub>&infin;</sub> (max of abs) distance between two points.
+     *
+     * @param p1 the first point
+     * @param p2 the second point
+     * @return the L<sub>&infin;</sub> distance between the two points
+     */
+    public static double distanceInf(double[] p1, double[] p2) {
+        double max = 0;
+        for (int i = 0; i < p1.length; i++) {
+            max = FastMath.max(max, FastMath.abs(p1[i] - p2[i]));
+        }
+        return max;
+    }
+
+    /**
+     * Calculates the L<sub>&infin;</sub> (max of abs) distance between two points.
+     *
+     * @param p1 the first point
+     * @param p2 the second point
+     * @return the L<sub>&infin;</sub> distance between the two points
+     */
+    public static int distanceInf(int[] p1, int[] p2) {
+        int max = 0;
+        for (int i = 0; i < p1.length; i++) {
+            max = FastMath.max(max, FastMath.abs(p1[i] - p2[i]));
+        }
+        return max;
+    }
+
+    /**
+     * Specification of ordering direction.
+     */
+    public static enum OrderDirection {
+        /** Constant for increasing direction. */
+        INCREASING,
+        /** Constant for decreasing direction. */
+        DECREASING
+    }
+
+    /**
+     * Checks that the given array is sorted.
+     *
+     * @param val Values.
+     * @param dir Ordering direction.
+     * @param strict Whether the order should be strict.
+     * @throws NonMonotonousSequenceException if the array is not sorted.
+     * @since 2.2
+     */
+    public static void checkOrder(double[] val, OrderDirection dir, boolean strict) {
+        double previous = val[0];
+        boolean ok = true;
+
+        int max = val.length;
+        for (int i = 1; i < max; i++) {
+            switch (dir) {
+            case INCREASING:
+                if (strict) {
+                    if (val[i] <= previous) {
+                        ok = false;
+                    }
+                } else {
+                    if (val[i] < previous) {
+                        ok = false;
+                    }
+                }
+                break;
+            case DECREASING:
+                if (strict) {
+                    if (val[i] >= previous) {
+                        ok = false;
+                    }
+                } else {
+                    if (val[i] > previous) {
+                        ok = false;
+                    }
+                }
+                break;
+            default:
+                // Should never happen.
+                throw new IllegalArgumentException();
+            }
+
+            if (!ok) {
+                throw new NonMonotonousSequenceException(val[i], previous, i, dir, strict);
+            }
+            previous = val[i];
+        }
+    }
+
+    /**
+     * Checks that the given array is sorted in strictly increasing order.
+     *
+     * @param val Values.
+     * @throws NonMonotonousSequenceException if the array is not sorted.
+     * @since 2.2
+     */
+    public static void checkOrder(double[] val) {
+        checkOrder(val, OrderDirection.INCREASING, true);
+    }
+
+    /**
+     * Checks that the given array is sorted.
+     *
+     * @param val Values
+     * @param dir Order direction (-1 for decreasing, 1 for increasing)
+     * @param strict Whether the order should be strict
+     * @throws NonMonotonousSequenceException if the array is not sorted.
+     * @deprecated as of 2.2 (please use the new {@link #checkOrder(double[],OrderDirection,boolean)
+     * checkOrder} method). To be removed in 3.0.
+     */
+    @Deprecated
+    public static void checkOrder(double[] val, int dir, boolean strict) {
+        if (dir > 0) {
+            checkOrder(val, OrderDirection.INCREASING, strict);
+        } else {
+            checkOrder(val, OrderDirection.DECREASING, strict);
+        }
+    }
+
+    /**
+     * Returns the Cartesian norm (2-norm), handling both overflow and underflow.
+     * Translation of the minpack enorm subroutine.
+     *
+     * The redistribution policy for MINPACK is available <a
+     * href="http://www.netlib.org/minpack/disclaimer">here</a>, for convenience, it
+     * is reproduced below.</p>
+     *
+     * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
+     * <tr><td>
+     *    Minpack Copyright Notice (1999) University of Chicago.
+     *    All rights reserved
+     * </td></tr>
+     * <tr><td>
+     * Redistribution and use in source and binary forms, with or without
+     * modification, are permitted provided that the following conditions
+     * are met:
+     * <ol>
+     *  <li>Redistributions of source code must retain the above copyright
+     *      notice, this list of conditions and the following disclaimer.</li>
+     * <li>Redistributions in binary form must reproduce the above
+     *     copyright notice, this list of conditions and the following
+     *     disclaimer in the documentation and/or other materials provided
+     *     with the distribution.</li>
+     * <li>The end-user documentation included with the redistribution, if any,
+     *     must include the following acknowledgment:
+     *     <code>This product includes software developed by the University of
+     *           Chicago, as Operator of Argonne National Laboratory.</code>
+     *     Alternately, this acknowledgment may appear in the software itself,
+     *     if and wherever such third-party acknowledgments normally appear.</li>
+     * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
+     *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
+     *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
+     *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
+     *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
+     *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
+     *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
+     *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
+     *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
+     *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
+     *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
+     *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
+     *     BE CORRECTED.</strong></li>
+     * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
+     *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
+     *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
+     *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
+     *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
+     *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
+     *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
+     *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
+     *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
+     *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
+     * <ol></td></tr>
+     * </table>
+     *
+     * @param v vector of doubles
+     * @return the 2-norm of the vector
+     * @since 2.2
+     */
+    public static double safeNorm(double[] v) {
+    double rdwarf = 3.834e-20;
+    double rgiant = 1.304e+19;
+    double s1=0.0;
+    double s2=0.0;
+    double s3=0.0;
+    double x1max = 0.0;
+    double x3max = 0.0;
+    double floatn = (double)v.length;
+    double agiant = rgiant/floatn;
+    for (int i=0;i<v.length;i++) {
+        double xabs = Math.abs(v[i]);
+        if (xabs<rdwarf || xabs>agiant) {
+            if (xabs>rdwarf) {
+                if (xabs>x1max) {
+                    double r=x1max/xabs;
+                    s1=1.0+s1*r*r;
+                    x1max=xabs;
+                } else {
+                    double r=xabs/x1max;
+                    s1+=r*r;
+                }
+            } else {
+                if (xabs>x3max) {
+                 double r=x3max/xabs;
+                 s3=1.0+s3*r*r;
+                 x3max=xabs;
+                } else {
+                    if (xabs!=0.0) {
+                        double r=xabs/x3max;
+                        s3+=r*r;
+                    }
+                }
+            }
+        } else {
+         s2+=xabs*xabs;
+        }
+    }
+    double norm;
+    if (s1!=0.0) {
+        norm = x1max*Math.sqrt(s1+(s2/x1max)/x1max);
+    } else {
+        if (s2==0.0) {
+            norm = x3max*Math.sqrt(s3);
+        } else {
+            if (s2>=x3max) {
+                norm = Math.sqrt(s2*(1.0+(x3max/s2)*(x3max*s3)));
+            } else {
+                norm = Math.sqrt(x3max*((s2/x3max)+(x3max*s3)));
+            }
+        }
+    }
+    return norm;
+}
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/MultidimensionalCounter.java b/src/main/java/org/apache/commons/math/util/MultidimensionalCounter.java
new file mode 100644
index 0000000..752fb3d
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/MultidimensionalCounter.java
@@ -0,0 +1,316 @@
+/*
+ * 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.util;
+
+import org.apache.commons.math.exception.DimensionMismatchException;
+import org.apache.commons.math.exception.OutOfRangeException;
+import org.apache.commons.math.exception.NotStrictlyPositiveException;
+
+/**
+ * Converter between unidimensional storage structure and multidimensional
+ * conceptual structure.
+ * This utility will convert from indices in a multidimensional structure
+ * to the corresponding index in a one-dimensional array. For example,
+ * assuming that the ranges (in 3 dimensions) of indices are 2, 4 and 3,
+ * the following correspondences, between 3-tuples indices and unidimensional
+ * indices, will hold:
+ * <ul>
+ *  <li>(0, 0, 0) corresponds to 0</li>
+ *  <li>(0, 0, 1) corresponds to 1</li>
+ *  <li>(0, 0, 2) corresponds to 2</li>
+ *  <li>(0, 1, 0) corresponds to 3</li>
+ *  <li>...</li>
+ *  <li>(1, 0, 0) corresponds to 12</li>
+ *  <li>...</li>
+ *  <li>(1, 3, 2) corresponds to 23</li>
+ * </ul>
+ * @version $Revision$ $Date$
+ * @since 2.2
+ */
+public class MultidimensionalCounter implements Iterable<Integer> {
+    /**
+     * Number of dimensions.
+     */
+    private final int dimension;
+    /**
+     * Offset for each dimension.
+     */
+    private final int[] uniCounterOffset;
+    /**
+     * Counter sizes.
+     */
+    private final int[] size;
+    /**
+     * Total number of (one-dimensional) slots.
+     */
+    private final int totalSize;
+    /**
+     * Index of last dimension.
+     */
+    private final int last;
+
+    /**
+     * Perform iteration over the multidimensional counter.
+     */
+    public class Iterator implements java.util.Iterator<Integer> {
+        /**
+         * Multidimensional counter.
+         */
+        private final int[] counter = new int[dimension];
+        /**
+         * Unidimensional counter.
+         */
+        private int count = -1;
+
+        /**
+         * Create an iterator
+         * @see #iterator()
+         */
+        Iterator() {
+            counter[last] = -1;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean hasNext() {
+            for (int i = 0; i < dimension; i++) {
+                if (counter[i] != size[i] - 1) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * @return the unidimensional count after the counter has been
+         * incremented by {@code 1}.
+         */
+        public Integer next() {
+            for (int i = last; i >= 0; i--) {
+                if (counter[i] == size[i] - 1) {
+                    counter[i] = 0;
+                } else {
+                    ++counter[i];
+                    break;
+                }
+            }
+
+            return ++count;
+        }
+
+        /**
+         * Get the current unidimensional counter slot.
+         *
+         * @return the index within the unidimensionl counter.
+         */
+        public int getCount() {
+            return count;
+        }
+        /**
+         * Get the current multidimensional counter slots.
+         *
+         * @return the indices within the multidimensional counter.
+         */
+        public int[] getCounts() {
+            return /* Arrays.*/ copyOf(counter, dimension); // Java 1.5 does not support Arrays.copyOf()
+        }
+
+        /**
+         * Get the current count in the selected dimension.
+         *
+         * @param dim Dimension index.
+         * @return the count at the corresponding index for the current state
+         * of the iterator.
+         * @throws IndexOutOfBoundsException if {@code index} is not in the
+         * correct interval (as defined by the length of the argument in the
+         * {@link MultidimensionalCounter#MultidimensionalCounter(int[])
+         * constructor of the enclosing class}).
+         */
+        public int getCount(int dim) {
+            return counter[dim];
+        }
+
+        /**
+         * @throws UnsupportedOperationException
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * Create a counter.
+     *
+     * @param size Counter sizes (number of slots in each dimension).
+     * @throws NotStrictlyPositiveException if one of the sizes is
+     * negative or zero.
+     */
+    public MultidimensionalCounter(int ... size) {
+        dimension = size.length;
+        this.size = /* Arrays.*/ copyOf(size, dimension); // Java 1.5 does not support Arrays.copyOf()
+
+        uniCounterOffset = new int[dimension];
+
+        last = dimension - 1;
+        int tS = size[last];
+        for (int i = 0; i < last; i++) {
+            int count = 1;
+            for (int j = i + 1; j < dimension; j++) {
+                count *= size[j];
+            }
+            uniCounterOffset[i] = count;
+            tS *= size[i];
+        }
+        uniCounterOffset[last] = 0;
+
+        if (tS <= 0) {
+            throw new NotStrictlyPositiveException(tS);
+        }
+
+        totalSize = tS;
+    }
+
+    /**
+     * Create an iterator over this counter.
+     *
+     * @return the iterator.
+     */
+    public Iterator iterator() {
+        return new Iterator();
+    }
+
+    /**
+     * Get the number of dimensions of the multidimensional counter.
+     *
+     * @return the number of dimensions.
+     */
+    public int getDimension() {
+        return dimension;
+    }
+
+    /**
+     * Convert to multidimensional counter.
+     *
+     * @param index Index in unidimensional counter.
+     * @return the multidimensional counts.
+     * @throws OutOfRangeException if {@code index} is not between
+     * {@code 0} and the value returned by {@link #getSize()} (excluded).
+     */
+    public int[] getCounts(int index) {
+        if (index < 0 ||
+            index >= totalSize) {
+            throw new OutOfRangeException(index, 0, totalSize);
+        }
+
+        final int[] indices = new int[dimension];
+
+        int count = 0;
+        for (int i = 0; i < last; i++) {
+            int idx = 0;
+            final int offset = uniCounterOffset[i];
+            while (count <= index) {
+                count += offset;
+                ++idx;
+            }
+            --idx;
+            count -= offset;
+            indices[i] = idx;
+        }
+
+        int idx = 1;
+        while (count < index) {
+            count += idx;
+            ++idx;
+        }
+        --idx;
+        indices[last] = idx;
+
+        return indices;
+    }
+
+    /**
+     * Convert to unidimensional counter.
+     *
+     * @param c Indices in multidimensional counter.
+     * @return the index within the unidimensionl counter.
+     * @throws DimensionMismatchException if the size of {@code c}
+     * does not match the size of the array given in the constructor.
+     * @throws OutOfRangeException if a value of {@code c} is not in
+     * the range of the corresponding dimension, as defined in the
+     * {@link MultidimensionalCounter#MultidimensionalCounter(int...) constructor}.
+     */
+    public int getCount(int ... c) throws OutOfRangeException {
+        if (c.length != dimension) {
+            throw new DimensionMismatchException(c.length, dimension);
+        }
+        int count = 0;
+        for (int i = 0; i < dimension; i++) {
+            final int index = c[i];
+            if (index < 0 ||
+                index >= size[i]) {
+                throw new OutOfRangeException(index, 0, size[i] - 1);
+            }
+            count += uniCounterOffset[i] * c[i];
+        }
+        return count + c[last];
+    }
+
+    /**
+     * Get the total number of elements.
+     *
+     * @return the total size of the unidimensional counter.
+     */
+    public int getSize() {
+        return totalSize;
+    }
+    /**
+     * Get the number of multidimensional counter slots in each dimension.
+     *
+     * @return the sizes of the multidimensional counter in each dimension.
+     */
+    public int[] getSizes() {
+        return /* Arrays.*/ copyOf(size, dimension); // Java 1.5 does not support Arrays.copyOf()
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < dimension; i++) {
+            sb.append("[").append(getCount(i)).append("]");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Java 1.5 does not support Arrays.copyOf()
+     *
+     * @param source the array to be copied
+     * @param newLen the length of the copy to be returned
+     * @return the copied array, truncated or padded as necessary.
+     */
+     private int[] copyOf(int[] source, int newLen) {
+         int[] output = new int[newLen];
+         System.arraycopy(source, 0, output, 0, Math.min(source.length, newLen));
+         return output;
+     }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/NumberTransformer.java b/src/main/java/org/apache/commons/math/util/NumberTransformer.java
new file mode 100644
index 0000000..07d04db
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/NumberTransformer.java
@@ -0,0 +1,39 @@
+/*
+ * 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.util;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * Subclasses implementing this interface can transform Objects to doubles.
+ * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $
+ *
+ * No longer extends Serializable since 2.0
+ *
+ */
+public interface NumberTransformer {
+
+    /**
+     * Implementing this interface provides a facility to transform
+     * from Object to Double.
+     *
+     * @param o the Object to be transformed.
+     * @return the double value of the Object.
+     * @throws MathException if the Object can not be transformed into a Double.
+     */
+    double transform(Object o) throws MathException;
+}
diff --git a/src/main/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java b/src/main/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java
new file mode 100644
index 0000000..400735f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/OpenIntToDoubleHashMap.java
@@ -0,0 +1,600 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Open addressed map from int to double.
+ * <p>This class provides a dedicated map from integers to doubles with a
+ * much smaller memory overhead than standard <code>java.util.Map</code>.</p>
+ * <p>This class is not synchronized. The specialized iterators returned by
+ * {@link #iterator()} are fail-fast: they throw a
+ * <code>ConcurrentModificationException</code> when they detect the map has been
+ * modified during iteration.</p>
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class OpenIntToDoubleHashMap implements Serializable {
+
+    /** Status indicator for free table entries. */
+    protected static final byte FREE    = 0;
+
+    /** Status indicator for full table entries. */
+    protected static final byte FULL    = 1;
+
+    /** Status indicator for removed table entries. */
+    protected static final byte REMOVED = 2;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3646337053166149105L;
+
+    /** Load factor for the map. */
+    private static final float LOAD_FACTOR = 0.5f;
+
+    /** Default starting size.
+     * <p>This must be a power of two for bit mask to work properly. </p>
+     */
+    private static final int DEFAULT_EXPECTED_SIZE = 16;
+
+    /** Multiplier for size growth when map fills up.
+     * <p>This must be a power of two for bit mask to work properly. </p>
+     */
+    private static final int RESIZE_MULTIPLIER = 2;
+
+    /** Number of bits to perturb the index when probing for collision resolution. */
+    private static final int PERTURB_SHIFT = 5;
+
+    /** Keys table. */
+    private int[] keys;
+
+    /** Values table. */
+    private double[] values;
+
+    /** States table. */
+    private byte[] states;
+
+    /** Return value for missing entries. */
+    private final double missingEntries;
+
+    /** Current size of the map. */
+    private int size;
+
+    /** Bit mask for hash values. */
+    private int mask;
+
+    /** Modifications count. */
+    private transient int count;
+
+    /**
+     * Build an empty map with default size and using NaN for missing entries.
+     */
+    public OpenIntToDoubleHashMap() {
+        this(DEFAULT_EXPECTED_SIZE, Double.NaN);
+    }
+
+    /**
+     * Build an empty map with default size
+     * @param missingEntries value to return when a missing entry is fetched
+     */
+    public OpenIntToDoubleHashMap(final double missingEntries) {
+        this(DEFAULT_EXPECTED_SIZE, missingEntries);
+    }
+
+    /**
+     * Build an empty map with specified size and using NaN for missing entries.
+     * @param expectedSize expected number of elements in the map
+     */
+    public OpenIntToDoubleHashMap(final int expectedSize) {
+        this(expectedSize, Double.NaN);
+    }
+
+    /**
+     * Build an empty map with specified size.
+     * @param expectedSize expected number of elements in the map
+     * @param missingEntries value to return when a missing entry is fetched
+     */
+    public OpenIntToDoubleHashMap(final int expectedSize,
+                                  final double missingEntries) {
+        final int capacity = computeCapacity(expectedSize);
+        keys   = new int[capacity];
+        values = new double[capacity];
+        states = new byte[capacity];
+        this.missingEntries = missingEntries;
+        mask   = capacity - 1;
+    }
+
+    /**
+     * Copy constructor.
+     * @param source map to copy
+     */
+    public OpenIntToDoubleHashMap(final OpenIntToDoubleHashMap source) {
+        final int length = source.keys.length;
+        keys = new int[length];
+        System.arraycopy(source.keys, 0, keys, 0, length);
+        values = new double[length];
+        System.arraycopy(source.values, 0, values, 0, length);
+        states = new byte[length];
+        System.arraycopy(source.states, 0, states, 0, length);
+        missingEntries = source.missingEntries;
+        size  = source.size;
+        mask  = source.mask;
+        count = source.count;
+    }
+
+    /**
+     * Compute the capacity needed for a given size.
+     * @param expectedSize expected size of the map
+     * @return capacity to use for the specified size
+     */
+    private static int computeCapacity(final int expectedSize) {
+        if (expectedSize == 0) {
+            return 1;
+        }
+        final int capacity   = (int) FastMath.ceil(expectedSize / LOAD_FACTOR);
+        final int powerOfTwo = Integer.highestOneBit(capacity);
+        if (powerOfTwo == capacity) {
+            return capacity;
+        }
+        return nextPowerOfTwo(capacity);
+    }
+
+    /**
+     * Find the smallest power of two greater than the input value
+     * @param i input value
+     * @return smallest power of two greater than the input value
+     */
+    private static int nextPowerOfTwo(final int i) {
+        return Integer.highestOneBit(i) << 1;
+    }
+
+    /**
+     * Get the stored value associated with the given key
+     * @param key key associated with the data
+     * @return data associated with the key
+     */
+    public double get(final int key) {
+
+        final int hash  = hashOf(key);
+        int index = hash & mask;
+        if (containsKey(key, index)) {
+            return values[index];
+        }
+
+        if (states[index] == FREE) {
+            return missingEntries;
+        }
+
+        int j = index;
+        for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) {
+            j = probe(perturb, j);
+            index = j & mask;
+            if (containsKey(key, index)) {
+                return values[index];
+            }
+        }
+
+        return missingEntries;
+
+    }
+
+    /**
+     * Check if a value is associated with a key.
+     * @param key key to check
+     * @return true if a value is associated with key
+     */
+    public boolean containsKey(final int key) {
+
+        final int hash  = hashOf(key);
+        int index = hash & mask;
+        if (containsKey(key, index)) {
+            return true;
+        }
+
+        if (states[index] == FREE) {
+            return false;
+        }
+
+        int j = index;
+        for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) {
+            j = probe(perturb, j);
+            index = j & mask;
+            if (containsKey(key, index)) {
+                return true;
+            }
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Get an iterator over map elements.
+     * <p>The specialized iterators returned are fail-fast: they throw a
+     * <code>ConcurrentModificationException</code> when they detect the map
+     * has been modified during iteration.</p>
+     * @return iterator over the map elements
+     */
+    public Iterator iterator() {
+        return new Iterator();
+    }
+
+    /**
+     * Perturb the hash for starting probing.
+     * @param hash initial hash
+     * @return perturbed hash
+     */
+    private static int perturb(final int hash) {
+        return hash & 0x7fffffff;
+    }
+
+    /**
+     * Find the index at which a key should be inserted
+     * @param key key to lookup
+     * @return index at which key should be inserted
+     */
+    private int findInsertionIndex(final int key) {
+        return findInsertionIndex(keys, states, key, mask);
+    }
+
+    /**
+     * Find the index at which a key should be inserted
+     * @param keys keys table
+     * @param states states table
+     * @param key key to lookup
+     * @param mask bit mask for hash values
+     * @return index at which key should be inserted
+     */
+    private static int findInsertionIndex(final int[] keys, final byte[] states,
+                                          final int key, final int mask) {
+        final int hash = hashOf(key);
+        int index = hash & mask;
+        if (states[index] == FREE) {
+            return index;
+        } else if (states[index] == FULL && keys[index] == key) {
+            return changeIndexSign(index);
+        }
+
+        int perturb = perturb(hash);
+        int j = index;
+        if (states[index] == FULL) {
+            while (true) {
+                j = probe(perturb, j);
+                index = j & mask;
+                perturb >>= PERTURB_SHIFT;
+
+                if (states[index] != FULL || keys[index] == key) {
+                    break;
+                }
+            }
+        }
+
+        if (states[index] == FREE) {
+            return index;
+        } else if (states[index] == FULL) {
+            // due to the loop exit condition,
+            // if (states[index] == FULL) then keys[index] == key
+            return changeIndexSign(index);
+        }
+
+        final int firstRemoved = index;
+        while (true) {
+            j = probe(perturb, j);
+            index = j & mask;
+
+            if (states[index] == FREE) {
+                return firstRemoved;
+            } else if (states[index] == FULL && keys[index] == key) {
+                return changeIndexSign(index);
+            }
+
+            perturb >>= PERTURB_SHIFT;
+
+        }
+
+    }
+
+    /**
+     * Compute next probe for collision resolution
+     * @param perturb perturbed hash
+     * @param j previous probe
+     * @return next probe
+     */
+    private static int probe(final int perturb, final int j) {
+        return (j << 2) + j + perturb + 1;
+    }
+
+    /**
+     * Change the index sign
+     * @param index initial index
+     * @return changed index
+     */
+    private static int changeIndexSign(final int index) {
+        return -index - 1;
+    }
+
+    /**
+     * Get the number of elements stored in the map.
+     * @return number of elements stored in the map
+     */
+    public int size() {
+        return size;
+    }
+
+
+    /**
+     * Remove the value associated with a key.
+     * @param key key to which the value is associated
+     * @return removed value
+     */
+    public double remove(final int key) {
+
+        final int hash  = hashOf(key);
+        int index = hash & mask;
+        if (containsKey(key, index)) {
+            return doRemove(index);
+        }
+
+        if (states[index] == FREE) {
+            return missingEntries;
+        }
+
+        int j = index;
+        for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) {
+            j = probe(perturb, j);
+            index = j & mask;
+            if (containsKey(key, index)) {
+                return doRemove(index);
+            }
+        }
+
+        return missingEntries;
+
+    }
+
+    /**
+     * Check if the tables contain an element associated with specified key
+     * at specified index.
+     * @param key key to check
+     * @param index index to check
+     * @return true if an element is associated with key at index
+     */
+    private boolean containsKey(final int key, final int index) {
+        return (key != 0 || states[index] == FULL) && keys[index] == key;
+    }
+
+    /**
+     * Remove an element at specified index.
+     * @param index index of the element to remove
+     * @return removed value
+     */
+    private double doRemove(int index) {
+        keys[index]   = 0;
+        states[index] = REMOVED;
+        final double previous = values[index];
+        values[index] = missingEntries;
+        --size;
+        ++count;
+        return previous;
+    }
+
+    /**
+     * Put a value associated with a key in the map.
+     * @param key key to which value is associated
+     * @param value value to put in the map
+     * @return previous value associated with the key
+     */
+    public double put(final int key, final double value) {
+        int index = findInsertionIndex(key);
+        double previous = missingEntries;
+        boolean newMapping = true;
+        if (index < 0) {
+            index = changeIndexSign(index);
+            previous = values[index];
+            newMapping = false;
+        }
+        keys[index]   = key;
+        states[index] = FULL;
+        values[index] = value;
+        if (newMapping) {
+            ++size;
+            if (shouldGrowTable()) {
+                growTable();
+            }
+            ++count;
+        }
+        return previous;
+
+    }
+
+    /**
+     * Grow the tables.
+     */
+    private void growTable() {
+
+        final int oldLength      = states.length;
+        final int[] oldKeys      = keys;
+        final double[] oldValues = values;
+        final byte[] oldStates   = states;
+
+        final int newLength = RESIZE_MULTIPLIER * oldLength;
+        final int[] newKeys = new int[newLength];
+        final double[] newValues = new double[newLength];
+        final byte[] newStates = new byte[newLength];
+        final int newMask = newLength - 1;
+        for (int i = 0; i < oldLength; ++i) {
+            if (oldStates[i] == FULL) {
+                final int key = oldKeys[i];
+                final int index = findInsertionIndex(newKeys, newStates, key, newMask);
+                newKeys[index]   = key;
+                newValues[index] = oldValues[i];
+                newStates[index] = FULL;
+            }
+        }
+
+        mask   = newMask;
+        keys   = newKeys;
+        values = newValues;
+        states = newStates;
+
+    }
+
+    /**
+     * Check if tables should grow due to increased size.
+     * @return true if  tables should grow
+     */
+    private boolean shouldGrowTable() {
+        return size > (mask + 1) * LOAD_FACTOR;
+    }
+
+    /**
+     * Compute the hash value of a key
+     * @param key key to hash
+     * @return hash value of the key
+     */
+    private static int hashOf(final int key) {
+        final int h = key ^ ((key >>> 20) ^ (key >>> 12));
+        return h ^ (h >>> 7) ^ (h >>> 4);
+    }
+
+
+    /** Iterator class for the map. */
+    public class Iterator {
+
+        /** Reference modification count. */
+        private final int referenceCount;
+
+        /** Index of current element. */
+        private int current;
+
+        /** Index of next element. */
+        private int next;
+
+        /**
+         * Simple constructor.
+         */
+        private Iterator() {
+
+            // preserve the modification count of the map to detect concurrent modifications later
+            referenceCount = count;
+
+            // initialize current index
+            next = -1;
+            try {
+                advance();
+            } catch (NoSuchElementException nsee) {
+                // ignored
+            }
+
+        }
+
+        /**
+         * Check if there is a next element in the map.
+         * @return true if there is a next element
+         */
+        public boolean hasNext() {
+            return next >= 0;
+        }
+
+        /**
+         * Get the key of current entry.
+         * @return key of current entry
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
+         */
+        public int key()
+            throws ConcurrentModificationException, NoSuchElementException {
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING);
+            }
+            if (current < 0) {
+                throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED);
+            }
+            return keys[current];
+        }
+
+        /**
+         * Get the value of current entry.
+         * @return value of current entry
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
+         */
+        public double value()
+            throws ConcurrentModificationException, NoSuchElementException {
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING);
+            }
+            if (current < 0) {
+                throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED);
+            }
+            return values[current];
+        }
+
+        /**
+         * Advance iterator one step further.
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
+         */
+        public void advance()
+            throws ConcurrentModificationException, NoSuchElementException {
+
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING);
+            }
+
+            // advance on step
+            current = next;
+
+            // prepare next step
+            try {
+                while (states[++next] != FULL) {
+                    // nothing to do
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                next = -2;
+                if (current < 0) {
+                    throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED);
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * Read a serialized object.
+     * @param stream input stream
+     * @throws IOException if object cannot be read
+     * @throws ClassNotFoundException if the class corresponding
+     * to the serialized object cannot be found
+     */
+    private void readObject(final ObjectInputStream stream)
+        throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        count = 0;
+    }
+
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java b/src/main/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java
new file mode 100644
index 0000000..297ab44
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/OpenIntToFieldHashMap.java
@@ -0,0 +1,620 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.math.Field;
+import org.apache.commons.math.FieldElement;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * Open addressed map from int to FieldElement.
+ * <p>This class provides a dedicated map from integers to FieldElements with a
+ * much smaller memory overhead than standard <code>java.util.Map</code>.</p>
+ * <p>This class is not synchronized. The specialized iterators returned by
+ * {@link #iterator()} are fail-fast: they throw a
+ * <code>ConcurrentModificationException</code> when they detect the map has been
+ * modified during iteration.</p>
+ * @param <T> the type of the field elements
+ * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
+ * @since 2.0
+ */
+public class OpenIntToFieldHashMap<T extends FieldElement<T>> implements Serializable {
+
+    /** Status indicator for free table entries. */
+    protected static final byte FREE    = 0;
+
+    /** Status indicator for full table entries. */
+    protected static final byte FULL    = 1;
+
+    /** Status indicator for removed table entries. */
+    protected static final byte REMOVED = 2;
+
+    /** Serializable version identifier. */
+    private static final long serialVersionUID = -9179080286849120720L;
+
+    /** Load factor for the map. */
+    private static final float LOAD_FACTOR = 0.5f;
+
+    /** Default starting size.
+     * <p>This must be a power of two for bit mask to work properly. </p>
+     */
+    private static final int DEFAULT_EXPECTED_SIZE = 16;
+
+    /** Multiplier for size growth when map fills up.
+     * <p>This must be a power of two for bit mask to work properly. </p>
+     */
+    private static final int RESIZE_MULTIPLIER = 2;
+
+    /** Number of bits to perturb the index when probing for collision resolution. */
+    private static final int PERTURB_SHIFT = 5;
+
+    /** Field to which the elements belong. */
+    private final Field<T> field;
+
+    /** Keys table. */
+    private int[] keys;
+
+    /** Values table. */
+    private T[] values;
+
+    /** States table. */
+    private byte[] states;
+
+    /** Return value for missing entries. */
+    private final T missingEntries;
+
+    /** Current size of the map. */
+    private int size;
+
+    /** Bit mask for hash values. */
+    private int mask;
+
+    /** Modifications count. */
+    private transient int count;
+
+    /**
+     * Build an empty map with default size and using zero for missing entries.
+     * @param field field to which the elements belong
+     */
+    public OpenIntToFieldHashMap(final Field<T>field) {
+        this(field, DEFAULT_EXPECTED_SIZE, field.getZero());
+    }
+
+    /**
+     * Build an empty map with default size
+     * @param field field to which the elements belong
+     * @param missingEntries value to return when a missing entry is fetched
+     */
+    public OpenIntToFieldHashMap(final Field<T>field, final T missingEntries) {
+        this(field,DEFAULT_EXPECTED_SIZE, missingEntries);
+    }
+
+    /**
+     * Build an empty map with specified size and using zero for missing entries.
+     * @param field field to which the elements belong
+     * @param expectedSize expected number of elements in the map
+     */
+    public OpenIntToFieldHashMap(final Field<T> field,final int expectedSize) {
+        this(field,expectedSize, field.getZero());
+    }
+
+    /**
+     * Build an empty map with specified size.
+     * @param field field to which the elements belong
+     * @param expectedSize expected number of elements in the map
+     * @param missingEntries value to return when a missing entry is fetched
+     */
+    public OpenIntToFieldHashMap(final Field<T> field,final int expectedSize,
+                                  final T missingEntries) {
+        this.field = field;
+        final int capacity = computeCapacity(expectedSize);
+        keys   = new int[capacity];
+        values = buildArray(capacity);
+        states = new byte[capacity];
+        this.missingEntries = missingEntries;
+        mask   = capacity - 1;
+    }
+
+    /**
+     * Copy constructor.
+     * @param source map to copy
+     */
+    public OpenIntToFieldHashMap(final OpenIntToFieldHashMap<T> source) {
+        field = source.field;
+        final int length = source.keys.length;
+        keys = new int[length];
+        System.arraycopy(source.keys, 0, keys, 0, length);
+        values = buildArray(length);
+        System.arraycopy(source.values, 0, values, 0, length);
+        states = new byte[length];
+        System.arraycopy(source.states, 0, states, 0, length);
+        missingEntries = source.missingEntries;
+        size  = source.size;
+        mask  = source.mask;
+        count = source.count;
+    }
+
+    /**
+     * Compute the capacity needed for a given size.
+     * @param expectedSize expected size of the map
+     * @return capacity to use for the specified size
+     */
+    private static int computeCapacity(final int expectedSize) {
+        if (expectedSize == 0) {
+            return 1;
+        }
+        final int capacity   = (int) FastMath.ceil(expectedSize / LOAD_FACTOR);
+        final int powerOfTwo = Integer.highestOneBit(capacity);
+        if (powerOfTwo == capacity) {
+            return capacity;
+        }
+        return nextPowerOfTwo(capacity);
+    }
+
+    /**
+     * Find the smallest power of two greater than the input value
+     * @param i input value
+     * @return smallest power of two greater than the input value
+     */
+    private static int nextPowerOfTwo(final int i) {
+        return Integer.highestOneBit(i) << 1;
+    }
+
+    /**
+     * Get the stored value associated with the given key
+     * @param key key associated with the data
+     * @return data associated with the key
+     */
+    public T get(final int key) {
+
+        final int hash  = hashOf(key);
+        int index = hash & mask;
+        if (containsKey(key, index)) {
+            return values[index];
+        }
+
+        if (states[index] == FREE) {
+            return missingEntries;
+        }
+
+        int j = index;
+        for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) {
+            j = probe(perturb, j);
+            index = j & mask;
+            if (containsKey(key, index)) {
+                return values[index];
+            }
+        }
+
+        return missingEntries;
+
+    }
+
+    /**
+     * Check if a value is associated with a key.
+     * @param key key to check
+     * @return true if a value is associated with key
+     */
+    public boolean containsKey(final int key) {
+
+        final int hash  = hashOf(key);
+        int index = hash & mask;
+        if (containsKey(key, index)) {
+            return true;
+        }
+
+        if (states[index] == FREE) {
+            return false;
+        }
+
+        int j = index;
+        for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) {
+            j = probe(perturb, j);
+            index = j & mask;
+            if (containsKey(key, index)) {
+                return true;
+            }
+        }
+
+        return false;
+
+    }
+
+    /**
+     * Get an iterator over map elements.
+     * <p>The specialized iterators returned are fail-fast: they throw a
+     * <code>ConcurrentModificationException</code> when they detect the map
+     * has been modified during iteration.</p>
+     * @return iterator over the map elements
+     */
+    public Iterator iterator() {
+        return new Iterator();
+    }
+
+    /**
+     * Perturb the hash for starting probing.
+     * @param hash initial hash
+     * @return perturbed hash
+     */
+    private static int perturb(final int hash) {
+        return hash & 0x7fffffff;
+    }
+
+    /**
+     * Find the index at which a key should be inserted
+     * @param key key to lookup
+     * @return index at which key should be inserted
+     */
+    private int findInsertionIndex(final int key) {
+        return findInsertionIndex(keys, states, key, mask);
+    }
+
+    /**
+     * Find the index at which a key should be inserted
+     * @param keys keys table
+     * @param states states table
+     * @param key key to lookup
+     * @param mask bit mask for hash values
+     * @return index at which key should be inserted
+     */
+    private static int findInsertionIndex(final int[] keys, final byte[] states,
+                                          final int key, final int mask) {
+        final int hash = hashOf(key);
+        int index = hash & mask;
+        if (states[index] == FREE) {
+            return index;
+        } else if (states[index] == FULL && keys[index] == key) {
+            return changeIndexSign(index);
+        }
+
+        int perturb = perturb(hash);
+        int j = index;
+        if (states[index] == FULL) {
+            while (true) {
+                j = probe(perturb, j);
+                index = j & mask;
+                perturb >>= PERTURB_SHIFT;
+
+                if (states[index] != FULL || keys[index] == key) {
+                    break;
+                }
+            }
+        }
+
+        if (states[index] == FREE) {
+            return index;
+        } else if (states[index] == FULL) {
+            // due to the loop exit condition,
+            // if (states[index] == FULL) then keys[index] == key
+            return changeIndexSign(index);
+        }
+
+        final int firstRemoved = index;
+        while (true) {
+            j = probe(perturb, j);
+            index = j & mask;
+
+            if (states[index] == FREE) {
+                return firstRemoved;
+            } else if (states[index] == FULL && keys[index] == key) {
+                return changeIndexSign(index);
+            }
+
+            perturb >>= PERTURB_SHIFT;
+
+        }
+
+    }
+
+    /**
+     * Compute next probe for collision resolution
+     * @param perturb perturbed hash
+     * @param j previous probe
+     * @return next probe
+     */
+    private static int probe(final int perturb, final int j) {
+        return (j << 2) + j + perturb + 1;
+    }
+
+    /**
+     * Change the index sign
+     * @param index initial index
+     * @return changed index
+     */
+    private static int changeIndexSign(final int index) {
+        return -index - 1;
+    }
+
+    /**
+     * Get the number of elements stored in the map.
+     * @return number of elements stored in the map
+     */
+    public int size() {
+        return size;
+    }
+
+
+    /**
+     * Remove the value associated with a key.
+     * @param key key to which the value is associated
+     * @return removed value
+     */
+    public T remove(final int key) {
+
+        final int hash  = hashOf(key);
+        int index = hash & mask;
+        if (containsKey(key, index)) {
+            return doRemove(index);
+        }
+
+        if (states[index] == FREE) {
+            return missingEntries;
+        }
+
+        int j = index;
+        for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) {
+            j = probe(perturb, j);
+            index = j & mask;
+            if (containsKey(key, index)) {
+                return doRemove(index);
+            }
+        }
+
+        return missingEntries;
+
+    }
+
+    /**
+     * Check if the tables contain an element associated with specified key
+     * at specified index.
+     * @param key key to check
+     * @param index index to check
+     * @return true if an element is associated with key at index
+     */
+    private boolean containsKey(final int key, final int index) {
+        return (key != 0 || states[index] == FULL) && keys[index] == key;
+    }
+
+    /**
+     * Remove an element at specified index.
+     * @param index index of the element to remove
+     * @return removed value
+     */
+    private T doRemove(int index) {
+        keys[index]   = 0;
+        states[index] = REMOVED;
+        final T previous = values[index];
+        values[index] = missingEntries;
+        --size;
+        ++count;
+        return previous;
+    }
+
+    /**
+     * Put a value associated with a key in the map.
+     * @param key key to which value is associated
+     * @param value value to put in the map
+     * @return previous value associated with the key
+     */
+    public T put(final int key, final T value) {
+        int index = findInsertionIndex(key);
+        T previous = missingEntries;
+        boolean newMapping = true;
+        if (index < 0) {
+            index = changeIndexSign(index);
+            previous = values[index];
+            newMapping = false;
+        }
+        keys[index]   = key;
+        states[index] = FULL;
+        values[index] = value;
+        if (newMapping) {
+            ++size;
+            if (shouldGrowTable()) {
+                growTable();
+            }
+            ++count;
+        }
+        return previous;
+
+    }
+
+    /**
+     * Grow the tables.
+     */
+    private void growTable() {
+
+        final int oldLength      = states.length;
+        final int[] oldKeys      = keys;
+        final T[] oldValues = values;
+        final byte[] oldStates   = states;
+
+        final int newLength = RESIZE_MULTIPLIER * oldLength;
+        final int[] newKeys = new int[newLength];
+        final T[] newValues = buildArray(newLength);
+        final byte[] newStates = new byte[newLength];
+        final int newMask = newLength - 1;
+        for (int i = 0; i < oldLength; ++i) {
+            if (oldStates[i] == FULL) {
+                final int key = oldKeys[i];
+                final int index = findInsertionIndex(newKeys, newStates, key, newMask);
+                newKeys[index]   = key;
+                newValues[index] = oldValues[i];
+                newStates[index] = FULL;
+            }
+        }
+
+        mask   = newMask;
+        keys   = newKeys;
+        values = newValues;
+        states = newStates;
+
+    }
+
+    /**
+     * Check if tables should grow due to increased size.
+     * @return true if  tables should grow
+     */
+    private boolean shouldGrowTable() {
+        return size > (mask + 1) * LOAD_FACTOR;
+    }
+
+    /**
+     * Compute the hash value of a key
+     * @param key key to hash
+     * @return hash value of the key
+     */
+    private static int hashOf(final int key) {
+        final int h = key ^ ((key >>> 20) ^ (key >>> 12));
+        return h ^ (h >>> 7) ^ (h >>> 4);
+    }
+
+
+    /** Iterator class for the map. */
+    public class Iterator {
+
+        /** Reference modification count. */
+        private final int referenceCount;
+
+        /** Index of current element. */
+        private int current;
+
+        /** Index of next element. */
+        private int next;
+
+        /**
+         * Simple constructor.
+         */
+        private Iterator() {
+
+            // preserve the modification count of the map to detect concurrent modifications later
+            referenceCount = count;
+
+            // initialize current index
+            next = -1;
+            try {
+                advance();
+            } catch (NoSuchElementException nsee) {
+                // ignored
+            }
+
+        }
+
+        /**
+         * Check if there is a next element in the map.
+         * @return true if there is a next element
+         */
+        public boolean hasNext() {
+            return next >= 0;
+        }
+
+        /**
+         * Get the key of current entry.
+         * @return key of current entry
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
+         */
+        public int key()
+            throws ConcurrentModificationException, NoSuchElementException {
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING);
+            }
+            if (current < 0) {
+                throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED);
+            }
+            return keys[current];
+        }
+
+        /**
+         * Get the value of current entry.
+         * @return value of current entry
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
+         */
+        public T value()
+            throws ConcurrentModificationException, NoSuchElementException {
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING);
+            }
+            if (current < 0) {
+                throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED);
+            }
+            return values[current];
+        }
+
+        /**
+         * Advance iterator one step further.
+         * @exception ConcurrentModificationException if the map is modified during iteration
+         * @exception NoSuchElementException if there is no element left in the map
+         */
+        public void advance()
+            throws ConcurrentModificationException, NoSuchElementException {
+
+            if (referenceCount != count) {
+                throw MathRuntimeException.createConcurrentModificationException(LocalizedFormats.MAP_MODIFIED_WHILE_ITERATING);
+            }
+
+            // advance on step
+            current = next;
+
+            // prepare next step
+            try {
+                while (states[++next] != FULL) {
+                    // nothing to do
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                next = -2;
+                if (current < 0) {
+                    throw MathRuntimeException.createNoSuchElementException(LocalizedFormats.ITERATOR_EXHAUSTED);
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * Read a serialized object.
+     * @param stream input stream
+     * @throws IOException if object cannot be read
+     * @throws ClassNotFoundException if the class corresponding
+     * to the serialized object cannot be found
+     */
+    private void readObject(final ObjectInputStream stream)
+        throws IOException, ClassNotFoundException {
+        stream.defaultReadObject();
+        count = 0;
+    }
+
+    /** Build an array of elements.
+     * @param length size of the array to build
+     * @return a new array
+     */
+    @SuppressWarnings("unchecked") // field is of type T
+    private T[] buildArray(final int length) {
+        return (T[]) Array.newInstance(field.getZero().getClass(), length);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/ResizableDoubleArray.java b/src/main/java/org/apache/commons/math/util/ResizableDoubleArray.java
new file mode 100644
index 0000000..b33f288
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/ResizableDoubleArray.java
@@ -0,0 +1,936 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+
+/**
+ * <p>
+ * A variable length {@link DoubleArray} implementation that automatically
+ * handles expanding and contracting its internal storage array as elements
+ * are added and removed.
+ * </p>
+ * <p>
+ *  The internal storage array starts with capacity determined by the
+ * <code>initialCapacity</code> property, which can be set by the constructor.
+ * The default initial capacity is 16.  Adding elements using
+ * {@link #addElement(double)} appends elements to the end of the array.  When
+ * there are no open entries at the end of the internal storage array, the
+ * array is expanded.  The size of the expanded array depends on the
+ * <code>expansionMode</code> and <code>expansionFactor</code> properties.
+ * The <code>expansionMode</code> determines whether the size of the array is
+ * multiplied by the <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if
+ * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code>
+ * storage locations added).  The default <code>expansionMode</code> is
+ * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code>
+ * is 2.0.
+ * </p>
+ * <p>
+ * The {@link #addElementRolling(double)} method adds a new element to the end
+ * of the internal storage array and adjusts the "usable window" of the
+ * internal array forward by one position (effectively making what was the
+ * second element the first, and so on).  Repeated activations of this method
+ * (or activation of {@link #discardFrontElements(int)}) will effectively orphan
+ * the storage locations at the beginning of the internal storage array.  To
+ * reclaim this storage, each time one of these methods is activated, the size
+ * of the internal storage array is compared to the number of addressable
+ * elements (the <code>numElements</code> property) and if the difference
+ * is too large, the internal array is contracted to size
+ * <code>numElements + 1.</code>  The determination of when the internal
+ * storage array is "too large" depends on the <code>expansionMode</code> and
+ * <code>contractionFactor</code> properties.  If  the <code>expansionMode</code>
+ * is <code>MULTIPLICATIVE_MODE</code>, contraction is triggered when the
+ * ratio between storage array length and <code>numElements</code> exceeds
+ * <code>contractionFactor.</code>  If the <code>expansionMode</code>
+ * is <code>ADDITIVE_MODE,</code> the number of excess storage locations
+ * is compared to <code>contractionFactor.</code>
+ * </p>
+ * <p>
+ * To avoid cycles of expansions and contractions, the
+ * <code>expansionFactor</code> must not exceed the
+ * <code>contractionFactor.</code> Constructors and mutators for both of these
+ * properties enforce this requirement, throwing IllegalArgumentException if it
+ * is violated.
+ * </p>
+ * @version $Revision: 1073474 $ $Date: 2011-02-22 20:52:17 +0100 (mar. 22 févr. 2011) $
+ */
+public class ResizableDoubleArray implements DoubleArray, Serializable {
+
+    /** additive expansion mode */
+    public static final int ADDITIVE_MODE = 1;
+
+    /** multiplicative expansion mode */
+    public static final int MULTIPLICATIVE_MODE = 0;
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = -3485529955529426875L;
+
+    /**
+     * The contraction criteria determines when the internal array will be
+     * contracted to fit the number of elements contained in the element
+     *  array + 1.
+     */
+    protected float contractionCriteria = 2.5f;
+
+    /**
+     * The expansion factor of the array.  When the array needs to be expanded,
+     * the new array size will be
+     * <code>internalArray.length * expansionFactor</code>
+     * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE, or
+     * <code>internalArray.length + expansionFactor</code> if
+     * <code>expansionMode</code> is set to ADDITIVE_MODE.
+     */
+    protected float expansionFactor = 2.0f;
+
+    /**
+     * Determines whether array expansion by <code>expansionFactor</code>
+     * is additive or multiplicative.
+     */
+    protected int expansionMode = MULTIPLICATIVE_MODE;
+
+    /**
+     * The initial capacity of the array.  Initial capacity is not exposed as a
+     * property as it is only meaningful when passed to a constructor.
+     */
+    protected int initialCapacity = 16;
+
+    /**
+     * The internal storage array.
+     */
+    protected double[] internalArray;
+
+    /**
+     * The number of addressable elements in the array.  Note that this
+     * has nothing to do with the length of the internal storage array.
+     */
+    protected int numElements = 0;
+
+    /**
+     * The position of the first addressable element in the internal storage
+     * array.  The addressable elements in the array are <code>
+     * internalArray[startIndex],...,internalArray[startIndex + numElements -1]
+     * </code>
+     */
+    protected int startIndex = 0;
+
+    /**
+     * Create a ResizableArray with default properties.
+     * <ul>
+     * <li><code>initialCapacity = 16</code></li>
+     * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li>
+     * <li><code>expansionFactor = 2.5</code></li>
+     * <li><code>contractionFactor = 2.0</code></li>
+     * </ul>
+     */
+    public ResizableDoubleArray() {
+        internalArray = new double[initialCapacity];
+    }
+
+    /**
+     * Create a ResizableArray with the specified initial capacity.  Other
+     * properties take default values:
+      * <ul>
+     * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li>
+     * <li><code>expansionFactor = 2.5</code></li>
+     * <li><code>contractionFactor = 2.0</code></li>
+     * </ul>
+     * @param initialCapacity The initial size of the internal storage array
+     * @throws IllegalArgumentException if initialCapacity is not > 0
+     */
+    public ResizableDoubleArray(int initialCapacity) {
+        setInitialCapacity(initialCapacity);
+        internalArray = new double[this.initialCapacity];
+    }
+
+    /**
+     * Create a ResizableArray from an existing double[] with the
+     * initial capacity and numElements corresponding to the size of
+     * the supplied double[] array. If the supplied array is null, a
+     * new empty array with the default initial capacity will be created.
+     * The input array is copied, not referenced.
+     * Other properties take default values:
+     * <ul>
+     * <li><code>initialCapacity = 16</code></li>
+     * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li>
+     * <li><code>expansionFactor = 2.5</code></li>
+     * <li><code>contractionFactor = 2.0</code></li>
+     * </ul>
+     *
+     * @param initialArray initial array
+     * @since 2.2
+     */
+    public ResizableDoubleArray(double[] initialArray) {
+        if (initialArray == null) {
+            this.internalArray = new double[initialCapacity];
+        } else {
+            this.internalArray = new double[initialArray.length];
+            System.arraycopy(initialArray, 0, this.internalArray, 0, initialArray.length);
+            initialCapacity = initialArray.length;
+            numElements = initialArray.length;
+        }
+    }
+
+    /**
+     * <p>
+     * Create a ResizableArray with the specified initial capacity
+     * and expansion factor.  The remaining properties take default
+     * values:
+     * <ul>
+     * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li>
+     * <li><code>contractionFactor = 0.5 + expansionFactor</code></li>
+     * </ul></p>
+     * <p>
+     * Throws IllegalArgumentException if the following conditions are
+     * not met:
+     * <ul>
+     * <li><code>initialCapacity > 0</code></li>
+     * <li><code>expansionFactor > 1</code></li>
+     * </ul></p>
+     *
+     * @param initialCapacity The initial size of the internal storage array
+     * @param expansionFactor the array will be expanded based on this
+     *                        parameter
+     * @throws IllegalArgumentException if parameters are not valid
+     */
+    public ResizableDoubleArray(int initialCapacity, float expansionFactor) {
+        this.expansionFactor = expansionFactor;
+        setInitialCapacity(initialCapacity);
+        internalArray = new double[initialCapacity];
+        setContractionCriteria(expansionFactor +0.5f);
+    }
+
+    /**
+     * <p>
+     * Create a ResizableArray with the specified initialCapacity,
+     * expansionFactor, and contractionCriteria. The <code>expansionMode</code>
+     * will default to <code>MULTIPLICATIVE_MODE.</code></p>
+     * <p>
+     * Throws IllegalArgumentException if the following conditions are
+     * not met:
+     * <ul>
+     * <li><code>initialCapacity > 0</code></li>
+     * <li><code>expansionFactor > 1</code></li>
+     * <li><code>contractionFactor >= expansionFactor</code></li>
+     * </ul></p>
+     * @param initialCapacity The initial size of the internal storage array
+     * @param expansionFactor the array will be expanded based on this
+     *                        parameter
+     * @param contractionCriteria The contraction Criteria.
+     * @throws IllegalArgumentException if parameters are not valid
+     */
+    public ResizableDoubleArray(int initialCapacity, float expansionFactor,
+        float contractionCriteria) {
+        this.expansionFactor = expansionFactor;
+        setContractionCriteria(contractionCriteria);
+        setInitialCapacity(initialCapacity);
+        internalArray = new double[initialCapacity];
+    }
+
+    /**
+     * <p>
+     * Create a ResizableArray with the specified properties.</p>
+    * <p>
+     * Throws IllegalArgumentException if the following conditions are
+     * not met:
+     * <ul>
+     * <li><code>initialCapacity > 0</code></li>
+     * <li><code>expansionFactor > 1</code></li>
+     * <li><code>contractionFactor >= expansionFactor</code></li>
+     * <li><code>expansionMode in {MULTIPLICATIVE_MODE, ADDITIVE_MODE}</code>
+     * </li>
+     * </ul></p>
+     *
+     * @param initialCapacity the initial size of the internal storage array
+     * @param expansionFactor the array will be expanded based on this
+     *                        parameter
+     * @param contractionCriteria the contraction Criteria
+     * @param expansionMode  the expansion mode
+     * @throws IllegalArgumentException if parameters are not valid
+     */
+    public ResizableDoubleArray(int initialCapacity, float expansionFactor,
+            float contractionCriteria, int expansionMode) {
+        this.expansionFactor = expansionFactor;
+        setContractionCriteria(contractionCriteria);
+        setInitialCapacity(initialCapacity);
+        setExpansionMode(expansionMode);
+        internalArray = new double[initialCapacity];
+    }
+
+    /**
+     * Copy constructor.  Creates a new ResizableDoubleArray that is a deep,
+     * fresh copy of the original. Needs to acquire synchronization lock
+     * on original.  Original may not be null; otherwise a NullPointerException
+     * is thrown.
+     *
+     * @param original array to copy
+     * @since 2.0
+     */
+    public ResizableDoubleArray(ResizableDoubleArray original) {
+        copy(original, this);
+    }
+
+    /**
+     * Adds an element to the end of this expandable array.
+     *
+     * @param value to be added to end of array
+     */
+    public synchronized void addElement(double value) {
+        numElements++;
+        if ((startIndex + numElements) > internalArray.length) {
+            expand();
+        }
+        internalArray[startIndex + (numElements - 1)] = value;
+        if (shouldContract()) {
+            contract();
+        }
+    }
+
+    /**
+     * Adds several element to the end of this expandable array.
+     *
+     * @param values to be added to end of array
+     * @since 2.2
+     */
+    public synchronized void addElements(double[] values) {
+        final double[] tempArray = new double[numElements + values.length + 1];
+        System.arraycopy(internalArray, startIndex, tempArray, 0, numElements);
+        System.arraycopy(values, 0, tempArray, numElements, values.length);
+        internalArray = tempArray;
+        startIndex = 0;
+        numElements += values.length;
+    }
+
+    /**
+     * <p>
+     * Adds an element to the end of the array and removes the first
+     * element in the array.  Returns the discarded first element.
+     * The effect is similar to a push operation in a FIFO queue.
+     * </p>
+     * <p>
+     * Example: If the array contains the elements 1, 2, 3, 4 (in that order)
+     * and addElementRolling(5) is invoked, the result is an array containing
+     * the entries 2, 3, 4, 5 and the value returned is 1.
+     * </p>
+     *
+     * @param value the value to be added to the array
+     * @return the value which has been discarded or "pushed" out of the array
+     *         by this rolling insert
+     */
+    public synchronized double addElementRolling(double value) {
+        double discarded = internalArray[startIndex];
+
+        if ((startIndex + (numElements + 1)) > internalArray.length) {
+            expand();
+        }
+        // Increment the start index
+        startIndex += 1;
+
+        // Add the new value
+        internalArray[startIndex + (numElements - 1)] = value;
+
+        // Check the contraction criteria
+        if (shouldContract()) {
+            contract();
+        }
+        return discarded;
+    }
+
+    /**
+     * Substitutes <code>value</code> for the most recently added value.
+     * Returns the value that has been replaced. If the array is empty (i.e.
+     * if {@link #numElements} is zero), a MathRuntimeException is thrown.
+     *
+     * @param value new value to substitute for the most recently added value
+     * @return value that has been replaced in the array
+     * @since 2.0
+     */
+    public synchronized double substituteMostRecentElement(double value) {
+        if (numElements < 1) {
+            throw MathRuntimeException.createArrayIndexOutOfBoundsException(
+                    LocalizedFormats.CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY);
+        }
+
+        double discarded = internalArray[startIndex + (numElements - 1)];
+
+        internalArray[startIndex + (numElements - 1)] = value;
+
+        return discarded;
+    }
+
+
+    /**
+     * Checks the expansion factor and the contraction criteria and throws an
+     * IllegalArgumentException if the contractionCriteria is less than the
+     * expansionCriteria
+     *
+     * @param expansion factor to be checked
+     * @param contraction criteria to be checked
+     * @throws IllegalArgumentException if the contractionCriteria is less than
+     *         the expansionCriteria.
+     */
+    protected void checkContractExpand(float contraction, float expansion) {
+
+        if (contraction < expansion) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.CONTRACTION_CRITERIA_SMALLER_THAN_EXPANSION_FACTOR,
+                    contraction, expansion);
+        }
+
+        if (contraction <= 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.CONTRACTION_CRITERIA_SMALLER_THAN_ONE,
+                    contraction);
+        }
+
+        if (expansion <= 1.0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.EXPANSION_FACTOR_SMALLER_THAN_ONE,
+                    expansion);
+        }
+    }
+
+    /**
+     * Clear the array, reset the size to the initialCapacity and the number
+     * of elements to zero.
+     */
+    public synchronized void clear() {
+        numElements = 0;
+        startIndex = 0;
+        internalArray = new double[initialCapacity];
+    }
+
+    /**
+     * Contracts the storage array to the (size of the element set) + 1 - to
+     * avoid a zero length array. This function also resets the startIndex to
+     * zero.
+     */
+    public synchronized void contract() {
+        double[] tempArray = new double[numElements + 1];
+
+        // Copy and swap - copy only the element array from the src array.
+        System.arraycopy(internalArray, startIndex, tempArray, 0, numElements);
+        internalArray = tempArray;
+
+        // Reset the start index to zero
+        startIndex = 0;
+    }
+
+    /**
+     * Discards the <code>i<code> initial elements of the array.  For example,
+     * if the array contains the elements 1,2,3,4, invoking
+     * <code>discardFrontElements(2)</code> will cause the first two elements
+     * to be discarded, leaving 3,4 in the array.  Throws illegalArgumentException
+     * if i exceeds numElements.
+     *
+     * @param i  the number of elements to discard from the front of the array
+     * @throws IllegalArgumentException if i is greater than numElements.
+     * @since 2.0
+     */
+    public synchronized void discardFrontElements(int i) {
+
+        discardExtremeElements(i,true);
+
+    }
+
+    /**
+     * Discards the <code>i<code> last elements of the array.  For example,
+     * if the array contains the elements 1,2,3,4, invoking
+     * <code>discardMostRecentElements(2)</code> will cause the last two elements
+     * to be discarded, leaving 1,2 in the array.  Throws illegalArgumentException
+     * if i exceeds numElements.
+     *
+     * @param i  the number of elements to discard from the end of the array
+     * @throws IllegalArgumentException if i is greater than numElements.
+     * @since 2.0
+     */
+    public synchronized void discardMostRecentElements(int i) {
+
+        discardExtremeElements(i,false);
+
+    }
+
+    /**
+     * Discards the <code>i<code> first or last elements of the array,
+     * depending on the value of <code>front</code>.
+     * For example, if the array contains the elements 1,2,3,4, invoking
+     * <code>discardExtremeElements(2,false)</code> will cause the last two elements
+     * to be discarded, leaving 1,2 in the array.
+     * For example, if the array contains the elements 1,2,3,4, invoking
+     * <code>discardExtremeElements(2,true)</code> will cause the first two elements
+     * to be discarded, leaving 3,4 in the array.
+     * Throws illegalArgumentException
+     * if i exceeds numElements.
+     *
+     * @param i  the number of elements to discard from the front/end of the array
+     * @param front true if elements are to be discarded from the front
+     * of the array, false if elements are to be discarded from the end
+     * of the array
+     * @throws IllegalArgumentException if i is greater than numElements.
+     * @since 2.0
+     */
+    private synchronized void discardExtremeElements(int i,boolean front) {
+        if (i > numElements) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.TOO_MANY_ELEMENTS_TO_DISCARD_FROM_ARRAY,
+                    i, numElements);
+       } else if (i < 0) {
+           throw MathRuntimeException.createIllegalArgumentException(
+                   LocalizedFormats.CANNOT_DISCARD_NEGATIVE_NUMBER_OF_ELEMENTS,
+                   i);
+        } else {
+            // "Subtract" this number of discarded from numElements
+            numElements -= i;
+            if (front) startIndex += i;
+        }
+        if (shouldContract()) {
+            contract();
+        }
+    }
+
+    /**
+     * Expands the internal storage array using the expansion factor.
+     * <p>
+     * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE,
+     * the new array size will be <code>internalArray.length * expansionFactor.</code>
+     * If <code>expansionMode</code> is set to ADDITIVE_MODE,  the length
+     * after expansion will be <code>internalArray.length + expansionFactor</code>
+     * </p>
+     */
+    protected synchronized void expand() {
+
+        // notice the use of FastMath.ceil(), this guarantees that we will always
+        // have an array of at least currentSize + 1.   Assume that the
+        // current initial capacity is 1 and the expansion factor
+        // is 1.000000000000000001.  The newly calculated size will be
+        // rounded up to 2 after the multiplication is performed.
+        int newSize = 0;
+        if (expansionMode == MULTIPLICATIVE_MODE) {
+            newSize = (int) FastMath.ceil(internalArray.length * expansionFactor);
+        } else {
+            newSize = internalArray.length + FastMath.round(expansionFactor);
+        }
+        double[] tempArray = new double[newSize];
+
+        // Copy and swap
+        System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length);
+        internalArray = tempArray;
+    }
+
+    /**
+     * Expands the internal storage array to the specified size.
+     *
+     * @param size Size of the new internal storage array
+     */
+    private synchronized void expandTo(int size) {
+        double[] tempArray = new double[size];
+        // Copy and swap
+        System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length);
+        internalArray = tempArray;
+    }
+
+    /**
+     * The contraction criteria defines when the internal array will contract
+     * to store only the number of elements in the element array.
+     * If  the <code>expansionMode</code> is <code>MULTIPLICATIVE_MODE</code>,
+     * contraction is triggered when the ratio between storage array length
+     * and <code>numElements</code> exceeds <code>contractionFactor</code>.
+     * If the <code>expansionMode</code> is <code>ADDITIVE_MODE</code>, the
+     * number of excess storage locations is compared to
+     * <code>contractionFactor.</code>
+     *
+     * @return the contraction criteria used to reclaim memory.
+     */
+    public float getContractionCriteria() {
+        return contractionCriteria;
+    }
+
+    /**
+     * Returns the element at the specified index
+     *
+     * @param index index to fetch a value from
+     * @return value stored at the specified index
+     * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than
+     *         zero or is greater than <code>getNumElements() - 1</code>.
+     */
+    public synchronized double getElement(int index) {
+        if (index >= numElements) {
+            throw MathRuntimeException.createArrayIndexOutOfBoundsException(
+                    LocalizedFormats.INDEX_LARGER_THAN_MAX,
+                    index, numElements - 1);
+        } else if (index >= 0) {
+            return internalArray[startIndex + index];
+        } else {
+            throw MathRuntimeException.createArrayIndexOutOfBoundsException(
+                    LocalizedFormats.CANNOT_RETRIEVE_AT_NEGATIVE_INDEX,
+                    index);
+        }
+    }
+
+     /**
+     * Returns a double array containing the elements of this
+     * <code>ResizableArray</code>.  This method returns a copy, not a
+     * reference to the underlying array, so that changes made to the returned
+     *  array have no effect on this <code>ResizableArray.</code>
+     * @return the double array.
+     */
+    public synchronized double[] getElements() {
+        double[] elementArray = new double[numElements];
+        System.arraycopy( internalArray, startIndex, elementArray, 0,
+                numElements);
+        return elementArray;
+    }
+
+    /**
+     * The expansion factor controls the size of a new array when an array
+     * needs to be expanded.  The <code>expansionMode</code>
+     * determines whether the size of the array is multiplied by the
+     * <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if
+     * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code>
+     * storage locations added).  The default <code>expansionMode</code> is
+     * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code>
+     * is 2.0.
+     *
+     * @return the expansion factor of this expandable double array
+     */
+    public float getExpansionFactor() {
+        return expansionFactor;
+    }
+
+    /**
+     * The <code>expansionMode</code> determines whether the internal storage
+     * array grows additively (ADDITIVE_MODE) or multiplicatively
+     * (MULTIPLICATIVE_MODE) when it is expanded.
+     *
+     * @return Returns the expansionMode.
+     */
+    public int getExpansionMode() {
+        return expansionMode;
+    }
+
+    /**
+     * Notice the package scope on this method.   This method is simply here
+     * for the JUnit test, it allows us check if the expansion is working
+     * properly after a number of expansions.  This is not meant to be a part
+     * of the public interface of this class.
+     *
+     * @return the length of the internal storage array.
+     */
+    synchronized int getInternalLength() {
+        return internalArray.length;
+    }
+
+    /**
+     * Returns the number of elements currently in the array.  Please note
+     * that this is different from the length of the internal storage array.
+     *
+     * @return number of elements
+     */
+    public synchronized int getNumElements() {
+        return numElements;
+    }
+
+    /**
+     * Returns the internal storage array.  Note that this method returns
+     * a reference to the internal storage array, not a copy, and to correctly
+     * address elements of the array, the <code>startIndex</code> is
+     * required (available via the {@link #start} method).  This method should
+     * only be used in cases where copying the internal array is not practical.
+     * The {@link #getElements} method should be used in all other cases.
+     *
+     *
+     * @return the internal storage array used by this object
+     * @deprecated replaced by {@link #getInternalValues()} as of 2.0
+     */
+    @Deprecated
+    public synchronized double[] getValues() {
+        return internalArray;
+    }
+
+    /**
+     * Returns the internal storage array.  Note that this method returns
+     * a reference to the internal storage array, not a copy, and to correctly
+     * address elements of the array, the <code>startIndex</code> is
+     * required (available via the {@link #start} method).  This method should
+     * only be used in cases where copying the internal array is not practical.
+     * The {@link #getElements} method should be used in all other cases.
+     *
+     *
+     * @return the internal storage array used by this object
+     * @since 2.0
+     */
+    public synchronized double[] getInternalValues() {
+        return internalArray;
+    }
+
+    /**
+     * Sets the contraction criteria for this ExpandContractDoubleArray.
+     *
+     * @param contractionCriteria contraction criteria
+     */
+    public void setContractionCriteria(float contractionCriteria) {
+        checkContractExpand(contractionCriteria, getExpansionFactor());
+        synchronized(this) {
+            this.contractionCriteria = contractionCriteria;
+        }
+    }
+
+
+    /**
+     * Sets the element at the specified index.  If the specified index is greater than
+     * <code>getNumElements() - 1</code>, the <code>numElements</code> property
+     * is increased to <code>index +1</code> and additional storage is allocated
+     * (if necessary) for the new element and all  (uninitialized) elements
+     * between the new element and the previous end of the array).
+     *
+     * @param index index to store a value in
+     * @param value value to store at the specified index
+     * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than
+     *         zero.
+     */
+    public synchronized void setElement(int index, double value) {
+        if (index < 0) {
+            throw MathRuntimeException.createArrayIndexOutOfBoundsException(
+                    LocalizedFormats.CANNOT_SET_AT_NEGATIVE_INDEX,
+                    index);
+        }
+        if (index + 1 > numElements) {
+            numElements = index + 1;
+        }
+        if ((startIndex + index) >= internalArray.length) {
+            expandTo(startIndex + (index + 1));
+        }
+        internalArray[startIndex + index] = value;
+    }
+
+    /**
+     * Sets the expansionFactor.  Throws IllegalArgumentException if the
+     * the following conditions are not met:
+     * <ul>
+     * <li><code>expansionFactor > 1</code></li>
+     * <li><code>contractionFactor >= expansionFactor</code></li>
+     * </ul>
+     * @param expansionFactor the new expansion factor value.
+     * @throws IllegalArgumentException if expansionFactor is <= 1 or greater
+     * than contractionFactor
+     */
+    public void setExpansionFactor(float expansionFactor) {
+        checkContractExpand(getContractionCriteria(), expansionFactor);
+        // The check above verifies that the expansion factor is > 1.0;
+        synchronized(this) {
+            this.expansionFactor = expansionFactor;
+        }
+    }
+
+    /**
+     * Sets the <code>expansionMode</code>. The specified value must be one of
+     * ADDITIVE_MODE, MULTIPLICATIVE_MODE.
+     *
+     * @param expansionMode The expansionMode to set.
+     * @throws IllegalArgumentException if the specified mode value is not valid
+     */
+    public void setExpansionMode(int expansionMode) {
+        if (expansionMode != MULTIPLICATIVE_MODE &&
+                expansionMode != ADDITIVE_MODE) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.UNSUPPORTED_EXPANSION_MODE,
+                    expansionMode, MULTIPLICATIVE_MODE, "MULTIPLICATIVE_MODE",
+                    ADDITIVE_MODE, "ADDITIVE_MODE");
+        }
+        synchronized(this) {
+            this.expansionMode = expansionMode;
+        }
+    }
+
+    /**
+     * Sets the initial capacity.  Should only be invoked by constructors.
+     *
+     * @param initialCapacity of the array
+     * @throws IllegalArgumentException if <code>initialCapacity</code> is not
+     *         positive.
+     */
+    protected void setInitialCapacity(int initialCapacity) {
+        if (initialCapacity > 0) {
+            synchronized(this) {
+                this.initialCapacity = initialCapacity;
+            }
+        } else {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INITIAL_CAPACITY_NOT_POSITIVE,
+                    initialCapacity);
+        }
+    }
+
+    /**
+     * This function allows you to control the number of elements contained
+     * in this array, and can be used to "throw out" the last n values in an
+     * array. This function will also expand the internal array as needed.
+     *
+     * @param i a new number of elements
+     * @throws IllegalArgumentException if <code>i</code> is negative.
+     */
+    public synchronized void setNumElements(int i) {
+
+        // If index is negative thrown an error
+        if (i < 0) {
+            throw MathRuntimeException.createIllegalArgumentException(
+                    LocalizedFormats.INDEX_NOT_POSITIVE,
+                    i);
+        }
+
+        // Test the new num elements, check to see if the array needs to be
+        // expanded to accommodate this new number of elements
+        if ((startIndex + i) > internalArray.length) {
+            expandTo(startIndex + i);
+        }
+
+        // Set the new number of elements to new value
+        numElements = i;
+    }
+
+    /**
+     * Returns true if the internal storage array has too many unused
+     * storage positions.
+     *
+     * @return true if array satisfies the contraction criteria
+     */
+    private synchronized boolean shouldContract() {
+        if (expansionMode == MULTIPLICATIVE_MODE) {
+            return (internalArray.length / ((float) numElements)) > contractionCriteria;
+        } else {
+            return (internalArray.length - numElements) > contractionCriteria;
+        }
+    }
+
+    /**
+     * Returns the starting index of the internal array.  The starting index is
+     * the position of the first addressable element in the internal storage
+     * array.  The addressable elements in the array are <code>
+     * internalArray[startIndex],...,internalArray[startIndex + numElements -1]
+     * </code>
+     *
+     * @return starting index
+     */
+    public synchronized int start() {
+        return startIndex;
+    }
+
+    /**
+     * <p>Copies source to dest, copying the underlying data, so dest is
+     * a new, independent copy of source.  Does not contract before
+     * the copy.</p>
+     *
+     * <p>Obtains synchronization locks on both source and dest
+     * (in that order) before performing the copy.</p>
+     *
+     * <p>Neither source nor dest may be null; otherwise a NullPointerException
+     * is thrown</p>
+     *
+     * @param source ResizableDoubleArray to copy
+     * @param dest ResizableArray to replace with a copy of the source array
+     * @since 2.0
+     *
+     */
+    public static void copy(ResizableDoubleArray source, ResizableDoubleArray dest) {
+       synchronized(source) {
+           synchronized(dest) {
+               dest.initialCapacity = source.initialCapacity;
+               dest.contractionCriteria = source.contractionCriteria;
+               dest.expansionFactor = source.expansionFactor;
+               dest.expansionMode = source.expansionMode;
+               dest.internalArray = new double[source.internalArray.length];
+               System.arraycopy(source.internalArray, 0, dest.internalArray,
+                       0, dest.internalArray.length);
+               dest.numElements = source.numElements;
+               dest.startIndex = source.startIndex;
+           }
+       }
+    }
+
+    /**
+     * Returns a copy of the ResizableDoubleArray.  Does not contract before
+     * the copy, so the returned object is an exact copy of this.
+     *
+     * @return a new ResizableDoubleArray with the same data and configuration
+     * properties as this
+     * @since 2.0
+     */
+    public synchronized ResizableDoubleArray copy() {
+        ResizableDoubleArray result = new ResizableDoubleArray();
+        copy(this, result);
+        return result;
+    }
+
+    /**
+     * Returns true iff object is a ResizableDoubleArray with the same properties
+     * as this and an identical internal storage array.
+     *
+     * @param object object to be compared for equality with this
+     * @return true iff object is a ResizableDoubleArray with the same data and
+     * properties as this
+     * @since 2.0
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this ) {
+            return true;
+        }
+       if (object instanceof ResizableDoubleArray == false) {
+            return false;
+        }
+       synchronized(this) {
+           synchronized(object) {
+               boolean result = true;
+               ResizableDoubleArray other = (ResizableDoubleArray) object;
+               result = result && (other.initialCapacity == initialCapacity);
+               result = result && (other.contractionCriteria == contractionCriteria);
+               result = result && (other.expansionFactor == expansionFactor);
+               result = result && (other.expansionMode == expansionMode);
+               result = result && (other.numElements == numElements);
+               result = result && (other.startIndex == startIndex);
+               if (!result) {
+                   return false;
+               } else {
+                   return Arrays.equals(internalArray, other.internalArray);
+               }
+           }
+       }
+    }
+
+    /**
+     * Returns a hash code consistent with equals.
+     *
+     * @return hash code representing this ResizableDoubleArray
+     * @since 2.0
+     */
+    @Override
+    public synchronized int hashCode() {
+        int[] hashData = new int[7];
+        hashData[0] = new Float(expansionFactor).hashCode();
+        hashData[1] = new Float(contractionCriteria).hashCode();
+        hashData[2] = expansionMode;
+            hashData[3] = Arrays.hashCode(internalArray);
+            hashData[4] = initialCapacity;
+            hashData[5] = numElements;
+            hashData[6] = startIndex;
+        return Arrays.hashCode(hashData);
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/TransformerMap.java b/src/main/java/org/apache/commons/math/util/TransformerMap.java
new file mode 100644
index 0000000..53d0b3a
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/TransformerMap.java
@@ -0,0 +1,189 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.math.MathException;
+
+/**
+ * This TansformerMap automates the transformation of mixed object types.
+ * It provides a means to set NumberTransformers that will be selected
+ * based on the Class of the object handed to the Maps
+ * <code>double transform(Object o)</code> method.
+ * @version $Revision: 922713 $ $Date: 2010-03-14 02:26:13 +0100 (dim. 14 mars 2010) $
+ */
+public class TransformerMap implements NumberTransformer, Serializable {
+
+    /** Serializable version identifier */
+    private static final long serialVersionUID = 4605318041528645258L;
+
+    /**
+     * A default Number Transformer for Numbers and numeric Strings.
+     */
+    private NumberTransformer defaultTransformer = null;
+
+    /**
+     * The internal Map.
+     */
+    private Map<Class<?>, NumberTransformer> map = null;
+
+    /**
+     * Build a map containing only the default transformer.
+     */
+    public TransformerMap() {
+        map = new HashMap<Class<?>, NumberTransformer>();
+        defaultTransformer = new DefaultTransformer();
+    }
+
+    /**
+     * Tests if a Class is present in the TransformerMap.
+     * @param key Class to check
+     * @return true|false
+     */
+    public boolean containsClass(Class<?> key) {
+        return map.containsKey(key);
+    }
+
+    /**
+     * Tests if a NumberTransformer is present in the TransformerMap.
+     * @param value NumberTransformer to check
+     * @return true|false
+     */
+    public boolean containsTransformer(NumberTransformer value) {
+        return map.containsValue(value);
+    }
+
+    /**
+     * Returns the Transformer that is mapped to a class
+     * if mapping is not present, this returns null.
+     * @param key The Class of the object
+     * @return the mapped NumberTransformer or null.
+     */
+    public NumberTransformer getTransformer(Class<?> key) {
+        return map.get(key);
+    }
+
+    /**
+     * Sets a Class to Transformer Mapping in the Map. If
+     * the Class is already present, this overwrites that
+     * mapping.
+     * @param key The Class
+     * @param transformer The NumberTransformer
+     * @return the replaced transformer if one is present
+     */
+    public NumberTransformer putTransformer(Class<?> key, NumberTransformer transformer) {
+        return map.put(key, transformer);
+    }
+
+    /**
+     * Removes a Class to Transformer Mapping in the Map.
+     * @param key The Class
+     * @return the removed transformer if one is present or
+     * null if none was present.
+     */
+    public NumberTransformer removeTransformer(Class<?> key) {
+        return map.remove(key);
+    }
+
+    /**
+     * Clears all the Class to Transformer mappings.
+     */
+    public void clear() {
+        map.clear();
+    }
+
+    /**
+     * Returns the Set of Classes used as keys in the map.
+     * @return Set of Classes
+     */
+    public Set<Class<?>> classes() {
+        return map.keySet();
+    }
+
+    /**
+     * Returns the Set of NumberTransformers used as values
+     * in the map.
+     * @return Set of NumberTransformers
+     */
+    public Collection<NumberTransformer> transformers() {
+        return map.values();
+    }
+
+    /**
+     * Attempts to transform the Object against the map of
+     * NumberTransformers. Otherwise it returns Double.NaN.
+     *
+     * @param o the Object to be transformed.
+     * @return the double value of the Object.
+     * @throws MathException if the Object can not be transformed into a Double.
+     * @see org.apache.commons.math.util.NumberTransformer#transform(java.lang.Object)
+     */
+    public double transform(Object o) throws MathException {
+        double value = Double.NaN;
+
+        if (o instanceof Number || o instanceof String) {
+            value = defaultTransformer.transform(o);
+        } else {
+            NumberTransformer trans = getTransformer(o.getClass());
+            if (trans != null) {
+                value = trans.transform(o);
+            }
+        }
+
+        return value;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof TransformerMap) {
+            TransformerMap rhs = (TransformerMap) other;
+            if (! defaultTransformer.equals(rhs.defaultTransformer)) {
+                return false;
+            }
+            if (map.size() != rhs.map.size()) {
+                return false;
+            }
+            for (Map.Entry<Class<?>, NumberTransformer> entry : map.entrySet()) {
+                if (! entry.getValue().equals(rhs.map.get(entry.getKey()))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        int hash = defaultTransformer.hashCode();
+        for (NumberTransformer t : map.values()) {
+            hash = hash * 31 + t.hashCode();
+        }
+        return hash;
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/math/util/package.html b/src/main/java/org/apache/commons/math/util/package.html
new file mode 100644
index 0000000..407b17f
--- /dev/null
+++ b/src/main/java/org/apache/commons/math/util/package.html
@@ -0,0 +1,20 @@
+<html>
+<!--
+   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.
+  -->
+    <!-- $Revision: 480440 $ $Date: 2006-11-29 08:14:12 +0100 (mer. 29 nov. 2006) $ -->
+    <body>Convenience routines and common data structures used throughout the commons-math library.</body>
+</html>
